Collection IO: Enable file exporters to be specified on Collections #116646
|
@ -279,5 +279,5 @@ StatementMacros:
|
|||
MacroBlockBegin: "^OSL_CLOSURE_STRUCT_BEGIN$"
|
||||
MacroBlockEnd: "^OSL_CLOSURE_STRUCT_END$"
|
||||
|
||||
# Ensure lew line at the end of source files.
|
||||
# Ensure new line at the end of source files.
|
||||
InsertNewlineAtEOF: True
|
||||
|
|
|
@ -703,12 +703,7 @@ mark_as_advanced(WITH_DRAW_DEBUG)
|
|||
|
||||
# LLVM
|
||||
option(WITH_LLVM "Use LLVM" OFF)
|
||||
if(APPLE)
|
||||
# We prefer static llvm build on Apple, dyn build possible though.
|
||||
option(LLVM_STATIC "Link with LLVM static libraries" ON)
|
||||
else()
|
||||
option(LLVM_STATIC "Link with LLVM static libraries" OFF)
|
||||
endif()
|
||||
option(LLVM_STATIC "Link with LLVM static libraries" OFF)
|
||||
mark_as_advanced(LLVM_STATIC)
|
||||
option(WITH_CLANG "Use Clang" OFF)
|
||||
|
||||
|
@ -1156,14 +1151,7 @@ set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_CYCLES_OSL OFF)
|
|||
# Hydra requires USD.
|
||||
set_and_warn_dependency(WITH_USD WITH_HYDRA OFF)
|
||||
|
||||
# auto enable openimageio for cycles
|
||||
if(WITH_CYCLES)
|
||||
# auto enable llvm for cycles_osl
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(WITH_LLVM ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CLANG ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
else()
|
||||
if(NOT WITH_CYCLES)
|
||||
set(WITH_CYCLES_OSL OFF)
|
||||
endif()
|
||||
|
||||
|
@ -1382,18 +1370,6 @@ if(NOT WITH_FFTW3 AND WITH_MOD_OCEANSIM)
|
|||
message(FATAL_ERROR "WITH_MOD_OCEANSIM requires WITH_FFTW3 to be ON")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES)
|
||||
if(WITH_CYCLES_OSL)
|
||||
if(NOT WITH_LLVM)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles OSL requires WITH_LLVM, the library may not have been found. "
|
||||
"Configure LLVM or disable WITH_CYCLES_OSL"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
if(NOT WITH_BOOST)
|
||||
message(
|
||||
|
|
|
@ -535,7 +535,7 @@ check_spelling_shaders: .FORCE
|
|||
"$(BLENDER_DIR)/source/"
|
||||
|
||||
check_descriptions: .FORCE
|
||||
@$(BLENDER_BIN) --background -noaudio --factory-startup --python \
|
||||
@$(BLENDER_BIN) --background --factory-startup --python \
|
||||
"$(BLENDER_DIR)/tools/check_source/check_descriptions.py"
|
||||
|
||||
check_deprecated: .FORCE
|
||||
|
@ -598,7 +598,7 @@ format: .FORCE
|
|||
doc_py: .FORCE
|
||||
@ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
|
||||
$(BLENDER_BIN) \
|
||||
--background -noaudio --factory-startup \
|
||||
--background --factory-startup \
|
||||
--python doc/python_api/sphinx_doc_gen.py
|
||||
@sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out
|
||||
@echo "docs written into: '$(BLENDER_DIR)/doc/python_api/sphinx-out/index.html'"
|
||||
|
@ -609,7 +609,7 @@ doc_doxy: .FORCE
|
|||
|
||||
doc_dna: .FORCE
|
||||
@$(BLENDER_BIN) \
|
||||
--background -noaudio --factory-startup \
|
||||
--background --factory-startup \
|
||||
--python doc/blender_file_format/BlendFileDnaExporter_25.py
|
||||
@echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'"
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ set(OSL_EXTRA_ARGS
|
|||
-DPython_EXECUTABLE=${PYTHON_BINARY}
|
||||
)
|
||||
|
||||
if(NOT APPLE)
|
||||
list(APPEND OSL_EXTRA_ARGS -DOSL_USE_OPTIX=ON)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_osl
|
||||
URL file://${PACKAGE_DIR}/${OSL_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
|
|
|
@ -26,7 +26,7 @@ exit /b 1
|
|||
:detect_blender_done
|
||||
|
||||
%BLENDER_BIN% ^
|
||||
--background -noaudio --factory-startup ^
|
||||
--background --factory-startup ^
|
||||
--python %BLENDER_DIR%/doc/python_api/sphinx_doc_gen.py
|
||||
|
||||
"%SPHINX_BIN%" -b html %SPHINXOPTS% %O% %SOURCEDIR% %BUILDDIR%
|
||||
|
|
|
@ -363,15 +363,15 @@ class DNACatalogHTML:
|
|||
|
||||
|
||||
def usage():
|
||||
print("\nUsage: \n\tblender2.5 --background -noaudio --python BlendFileDnaExporter_25.py [-- [options]]")
|
||||
print("\nUsage: \n\tblender2.5 --background --python BlendFileDnaExporter_25.py [-- [options]]")
|
||||
print("Options:")
|
||||
print("\t--dna-keep-blend: doesn't delete the produced blend file DNA export to html")
|
||||
print("\t--dna-debug: sets the logging level to DEBUG (lots of additional info)")
|
||||
print("\t--dna-versioned saves version information in the html and blend filenames")
|
||||
print("\t--dna-overwrite-css overwrite dna.css, useful when modifying css in the script")
|
||||
print("Examples:")
|
||||
print("\tdefault: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py")
|
||||
print("\twith options: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
|
||||
print("\tdefault: % blender2.5 --background --python BlendFileDnaExporter_25.py")
|
||||
print("\twith options: % blender2.5 --background --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
|
||||
|
||||
|
||||
######################################################
|
||||
|
|
|
@ -16,14 +16,14 @@ Below you have the help message with a list of options you can use.
|
|||
|
||||
|
||||
Usage:
|
||||
blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py [-- [options]]
|
||||
blender2.5 --background --python BlendFileDnaExporter_25.py [-- [options]]
|
||||
Options:
|
||||
--dna-keep-blend: doesn't delete the produced blend file DNA export to html
|
||||
--dna-debug: sets the logging level to DEBUG (lots of additional info)
|
||||
--dna-versioned saves version information in the html and blend filenames
|
||||
--dna-overwrite-css overwrite dna.css, useful when modifying css in the script
|
||||
Examples:
|
||||
default: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py
|
||||
with options: % blender2.5 --background -noaudio --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug
|
||||
default: % blender2.5 --background --python BlendFileDnaExporter_25.py
|
||||
with options: % blender2.5 --background --python BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ import pxr.Gf as Gf
|
|||
import pxr.Sdf as Sdf
|
||||
import pxr.Usd as Usd
|
||||
import pxr.UsdShade as UsdShade
|
||||
import textwrap
|
||||
|
||||
|
||||
class USDHookExample(bpy.types.USDHook):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
..
|
||||
This document is appended to the auto generated BMesh API doc to avoid clogging up the C files with details.
|
||||
to test this run:
|
||||
./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py -- \
|
||||
./blender.bin -b -P doc/python_api/sphinx_doc_gen.py -- \
|
||||
--partial bmesh* ; cd doc/python_api ; sphinx-build sphinx-in sphinx-out ; cd ../../
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ API dump in RST files
|
|||
---------------------
|
||||
Run this script from Blender's root path once you have compiled Blender
|
||||
|
||||
blender --background --factory-startup -noaudio --python doc/python_api/sphinx_doc_gen.py
|
||||
blender --background --factory-startup --python doc/python_api/sphinx_doc_gen.py
|
||||
|
||||
This will generate python files in doc/python_api/sphinx-in/
|
||||
providing ./blender is or links to the blender executable
|
||||
|
@ -239,12 +239,12 @@ BPY_LOGGER.setLevel(logging.DEBUG)
|
|||
"""
|
||||
# for quick rebuilds
|
||||
rm -rf /b/doc/python_api/sphinx-* && \
|
||||
./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py && \
|
||||
./blender -b --factory-startup -P doc/python_api/sphinx_doc_gen.py && \
|
||||
sphinx-build doc/python_api/sphinx-in doc/python_api/sphinx-out
|
||||
|
||||
or
|
||||
|
||||
./blender -b -noaudio --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
|
||||
./blender -b --factory-startup -P doc/python_api/sphinx_doc_gen.py -- -f -B
|
||||
"""
|
||||
|
||||
# Switch for quick testing so doc-builds don't take so long.
|
||||
|
|
|
@ -176,19 +176,6 @@ int CLG_color_support_get(CLG_LogRef *clg_ref);
|
|||
} \
|
||||
((void)0)
|
||||
|
||||
#define CLOG_STR_AT_SEVERITY_N(clg_ref, severity, verbose_level, str) \
|
||||
{ \
|
||||
CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
|
||||
if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
|
||||
(severity >= CLG_SEVERITY_WARN)) \
|
||||
{ \
|
||||
const char *_str = str; \
|
||||
CLG_log_str(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, _str); \
|
||||
MEM_freeN((void *)_str); \
|
||||
} \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
#define CLOG_INFO(clg_ref, level, ...) \
|
||||
CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_INFO, level, __VA_ARGS__)
|
||||
#define CLOG_WARN(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_WARN, 0, __VA_ARGS__)
|
||||
|
@ -201,13 +188,6 @@ int CLG_color_support_get(CLG_LogRef *clg_ref);
|
|||
#define CLOG_STR_ERROR(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_ERROR, 0, str)
|
||||
#define CLOG_STR_FATAL(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_FATAL, 0, str)
|
||||
|
||||
/* Allocated string which is immediately freed. */
|
||||
#define CLOG_STR_INFO_N(clg_ref, level, str) \
|
||||
CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_INFO, level, str)
|
||||
#define CLOG_STR_WARN_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_WARN, 0, str)
|
||||
#define CLOG_STR_ERROR_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_ERROR, 0, str)
|
||||
#define CLOG_STR_FATAL_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_FATAL, 0, str)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "util/log.h"
|
||||
#include "util/task.h"
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
#include "BKE_duplilist.hh"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "util/string.h"
|
||||
#include "util/task.h"
|
||||
|
||||
#include "BKE_duplilist.h"
|
||||
#include "BKE_duplilist.hh"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ macro(cycles_external_libraries_append libraries)
|
|||
list(APPEND ${libraries} ${GLOG_LIBRARIES} ${GFLAGS_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_CYCLES_OSL)
|
||||
list(APPEND ${libraries} ${OSL_LIBRARIES} ${CLANG_LIBRARIES} ${LLVM_LIBRARY})
|
||||
list(APPEND ${libraries} ${OSL_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_CYCLES_EMBREE)
|
||||
list(APPEND ${libraries} ${EMBREE_LIBRARIES})
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "util/log.h"
|
||||
|
||||
#ifdef WITH_OSL
|
||||
# include <OSL/oslconfig.h>
|
||||
# include <OSL/oslversion.h>
|
||||
#endif
|
||||
|
||||
|
@ -72,7 +73,8 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
|
|||
|
||||
info.type = DEVICE_OPTIX;
|
||||
info.id += "_OptiX";
|
||||
# if defined(WITH_OSL) && (OSL_VERSION_MINOR >= 13 || OSL_VERSION_MAJOR > 1)
|
||||
# if defined(WITH_OSL) && defined(OSL_USE_OPTIX) && \
|
||||
(OSL_VERSION_MINOR >= 13 || OSL_VERSION_MAJOR > 1)
|
||||
info.has_osl = true;
|
||||
# endif
|
||||
info.denoisers |= DENOISER_OPTIX;
|
||||
|
|
|
@ -32,8 +32,6 @@ set(LIB
|
|||
${OSL_LIBRARIES}
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
${PUGIXML_LIBRARIES}
|
||||
${CLANG_LIBRARIES}
|
||||
${LLVM_LIBRARY}
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
|
|
|
@ -102,7 +102,8 @@ GHOST_DropTargetX11::~GHOST_DropTargetX11()
|
|||
char *GHOST_DropTargetX11::FileUrlDecode(const char *fileUrl)
|
||||
{
|
||||
if (strncmp(fileUrl, "file://", 7) == 0) {
|
||||
return GHOST_URL_decode_alloc(fileUrl + 7);
|
||||
const char *file = fileUrl + 7;
|
||||
return GHOST_URL_decode_alloc(file, strlen(file));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "GHOST_Debug.hh"
|
||||
#include "GHOST_PathUtils.hh"
|
||||
#include "GHOST_Types.h"
|
||||
|
||||
|
@ -24,9 +25,10 @@ using DecodeState_e = enum DecodeState_e {
|
|||
STATE_CONVERTING
|
||||
};
|
||||
|
||||
void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src)
|
||||
void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src, const int buf_src_len)
|
||||
{
|
||||
const uint buf_src_len = strlen(buf_src);
|
||||
GHOST_ASSERT(strnlen(buf_src, buf_src_len) == buf_src_len, "Incorrect length");
|
||||
|
||||
DecodeState_e state = STATE_SEARCH;
|
||||
uint ascii_character;
|
||||
|
||||
|
@ -85,12 +87,12 @@ void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src)
|
|||
}
|
||||
}
|
||||
|
||||
char *GHOST_URL_decode_alloc(const char *buf_src)
|
||||
char *GHOST_URL_decode_alloc(const char *buf_src, const int buf_src_len)
|
||||
{
|
||||
/* Assume one character of encoded URL can be expanded to 4 chars max. */
|
||||
const size_t decoded_size_max = 4 * strlen(buf_src) + 1;
|
||||
const size_t decoded_size_max = 4 * buf_src_len + 1;
|
||||
char *buf_dst = (char *)malloc(decoded_size_max);
|
||||
GHOST_URL_decode(buf_dst, decoded_size_max, buf_src);
|
||||
GHOST_URL_decode(buf_dst, decoded_size_max, buf_src, buf_src_len);
|
||||
const size_t decoded_size = strlen(buf_dst) + 1;
|
||||
if (decoded_size != decoded_size_max) {
|
||||
char *buf_dst_trim = (char *)malloc(decoded_size);
|
||||
|
|
|
@ -14,12 +14,13 @@
|
|||
* \param buf_dst: Buffer for decoded URL.
|
||||
* \param buf_dst_maxlen: Size of output buffer.
|
||||
* \param buf_src: Input encoded buffer to be decoded.
|
||||
* \param buf_src_len: The length of `buf_src` to use.
|
||||
*/
|
||||
void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src);
|
||||
void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src, int buf_src_len);
|
||||
/**
|
||||
* A version of #GHOST_URL_decode that allocates the string & returns it.
|
||||
*
|
||||
* \param buf_src: Input encoded buffer to be decoded.
|
||||
* \return The decoded output buffer.
|
||||
*/
|
||||
char *GHOST_URL_decode_alloc(const char *buf_src);
|
||||
char *GHOST_URL_decode_alloc(const char *buf_src, int buf_src_len);
|
||||
|
|
|
@ -2926,6 +2926,9 @@ static char *read_buffer_from_data_offer(GWL_DataOffer *data_offer,
|
|||
}
|
||||
close(pipefd[0]);
|
||||
}
|
||||
else {
|
||||
*r_len = 0;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -3259,20 +3262,19 @@ static void data_device_handle_drop(void *data, wl_data_device * /*wl_data_devic
|
|||
|
||||
CLOG_INFO(LOG, 2, "drop mime_recieve=%s", mime_receive);
|
||||
|
||||
auto read_uris_fn = [](GWL_Seat *const seat,
|
||||
GWL_DataOffer *data_offer,
|
||||
wl_surface *wl_surface_window,
|
||||
const char *mime_receive) {
|
||||
auto read_drop_data_fn = [](GWL_Seat *const seat,
|
||||
GWL_DataOffer *data_offer,
|
||||
wl_surface *wl_surface_window,
|
||||
const char *mime_receive) {
|
||||
const uint64_t event_ms = seat->system->getMilliSeconds();
|
||||
const wl_fixed_t xy[2] = {UNPACK2(data_offer->dnd.xy)};
|
||||
|
||||
const bool nil_terminate = (mime_receive != ghost_wl_mime_text_uri);
|
||||
size_t data_buf_len = 0;
|
||||
const char *data_buf = read_buffer_from_data_offer(
|
||||
data_offer, mime_receive, nullptr, false, &data_buf_len);
|
||||
std::string data = data_buf ? std::string(data_buf, data_buf_len) : "";
|
||||
free(const_cast<char *>(data_buf));
|
||||
data_offer, mime_receive, nullptr, nil_terminate, &data_buf_len);
|
||||
|
||||
CLOG_INFO(LOG, 2, "drop_read_uris mime_receive=%s, data=%s", mime_receive, data.c_str());
|
||||
CLOG_INFO(LOG, 2, "read_drop_data mime_receive=%s, data_len=%zu", mime_receive, data_buf_len);
|
||||
|
||||
wl_data_offer_finish(data_offer->wl.id);
|
||||
wl_data_offer_destroy(data_offer->wl.id);
|
||||
|
@ -3283,69 +3285,97 @@ static void data_device_handle_drop(void *data, wl_data_device * /*wl_data_devic
|
|||
delete data_offer;
|
||||
data_offer = nullptr;
|
||||
|
||||
GHOST_SystemWayland *const system = seat->system;
|
||||
/* Don't generate a drop event if the data could not be read,
|
||||
* an error will have been logged. */
|
||||
if (data_buf != nullptr) {
|
||||
GHOST_TDragnDropTypes ghost_dnd_type = GHOST_kDragnDropTypeUnknown;
|
||||
void *ghost_dnd_data = nullptr;
|
||||
|
||||
if (mime_receive == ghost_wl_mime_text_uri) {
|
||||
static constexpr const char *file_proto = "file://";
|
||||
/* NOTE: some applications CRLF (`\r\n`) GTK3 for e.g. & others don't `pcmanfm-qt`.
|
||||
* So support both, once `\n` is found, strip the preceding `\r` if found. */
|
||||
static constexpr const char *lf = "\n";
|
||||
/* Failure to receive drop data . */
|
||||
if (mime_receive == ghost_wl_mime_text_uri) {
|
||||
const char file_proto[] = "file://";
|
||||
/* NOTE: some applications CRLF (`\r\n`) GTK3 for e.g. & others don't `pcmanfm-qt`.
|
||||
* So support both, once `\n` is found, strip the preceding `\r` if found. */
|
||||
const char lf = '\n';
|
||||
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_window);
|
||||
std::vector<std::string> uris;
|
||||
const std::string_view data = std::string_view(data_buf, data_buf_len);
|
||||
std::vector<std::string_view> uris;
|
||||
|
||||
size_t pos = 0;
|
||||
while (pos != std::string::npos) {
|
||||
pos = data.find(file_proto, pos);
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
size_t pos = 0;
|
||||
while (pos != std::string::npos) {
|
||||
pos = data.find(file_proto, pos);
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
const size_t start = pos + sizeof(file_proto) - 1;
|
||||
pos = data.find(lf, pos);
|
||||
|
||||
size_t end = pos;
|
||||
if (UNLIKELY(end == std::string::npos)) {
|
||||
/* Note that most well behaved file managers will add a trailing newline,
|
||||
* Gnome's web browser (44.3) doesn't, so support reading up until the last byte. */
|
||||
end = data.size();
|
||||
}
|
||||
/* Account for 'CRLF' case. */
|
||||
if (data[end - 1] == '\r') {
|
||||
end -= 1;
|
||||
}
|
||||
|
||||
std::string_view data_substr = data.substr(start, end - start);
|
||||
uris.push_back(data_substr);
|
||||
CLOG_INFO(LOG,
|
||||
2,
|
||||
"read_drop_data pos=%zu, text_uri=\"%.*s\"",
|
||||
start,
|
||||
int(data_substr.size()),
|
||||
data_substr.data());
|
||||
}
|
||||
const size_t start = pos + sizeof(file_proto) - 1;
|
||||
pos = data.find(lf, pos);
|
||||
|
||||
size_t end = pos;
|
||||
if (UNLIKELY(end == std::string::npos)) {
|
||||
/* Note that most well behaved file managers will add a trailing newline,
|
||||
* Gnome's web browser (44.3) doesn't, so support reading up until the last byte. */
|
||||
end = data.size();
|
||||
GHOST_TStringArray *flist = static_cast<GHOST_TStringArray *>(
|
||||
malloc(sizeof(GHOST_TStringArray)));
|
||||
flist->count = int(uris.size());
|
||||
flist->strings = static_cast<uint8_t **>(malloc(uris.size() * sizeof(uint8_t *)));
|
||||
for (size_t i = 0; i < uris.size(); i++) {
|
||||
flist->strings[i] = reinterpret_cast<uint8_t *>(
|
||||
GHOST_URL_decode_alloc(uris[i].data(), uris[i].size()));
|
||||
}
|
||||
/* Account for 'CRLF' case. */
|
||||
if (data[end - 1] == '\r') {
|
||||
end -= 1;
|
||||
}
|
||||
uris.push_back(data.substr(start, end - start));
|
||||
CLOG_INFO(LOG, 2, "drop_read_uris pos=%zu, text_uri=\"%s\"", start, uris.back().c_str());
|
||||
|
||||
CLOG_INFO(LOG, 2, "read_drop_data file_count=%d", flist->count);
|
||||
ghost_dnd_type = GHOST_kDragnDropTypeFilenames;
|
||||
ghost_dnd_data = flist;
|
||||
}
|
||||
else if (ELEM(mime_receive, ghost_wl_mime_text_plain, ghost_wl_mime_text_utf8)) {
|
||||
ghost_dnd_type = GHOST_kDragnDropTypeString;
|
||||
ghost_dnd_data = (void *)data_buf; /* Move ownership to the event. */
|
||||
data_buf = nullptr;
|
||||
}
|
||||
|
||||
GHOST_TStringArray *flist = static_cast<GHOST_TStringArray *>(
|
||||
malloc(sizeof(GHOST_TStringArray)));
|
||||
flist->count = int(uris.size());
|
||||
flist->strings = static_cast<uint8_t **>(malloc(uris.size() * sizeof(uint8_t *)));
|
||||
for (size_t i = 0; i < uris.size(); i++) {
|
||||
flist->strings[i] = reinterpret_cast<uint8_t *>(GHOST_URL_decode_alloc(uris[i].c_str()));
|
||||
if (ghost_dnd_type != GHOST_kDragnDropTypeUnknown) {
|
||||
GHOST_SystemWayland *const system = seat->system;
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_window);
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, xy)};
|
||||
|
||||
system->pushEvent_maybe_pending(new GHOST_EventDragnDrop(event_ms,
|
||||
GHOST_kEventDraggingDropDone,
|
||||
ghost_dnd_type,
|
||||
win,
|
||||
UNPACK2(event_xy),
|
||||
ghost_dnd_data));
|
||||
|
||||
wl_display_roundtrip(system->wl_display_get());
|
||||
}
|
||||
else {
|
||||
CLOG_INFO(LOG, 2, "read_drop_data, unhandled!");
|
||||
}
|
||||
|
||||
CLOG_INFO(LOG, 2, "drop_read_uris_fn file_count=%d", flist->count);
|
||||
const int event_xy[2] = {WL_FIXED_TO_INT_FOR_WINDOW_V2(win, xy)};
|
||||
system->pushEvent_maybe_pending(new GHOST_EventDragnDrop(event_ms,
|
||||
GHOST_kEventDraggingDropDone,
|
||||
GHOST_kDragnDropTypeFilenames,
|
||||
win,
|
||||
UNPACK2(event_xy),
|
||||
flist));
|
||||
free(const_cast<char *>(data_buf));
|
||||
}
|
||||
else if (ELEM(mime_receive, ghost_wl_mime_text_plain, ghost_wl_mime_text_utf8)) {
|
||||
/* TODO: enable use of internal functions 'txt_insert_buf' and
|
||||
* 'text_update_edited' to behave like dropped text was pasted. */
|
||||
CLOG_INFO(LOG, 2, "drop_read_uris_fn (text_plain, text_utf8), unhandled!");
|
||||
}
|
||||
wl_display_roundtrip(system->wl_display_get());
|
||||
};
|
||||
|
||||
/* Pass in `seat->wl_surface_window_focus_dnd` instead of accessing it from `seat` since the
|
||||
* leave callback (#data_device_handle_leave) will clear the value once this function starts. */
|
||||
std::thread read_thread(
|
||||
read_uris_fn, seat, data_offer, seat->wl.surface_window_focus_dnd, mime_receive);
|
||||
read_drop_data_fn, seat, data_offer, seat->wl.surface_window_focus_dnd, mime_receive);
|
||||
read_thread.detach();
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ for blend in icons_blend:
|
|||
output_dir = os.path.join(BASEDIR, "icons")
|
||||
files_old = set(names_and_time_from_path(output_dir))
|
||||
cmd = (
|
||||
blender_bin, "--background", "--factory-startup", "-noaudio",
|
||||
blender_bin, "--background", "--factory-startup",
|
||||
blend,
|
||||
"--python", os.path.join(BASEDIR, "blender_icons_geom.py"),
|
||||
"--",
|
||||
|
|
|
@ -71,7 +71,7 @@ datatoc_icon_split_py = os.path.join(BASEDIR, "..", "..", "source", "blender", "
|
|||
|
||||
# create .dat pixmaps (which are stored in git)
|
||||
cmd = (
|
||||
blender_bin, "--background", "--factory-startup", "-noaudio",
|
||||
blender_bin, "--background", "--factory-startup",
|
||||
"--python", datatoc_icon_split_py, "--",
|
||||
"--image=" + os.path.join(BASEDIR, "blender_icons16.png"),
|
||||
"--output=" + os.path.join(BASEDIR, "blender_icons16"),
|
||||
|
@ -85,7 +85,7 @@ cmd = (
|
|||
run(cmd, env=env)
|
||||
|
||||
cmd = (
|
||||
blender_bin, "--background", "--factory-startup", "-noaudio",
|
||||
blender_bin, "--background", "--factory-startup",
|
||||
"--python", datatoc_icon_split_py, "--",
|
||||
"--image=" + os.path.join(BASEDIR, "blender_icons32.png"),
|
||||
"--output=" + os.path.join(BASEDIR, "blender_icons32"),
|
||||
|
|
|
@ -262,7 +262,6 @@ url_manual_mapping = (
|
|||
("bpy.types.clothsettings.compression_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-compression-stiffness-max"),
|
||||
("bpy.types.colormanagedsequencercolorspacesettings*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings"),
|
||||
("bpy.types.colormanagedviewsettings.view_transform*", "render/color_management.html#bpy-types-colormanagedviewsettings-view-transform"),
|
||||
("bpy.types.compositornodetree.use_groupnode_buffer*", "compositing/sidebar.html#bpy-types-compositornodetree-use-groupnode-buffer"),
|
||||
("bpy.types.cyclesmaterialsettings.volume_step_rate*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-step-rate"),
|
||||
("bpy.types.cyclesobjectsettings.is_caustics_caster*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-is-caustics-caster"),
|
||||
("bpy.types.cyclesrendersettings.adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-threshold"),
|
||||
|
@ -1023,7 +1022,6 @@ url_manual_mapping = (
|
|||
("bpy.types.compositornodecolorcorrection*", "compositing/types/color/adjust/color_correction.html#bpy-types-compositornodecolorcorrection"),
|
||||
("bpy.types.compositornodemoviedistortion*", "compositing/types/transform/movie_distortion.html#bpy-types-compositornodemoviedistortion"),
|
||||
("bpy.types.compositornodetree.chunk_size*", "compositing/sidebar.html#bpy-types-compositornodetree-chunk-size"),
|
||||
("bpy.types.compositornodetree.use_opencl*", "compositing/sidebar.html#bpy-types-compositornodetree-use-opencl"),
|
||||
("bpy.types.cyclesrendersettings.caustics*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-caustics"),
|
||||
("bpy.types.cyclesrendersettings.denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoiser"),
|
||||
("bpy.types.editbone.use_inherit_rotation*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-inherit-rotation"),
|
||||
|
|
|
@ -105,7 +105,6 @@ class WM_OT_previews_batch_generate(Operator):
|
|||
bpy.app.binary_path,
|
||||
"--background",
|
||||
"--factory-startup",
|
||||
"-noaudio",
|
||||
]
|
||||
if self.use_trusted:
|
||||
cmd.append("--enable-autoexec")
|
||||
|
@ -215,7 +214,6 @@ class WM_OT_previews_batch_clear(Operator):
|
|||
bpy.app.binary_path,
|
||||
"--background",
|
||||
"--factory-startup",
|
||||
"-noaudio",
|
||||
]
|
||||
if self.use_trusted:
|
||||
cmd.append("--enable-autoexec")
|
||||
|
|
|
@ -533,7 +533,7 @@ class NODE_MT_category_GEO_UTILITIES(Menu):
|
|||
bl_idname = "NODE_MT_category_GEO_UTILITIES"
|
||||
bl_label = "Utilities"
|
||||
|
||||
def draw(self, _context):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_geometry_node_GEO_COLOR")
|
||||
layout.menu("NODE_MT_category_GEO_TEXT")
|
||||
|
@ -541,6 +541,8 @@ class NODE_MT_category_GEO_UTILITIES(Menu):
|
|||
layout.separator()
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_FIELD")
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_MATH")
|
||||
if context.preferences.experimental.use_new_matrix_socket:
|
||||
layout.menu("NODE_MT_category_utilities_matrix")
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_ROTATION")
|
||||
layout.menu("NODE_MT_category_GEO_UTILITIES_DEPRECATED")
|
||||
layout.separator()
|
||||
|
@ -592,6 +594,22 @@ class NODE_MT_category_GEO_UTILITIES_ROTATION(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, "Utilities/Rotation")
|
||||
|
||||
|
||||
class NODE_MT_category_utilities_matrix(Menu):
|
||||
bl_idname = "NODE_MT_category_utilities_matrix"
|
||||
bl_label = "Matrix"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeCombineTransform")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeInvertMatrix")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeMatrixMultiply")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeSeparateTransform")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeTransformDirection")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeTransformPoint")
|
||||
node_add_menu.add_node_type(layout, "FunctionNodeTransposeMatrix")
|
||||
node_add_menu.draw_assets_for_catalog(layout, "Utilities/Matrix")
|
||||
|
||||
|
||||
class NODE_MT_category_GEO_UTILITIES_MATH(Menu):
|
||||
bl_idname = "NODE_MT_category_GEO_UTILITIES_MATH"
|
||||
bl_label = "Math"
|
||||
|
@ -779,6 +797,7 @@ classes = (
|
|||
NODE_MT_category_GEO_UTILITIES_FIELD,
|
||||
NODE_MT_category_GEO_UTILITIES_MATH,
|
||||
NODE_MT_category_GEO_UTILITIES_ROTATION,
|
||||
NODE_MT_category_utilities_matrix,
|
||||
NODE_MT_category_GEO_UTILITIES_DEPRECATED,
|
||||
NODE_MT_category_GEO_GROUP,
|
||||
)
|
||||
|
|
|
@ -43,7 +43,7 @@ class MotionPathButtonsPanel:
|
|||
col.prop(mps, "frame_step", text="Step")
|
||||
|
||||
row = col.row()
|
||||
row.prop(mps, "bake_in_camera_space", text="Bake to Active Camera")
|
||||
row.prop(mps, "use_camera_space_bake", text="Bake to Active Camera")
|
||||
|
||||
if bones:
|
||||
op_category = "pose"
|
||||
|
|
|
@ -51,6 +51,14 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
|
|||
|
||||
layout.operator("grease_pencil.layer_group_add", text="Add Group")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("grease_pencil.layer_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
|
||||
layout.operator("grease_pencil.layer_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
|
||||
|
||||
layout.separator()
|
||||
layout.operator("grease_pencil.layer_lock_all", icon='LOCKED', text="Lock All")
|
||||
layout.operator("grease_pencil.layer_lock_all", icon='UNLOCKED', text="Unlock All").lock = False
|
||||
|
||||
|
||||
class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
|
||||
bl_label = "Layers"
|
||||
|
|
|
@ -151,7 +151,9 @@ class OBJECT_MT_modifier_add_generate(ModifierAddMenu, Menu):
|
|||
self.operator_modifier_add(layout, 'WIREFRAME')
|
||||
if ob_type == 'GREASEPENCIL':
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_DASH')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_LENGTH')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_MIRROR')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_MULTIPLY')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_SUBDIV')
|
||||
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ class GRAPH_MT_view(Menu):
|
|||
layout.prop(st, "use_realtime_update")
|
||||
layout.prop(st, "show_sliders")
|
||||
layout.prop(st, "use_auto_merge_keyframes")
|
||||
layout.prop(st, "autolock_translation_axis")
|
||||
layout.prop(st, "use_auto_lock_translation_axis")
|
||||
layout.separator()
|
||||
|
||||
if st.mode != 'DRIVERS':
|
||||
|
|
|
@ -818,12 +818,9 @@ class NODE_PT_quality(bpy.types.Panel):
|
|||
col.active = not use_realtime
|
||||
col.prop(tree, "render_quality", text="Render")
|
||||
col.prop(tree, "edit_quality", text="Edit")
|
||||
col.prop(tree, "chunk_size")
|
||||
|
||||
col = layout.column()
|
||||
col.active = not use_realtime
|
||||
col.prop(tree, "use_opencl")
|
||||
col.prop(tree, "use_groupnode_buffer")
|
||||
col.prop(tree, "use_two_pass")
|
||||
col.prop(tree, "use_viewer_border")
|
||||
|
||||
|
|
|
@ -2661,6 +2661,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
|
|||
({"property": "use_sculpt_texture_paint"}, ("blender/blender/issues/96225", "#96225")),
|
||||
({"property": "use_experimental_compositors"}, ("blender/blender/issues/88150", "#88150")),
|
||||
({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/6", "Grease Pencil 3.0")),
|
||||
({"property": "use_new_matrix_socket"}, ("blender/blender/issues/116067", "Matrix Socket")),
|
||||
({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")),
|
||||
({"property": "use_extension_repos"}, ("/blender/blender/issues/106254", "#106254")),
|
||||
),
|
||||
|
|
|
@ -827,13 +827,21 @@ class VIEW3D_HT_header(Header):
|
|||
depress=(tool_settings.gpencil_selectmode_edit == 'STROKE'),
|
||||
).mode = 'STROKE'
|
||||
|
||||
if object_mode == 'PAINT_GREASE_PENCIL':
|
||||
row = layout.row(align=True)
|
||||
row.prop(tool_settings, "use_gpencil_draw_additive", text="", icon='FREEZE')
|
||||
|
||||
if object_mode in {'PAINT_GREASE_PENCIL', 'EDIT', 'WEIGHT_PAINT'}:
|
||||
row = layout.row(align=True)
|
||||
row.prop(tool_settings, "use_grease_pencil_multi_frame_editing", text="")
|
||||
|
||||
if object_mode == 'PAINT_GREASE_PENCIL':
|
||||
row = layout.row()
|
||||
sub = row.row(align=True)
|
||||
sub.prop(tool_settings, "use_gpencil_draw_additive", text="", icon='FREEZE')
|
||||
if object_mode in {'EDIT', 'WEIGHT_PAINT'}:
|
||||
sub = row.row(align=True)
|
||||
sub.enabled = tool_settings.use_grease_pencil_multi_frame_editing
|
||||
sub.popover(
|
||||
panel="VIEW3D_PT_grease_pencil_multi_frame",
|
||||
text="Multiframe",
|
||||
)
|
||||
|
||||
# Grease Pencil (legacy)
|
||||
if obj and obj.type == 'GPENCIL' and context.gpencil_data:
|
||||
|
@ -8004,6 +8012,25 @@ class VIEW3D_PT_gpencil_multi_frame(Panel):
|
|||
layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_grease_pencil_multi_frame(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Multi Frame"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
|
||||
settings = tool_settings.gpencil_sculpt
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(settings, "use_multiframe_falloff")
|
||||
|
||||
# Falloff curve
|
||||
if settings.use_multiframe_falloff:
|
||||
layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
|
||||
|
||||
|
||||
# Grease Pencil Object - Curve Editing tools
|
||||
class VIEW3D_PT_gpencil_curve_edit(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
@ -9024,6 +9051,7 @@ classes = (
|
|||
VIEW3D_PT_grease_pencil,
|
||||
VIEW3D_PT_annotation_onion,
|
||||
VIEW3D_PT_gpencil_multi_frame,
|
||||
VIEW3D_PT_grease_pencil_multi_frame,
|
||||
VIEW3D_PT_gpencil_curve_edit,
|
||||
VIEW3D_PT_gpencil_sculpt_automasking,
|
||||
VIEW3D_PT_quad_view,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_vector.hh"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "ED_transform.hh"
|
||||
|
@ -192,6 +193,8 @@ bool autokeyframe_property(bContext *C,
|
|||
* expected to be the size of the property array.
|
||||
* \param frame: is expected to be in the local time of the action, meaning it has to be NLA mapped
|
||||
* already.
|
||||
* \param keying_mask is expected to have the same size as `rna_path`. A false bit means that index
|
||||
* will be skipped.
|
||||
* \returns The number of keys inserted.
|
||||
*/
|
||||
int insert_key_action(Main *bmain,
|
||||
|
@ -202,7 +205,8 @@ int insert_key_action(Main *bmain,
|
|||
float frame,
|
||||
Span<float> values,
|
||||
eInsertKeyFlags insert_key_flag,
|
||||
eBezTriple_KeyframeType key_type);
|
||||
eBezTriple_KeyframeType key_type,
|
||||
const BLI_bitmap *keying_mask);
|
||||
|
||||
/**
|
||||
* Insert keys to the ID of the given PointerRNA for the given RNA paths. Tries to create an
|
||||
|
@ -215,6 +219,7 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
|||
eInsertKeyFlags insert_key_flags,
|
||||
eBezTriple_KeyframeType key_type,
|
||||
Main *bmain,
|
||||
ReportList *reports);
|
||||
ReportList *reports,
|
||||
const AnimationEvalContext &anim_eval_context);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
* \ingroup animrig
|
||||
*/
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.hh"
|
||||
|
@ -19,8 +17,6 @@
|
|||
|
||||
#include "DNA_armature_types.h"
|
||||
|
||||
#include "BLI_math_bits.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
|
@ -440,7 +436,7 @@ void ANIM_armature_bonecoll_active_name_set(bArmature *armature, const char *nam
|
|||
ANIM_armature_bonecoll_active_set(armature, bcoll);
|
||||
}
|
||||
|
||||
void ANIM_armature_bonecoll_active_runtime_refresh(struct bArmature *armature)
|
||||
void ANIM_armature_bonecoll_active_runtime_refresh(bArmature *armature)
|
||||
{
|
||||
const std::string_view active_name = armature->active_collection_name;
|
||||
if (active_name.empty()) {
|
||||
|
@ -1062,8 +1058,8 @@ static bool bcoll_list_contains(const ListBase /*BoneCollectionRef*/ *collection
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ANIM_armature_bonecoll_contains_active_bone(const struct bArmature *armature,
|
||||
const struct BoneCollection *bcoll)
|
||||
bool ANIM_armature_bonecoll_contains_active_bone(const bArmature *armature,
|
||||
const BoneCollection *bcoll)
|
||||
{
|
||||
if (armature->edbo) {
|
||||
if (!armature->act_edbone) {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
#include "ANIM_driver.hh"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_fcurve_driver.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "RNA_access.hh"
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include "RNA_path.hh"
|
||||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
namespace blender::animrig {
|
||||
|
@ -863,7 +862,8 @@ int insert_key_action(Main *bmain,
|
|||
const float frame,
|
||||
const Span<float> values,
|
||||
eInsertKeyFlags insert_key_flag,
|
||||
eBezTriple_KeyframeType key_type)
|
||||
eBezTriple_KeyframeType key_type,
|
||||
const BLI_bitmap *keying_mask)
|
||||
{
|
||||
BLI_assert(bmain != nullptr);
|
||||
BLI_assert(action != nullptr);
|
||||
|
@ -880,6 +880,10 @@ int insert_key_action(Main *bmain,
|
|||
int property_array_index = 0;
|
||||
int inserted_keys = 0;
|
||||
for (float value : values) {
|
||||
if (!BLI_BITMAP_TEST_BOOL(keying_mask, property_array_index)) {
|
||||
property_array_index++;
|
||||
continue;
|
||||
}
|
||||
const bool inserted_key = insert_keyframe_fcurve_value(bmain,
|
||||
nullptr,
|
||||
ptr,
|
||||
|
@ -925,7 +929,8 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
|||
const eInsertKeyFlags insert_key_flags,
|
||||
const eBezTriple_KeyframeType key_type,
|
||||
Main *bmain,
|
||||
ReportList *reports)
|
||||
ReportList *reports,
|
||||
const AnimationEvalContext &anim_eval_context)
|
||||
{
|
||||
ID *id = rna_pointer->owner_id;
|
||||
bAction *action = id_action_ensure(bmain, id);
|
||||
|
@ -939,6 +944,15 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
|||
}
|
||||
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
/* Keyframing functions can deal with the nla_context being a nullptr. */
|
||||
ListBase nla_cache = {nullptr, nullptr};
|
||||
NlaKeyframingContext *nla_context = nullptr;
|
||||
if (adt && adt->action == action) {
|
||||
nla_context = BKE_animsys_get_nla_keyframing_context(
|
||||
&nla_cache, rna_pointer, adt, &anim_eval_context);
|
||||
}
|
||||
|
||||
const float nla_frame = BKE_nla_tweakedit_remap(adt, scene_frame, NLATIME_CONVERT_UNMAP);
|
||||
const bool visual_keyframing = insert_key_flags & INSERTKEY_MATRIX;
|
||||
|
||||
|
@ -961,6 +975,16 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
|||
prop);
|
||||
Vector<float> rna_values = get_keyframe_values(&ptr, prop, visual_keyframing);
|
||||
|
||||
BLI_bitmap *successful_remaps = BLI_BITMAP_NEW(rna_values.size(), __func__);
|
||||
BKE_animsys_nla_remap_keyframe_values(nla_context,
|
||||
rna_pointer,
|
||||
prop,
|
||||
rna_values.as_mutable_span(),
|
||||
-1,
|
||||
&anim_eval_context,
|
||||
nullptr,
|
||||
successful_remaps);
|
||||
|
||||
insert_key_count += insert_key_action(bmain,
|
||||
action,
|
||||
rna_pointer,
|
||||
|
@ -969,7 +993,9 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
|||
nla_frame,
|
||||
rna_values.as_span(),
|
||||
insert_key_flags,
|
||||
key_type);
|
||||
key_type,
|
||||
successful_remaps);
|
||||
MEM_freeN(successful_remaps);
|
||||
}
|
||||
|
||||
if (insert_key_count == 0) {
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include "BKE_animsys.h"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_layer.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_scene.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
@ -22,11 +20,8 @@
|
|||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "ED_keyframing.hh"
|
||||
#include "ED_scene.hh"
|
||||
#include "ED_transform.hh"
|
||||
|
||||
#include "ANIM_keyframing.hh"
|
||||
#include "ANIM_rna.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
@ -165,7 +160,8 @@ void autokeyframe_object(bContext *C, Scene *scene, Object *ob, Span<std::string
|
|||
flag,
|
||||
eBezTriple_KeyframeType(scene->toolsettings->keyframe_type),
|
||||
bmain,
|
||||
reports);
|
||||
reports,
|
||||
anim_eval_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,7 +286,8 @@ void autokeyframe_pose_channel(bContext *C,
|
|||
flag,
|
||||
eBezTriple_KeyframeType(scene->toolsettings->keyframe_type),
|
||||
bmain,
|
||||
reports);
|
||||
reports,
|
||||
anim_eval_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,10 @@
|
|||
#include "ANIM_rna.hh"
|
||||
#include "ANIM_visualkey.hh"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.hh"
|
||||
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
@ -25,7 +23,6 @@
|
|||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_prototypes.h"
|
||||
#include "RNA_types.hh"
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
|
@ -214,11 +211,11 @@ Vector<float> visualkey_get_values(PointerRNA *ptr, PropertyRNA *prop)
|
|||
Object *ob = static_cast<Object *>(ptr->data);
|
||||
/* Loc code is specific... */
|
||||
if (strstr(identifier, "location")) {
|
||||
values.extend({ob->object_to_world[3], 3});
|
||||
values.extend({ob->object_to_world().location(), 3});
|
||||
return values;
|
||||
}
|
||||
|
||||
copy_m4_m4(tmat, ob->object_to_world);
|
||||
copy_m4_m4(tmat, ob->object_to_world().ptr());
|
||||
rotmode = ob->rotmode;
|
||||
}
|
||||
else if (ptr->type == &RNA_PoseBone) {
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
|
||||
#include "BKE_callbacks.hh"
|
||||
|
||||
struct IDRemapper;
|
||||
struct Main;
|
||||
|
||||
namespace blender::bke::id {
|
||||
class IDRemapper;
|
||||
}
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
class AssetIdentifier;
|
||||
|
@ -140,7 +143,7 @@ class AssetLibrary {
|
|||
* mapped to null (typically when an ID gets removed), the asset is removed, because we don't
|
||||
* support such empty/null assets.
|
||||
*/
|
||||
void remap_ids_and_remove_invalid(const IDRemapper &mappings);
|
||||
void remap_ids_and_remove_invalid(const blender::bke::id::IDRemapper &mappings);
|
||||
|
||||
/**
|
||||
* Update `catalog_simple_name` by looking up the asset's catalog by its ID.
|
||||
|
@ -230,11 +233,6 @@ std::string AS_asset_library_find_suitable_root_path_from_path(blender::StringRe
|
|||
*/
|
||||
std::string AS_asset_library_find_suitable_root_path_from_main(const Main *bmain);
|
||||
|
||||
blender::asset_system::AssetCatalogService *AS_asset_library_get_catalog_service(
|
||||
const blender::asset_system::AssetLibrary *library);
|
||||
blender::asset_system::AssetCatalogTree *AS_asset_library_get_catalog_tree(
|
||||
const blender::asset_system::AssetLibrary *library);
|
||||
|
||||
/**
|
||||
* Force clearing of all asset library data. After calling this, new asset libraries can be loaded
|
||||
* just as usual using #AS_asset_library_load(), no init or other setup is needed.
|
||||
|
@ -253,10 +251,6 @@ void AS_asset_libraries_exit();
|
|||
blender::asset_system::AssetLibrary *AS_asset_library_load(const char *name,
|
||||
const char *library_dirpath);
|
||||
|
||||
/** Look up the asset's catalog and copy its simple name into #asset_data. */
|
||||
void AS_asset_library_refresh_catalog_simplename(
|
||||
blender::asset_system::AssetLibrary *asset_library, AssetMetaData *asset_data);
|
||||
|
||||
/** Return whether any loaded AssetLibrary has unsaved changes to its catalogs. */
|
||||
bool AS_asset_library_has_any_unsaved_catalogs(void);
|
||||
|
||||
|
@ -264,7 +258,7 @@ bool AS_asset_library_has_any_unsaved_catalogs(void);
|
|||
* An asset library can include local IDs (IDs in the current file). Their pointers need to be
|
||||
* remapped on change (or assets removed as IDs gets removed).
|
||||
*/
|
||||
void AS_asset_library_remap_ids(const IDRemapper *mappings);
|
||||
void AS_asset_library_remap_ids(const blender::bke::id::IDRemapper &mappings);
|
||||
|
||||
/**
|
||||
* Attempt to resolve a full path to an asset based on the currently available (not necessary
|
||||
|
|
|
@ -317,7 +317,7 @@ static std::string asset_definition_default_file_path_from_dir(StringRef asset_l
|
|||
|
||||
void AssetCatalogService::load_from_disk()
|
||||
{
|
||||
load_from_disk(asset_library_root_);
|
||||
this->load_from_disk(asset_library_root_);
|
||||
}
|
||||
|
||||
void AssetCatalogService::load_from_disk(const CatalogFilePath &file_or_directory_path)
|
||||
|
@ -330,10 +330,10 @@ void AssetCatalogService::load_from_disk(const CatalogFilePath &file_or_director
|
|||
}
|
||||
|
||||
if (S_ISREG(status.st_mode)) {
|
||||
load_single_file(file_or_directory_path);
|
||||
this->load_single_file(file_or_directory_path);
|
||||
}
|
||||
else if (S_ISDIR(status.st_mode)) {
|
||||
load_directory_recursive(file_or_directory_path);
|
||||
this->load_directory_recursive(file_or_directory_path);
|
||||
}
|
||||
else {
|
||||
/* TODO(@sybren): throw an appropriate exception. */
|
||||
|
@ -341,7 +341,7 @@ void AssetCatalogService::load_from_disk(const CatalogFilePath &file_or_director
|
|||
|
||||
/* TODO: Should there be a sanitize step? E.g. to remove catalogs with identical paths? */
|
||||
|
||||
rebuild_tree();
|
||||
this->rebuild_tree();
|
||||
}
|
||||
|
||||
void AssetCatalogService::add_from_existing(const AssetCatalogService &other_service)
|
||||
|
@ -423,7 +423,7 @@ void AssetCatalogService::reload_catalogs()
|
|||
const CatalogID catalog_id = catalog->catalog_id;
|
||||
cats_in_file.add(catalog_id);
|
||||
|
||||
const bool should_skip = is_catalog_known_with_unsaved_changes(catalog_id);
|
||||
const bool should_skip = this->is_catalog_known_with_unsaved_changes(catalog_id);
|
||||
if (should_skip) {
|
||||
/* Do not overwrite unsaved local changes. */
|
||||
return false;
|
||||
|
@ -447,7 +447,7 @@ void AssetCatalogService::purge_catalogs_not_listed(const Set<CatalogID> &catalo
|
|||
if (catalogs_to_keep.contains(cat_id)) {
|
||||
continue;
|
||||
}
|
||||
if (is_catalog_known_with_unsaved_changes(cat_id)) {
|
||||
if (this->is_catalog_known_with_unsaved_changes(cat_id)) {
|
||||
continue;
|
||||
}
|
||||
/* This catalog is not on disk, but also not modified, so get rid of it. */
|
||||
|
@ -455,7 +455,7 @@ void AssetCatalogService::purge_catalogs_not_listed(const Set<CatalogID> &catalo
|
|||
}
|
||||
|
||||
for (CatalogID cat_id : cats_to_remove) {
|
||||
delete_catalog_by_id_hard(cat_id);
|
||||
this->delete_catalog_by_id_hard(cat_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,12 +481,12 @@ bool AssetCatalogService::write_to_disk(const CatalogFilePath &blend_file_path)
|
|||
{
|
||||
BLI_assert(!is_read_only_);
|
||||
|
||||
if (!write_to_disk_ex(blend_file_path)) {
|
||||
if (!this->write_to_disk_ex(blend_file_path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
untag_has_unsaved_changes();
|
||||
rebuild_tree();
|
||||
this->untag_has_unsaved_changes();
|
||||
this->rebuild_tree();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,7 @@ bool AssetCatalogService::write_to_disk_ex(const CatalogFilePath &blend_file_pat
|
|||
|
||||
/* - Already loaded a CDF from disk? -> Always write to that file. */
|
||||
if (catalog_collection_->catalog_definition_file_) {
|
||||
reload_catalogs();
|
||||
this->reload_catalogs();
|
||||
return catalog_collection_->catalog_definition_file_->write_to_disk();
|
||||
}
|
||||
|
||||
|
@ -507,9 +507,10 @@ bool AssetCatalogService::write_to_disk_ex(const CatalogFilePath &blend_file_pat
|
|||
return true; /* Writing nothing when there is nothing to write is still a success. */
|
||||
}
|
||||
|
||||
const CatalogFilePath cdf_path_to_write = find_suitable_cdf_path_for_writing(blend_file_path);
|
||||
catalog_collection_->catalog_definition_file_ = construct_cdf_in_memory(cdf_path_to_write);
|
||||
reload_catalogs();
|
||||
const CatalogFilePath cdf_path_to_write = this->find_suitable_cdf_path_for_writing(
|
||||
blend_file_path);
|
||||
catalog_collection_->catalog_definition_file_ = this->construct_cdf_in_memory(cdf_path_to_write);
|
||||
this->reload_catalogs();
|
||||
return catalog_collection_->catalog_definition_file_->write_to_disk();
|
||||
}
|
||||
|
||||
|
@ -528,7 +529,7 @@ void AssetCatalogService::prepare_to_merge_on_write()
|
|||
|
||||
/* Mark all in-memory catalogs as "dirty", to force them to be kept around on
|
||||
* the next "load-merge-write" cycle. */
|
||||
tag_all_catalogs_as_unsaved_changes();
|
||||
this->tag_all_catalogs_as_unsaved_changes();
|
||||
}
|
||||
|
||||
CatalogFilePath AssetCatalogService::find_suitable_cdf_path_for_writing(
|
||||
|
@ -590,8 +591,8 @@ std::unique_ptr<AssetCatalogTree> AssetCatalogService::read_into_tree()
|
|||
|
||||
void AssetCatalogService::rebuild_tree()
|
||||
{
|
||||
create_missing_catalogs();
|
||||
this->catalog_tree_ = read_into_tree();
|
||||
this->create_missing_catalogs();
|
||||
this->catalog_tree_ = this->read_into_tree();
|
||||
}
|
||||
|
||||
void AssetCatalogService::create_missing_catalogs()
|
||||
|
@ -661,7 +662,7 @@ void AssetCatalogService::redo()
|
|||
|
||||
undo_snapshots_.append(std::move(catalog_collection_));
|
||||
catalog_collection_ = redo_snapshots_.pop_last();
|
||||
rebuild_tree();
|
||||
this->rebuild_tree();
|
||||
AssetLibraryService::get()->rebuild_all_library();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "AS_asset_library.hh"
|
||||
#include "AS_asset_representation.hh"
|
||||
|
||||
#include "BKE_lib_remap.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_preferences.h"
|
||||
|
||||
|
@ -93,36 +94,11 @@ std::string AS_asset_library_find_suitable_root_path_from_main(const Main *bmain
|
|||
return AS_asset_library_find_suitable_root_path_from_path(bmain->filepath);
|
||||
}
|
||||
|
||||
AssetCatalogService *AS_asset_library_get_catalog_service(const AssetLibrary *library)
|
||||
{
|
||||
if (library == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return library->catalog_service.get();
|
||||
}
|
||||
|
||||
AssetCatalogTree *AS_asset_library_get_catalog_tree(const AssetLibrary *library)
|
||||
{
|
||||
AssetCatalogService *catalog_service = AS_asset_library_get_catalog_service(library);
|
||||
if (catalog_service == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return catalog_service->get_catalog_tree();
|
||||
}
|
||||
|
||||
void AS_asset_library_refresh_catalog_simplename(AssetLibrary *asset_library,
|
||||
AssetMetaData *asset_data)
|
||||
{
|
||||
asset_library->refresh_catalog_simplename(asset_data);
|
||||
}
|
||||
|
||||
void AS_asset_library_remap_ids(const IDRemapper *mappings)
|
||||
void AS_asset_library_remap_ids(const bke::id::IDRemapper &mappings)
|
||||
{
|
||||
AssetLibraryService *service = AssetLibraryService::get();
|
||||
service->foreach_loaded_asset_library(
|
||||
[mappings](AssetLibrary &library) { library.remap_ids_and_remove_invalid(*mappings); },
|
||||
true);
|
||||
[mappings](AssetLibrary &library) { library.remap_ids_and_remove_invalid(mappings); }, true);
|
||||
}
|
||||
|
||||
void AS_asset_full_path_explode_from_weak_ref(const AssetWeakReference *asset_reference,
|
||||
|
@ -239,7 +215,7 @@ bool AssetLibrary::remove_asset(AssetRepresentation &asset)
|
|||
return asset_storage_->remove_asset(asset);
|
||||
}
|
||||
|
||||
void AssetLibrary::remap_ids_and_remove_invalid(const IDRemapper &mappings)
|
||||
void AssetLibrary::remap_ids_and_remove_invalid(const bke::id::IDRemapper &mappings)
|
||||
{
|
||||
asset_storage_->remap_ids_and_remove_invalid(mappings);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ OnDiskAssetLibrary::OnDiskAssetLibrary(eAssetLibraryType library_type,
|
|||
StringRef root_path)
|
||||
: AssetLibrary(library_type, name, root_path)
|
||||
{
|
||||
on_blend_save_handler_register();
|
||||
this->on_blend_save_handler_register();
|
||||
}
|
||||
|
||||
void OnDiskAssetLibrary::refresh_catalogs()
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace blender::asset_system {
|
|||
|
||||
RuntimeAssetLibrary::RuntimeAssetLibrary() : AssetLibrary(ASSET_LIBRARY_LOCAL)
|
||||
{
|
||||
on_blend_save_handler_register();
|
||||
this->on_blend_save_handler_register();
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -74,7 +74,7 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return get_asset_library_on_disk_builtin(type, root_path);
|
||||
return this->get_asset_library_on_disk_builtin(type, root_path);
|
||||
}
|
||||
case ASSET_LIBRARY_LOCAL: {
|
||||
/* For the "Current File" library we get the asset library root path based on main. */
|
||||
|
@ -83,14 +83,14 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||
|
||||
if (root_path.empty()) {
|
||||
/* File wasn't saved yet. */
|
||||
return get_asset_library_current_file();
|
||||
return this->get_asset_library_current_file();
|
||||
}
|
||||
return get_asset_library_on_disk_builtin(type, root_path);
|
||||
return this->get_asset_library_on_disk_builtin(type, root_path);
|
||||
}
|
||||
case ASSET_LIBRARY_ALL:
|
||||
return get_asset_library_all(bmain);
|
||||
return this->get_asset_library_all(bmain);
|
||||
case ASSET_LIBRARY_CUSTOM: {
|
||||
bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref(
|
||||
bUserAssetLibrary *custom_library = this->find_custom_asset_library_from_library_ref(
|
||||
library_reference);
|
||||
if (!custom_library) {
|
||||
return nullptr;
|
||||
|
@ -101,7 +101,8 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
AssetLibrary *library = get_asset_library_on_disk_custom(custom_library->name, root_path);
|
||||
AssetLibrary *library = this->get_asset_library_on_disk_custom(custom_library->name,
|
||||
root_path);
|
||||
library->import_method_ = eAssetImportMethod(custom_library->import_method);
|
||||
library->may_override_import_method_ = true;
|
||||
library->use_relative_path_ = (custom_library->flag & ASSET_LIBRARY_RELATIVE_PATH) != 0;
|
||||
|
@ -156,7 +157,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(eAssetLibraryType l
|
|||
AssetLibrary *AssetLibraryService::get_asset_library_on_disk_custom(StringRef name,
|
||||
StringRefNull root_path)
|
||||
{
|
||||
return get_asset_library_on_disk(ASSET_LIBRARY_CUSTOM, name, root_path);
|
||||
return this->get_asset_library_on_disk(ASSET_LIBRARY_CUSTOM, name, root_path);
|
||||
}
|
||||
|
||||
AssetLibrary *AssetLibraryService::get_asset_library_on_disk_builtin(eAssetLibraryType type,
|
||||
|
@ -168,7 +169,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk_builtin(eAssetLibra
|
|||
|
||||
/* Builtin asset libraries don't need a name, the #eAssetLibraryType is enough to identify them
|
||||
* (and doesn't change, unlike the name). */
|
||||
return get_asset_library_on_disk(type, {}, root_path);
|
||||
return this->get_asset_library_on_disk(type, {}, root_path);
|
||||
}
|
||||
|
||||
AssetLibrary *AssetLibraryService::get_asset_library_current_file()
|
||||
|
@ -203,7 +204,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain)
|
|||
}
|
||||
|
||||
/* Ensure all asset libraries are loaded. */
|
||||
get_asset_library(bmain, library_ref);
|
||||
this->get_asset_library(bmain, library_ref);
|
||||
}
|
||||
|
||||
if (all_library_) {
|
||||
|
@ -249,8 +250,8 @@ std::string AssetLibraryService::resolve_asset_weak_reference_to_library_path(
|
|||
|
||||
switch (eAssetLibraryType(asset_reference.asset_library_type)) {
|
||||
case ASSET_LIBRARY_CUSTOM: {
|
||||
bUserAssetLibrary *custom_lib = find_custom_preferences_asset_library_from_asset_weak_ref(
|
||||
asset_reference);
|
||||
bUserAssetLibrary *custom_lib =
|
||||
this->find_custom_preferences_asset_library_from_asset_weak_ref(asset_reference);
|
||||
if (custom_lib) {
|
||||
library_dirpath = custom_lib->dirpath;
|
||||
break;
|
||||
|
@ -258,7 +259,7 @@ std::string AssetLibraryService::resolve_asset_weak_reference_to_library_path(
|
|||
|
||||
/* A bit of an odd-ball, the API supports loading custom libraries from arbitrary paths (used
|
||||
* by unit tests). So check all loaded on-disk libraries too. */
|
||||
AssetLibrary *loaded_custom_lib = find_loaded_on_disk_asset_library_from_name(
|
||||
AssetLibrary *loaded_custom_lib = this->find_loaded_on_disk_asset_library_from_name(
|
||||
asset_reference.asset_library_identifier);
|
||||
if (!loaded_custom_lib) {
|
||||
return "";
|
||||
|
@ -368,7 +369,7 @@ std::optional<AssetLibraryService::ExplodedPath> AssetLibraryService::
|
|||
|
||||
switch (eAssetLibraryType(asset_reference.asset_library_type)) {
|
||||
case ASSET_LIBRARY_LOCAL: {
|
||||
std::string path_in_file = normalize_asset_weak_reference_relative_asset_identifier(
|
||||
std::string path_in_file = this->normalize_asset_weak_reference_relative_asset_identifier(
|
||||
asset_reference);
|
||||
const int64_t group_len = int64_t(path_in_file.find(SEP));
|
||||
|
||||
|
@ -381,14 +382,14 @@ std::optional<AssetLibraryService::ExplodedPath> AssetLibraryService::
|
|||
}
|
||||
case ASSET_LIBRARY_CUSTOM:
|
||||
case ASSET_LIBRARY_ESSENTIALS: {
|
||||
std::string full_path = resolve_asset_weak_reference_to_full_path(asset_reference);
|
||||
std::string full_path = this->resolve_asset_weak_reference_to_full_path(asset_reference);
|
||||
/* #full_path uses native slashes, so others don't need to be considered in the following. */
|
||||
|
||||
if (full_path.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
int64_t blendfile_extension_pos = rfind_blendfile_extension(full_path);
|
||||
int64_t blendfile_extension_pos = this->rfind_blendfile_extension(full_path);
|
||||
BLI_assert(blendfile_extension_pos != StringRef::not_found);
|
||||
|
||||
size_t group_pos = full_path.find(SEP, blendfile_extension_pos);
|
||||
|
|
|
@ -43,7 +43,7 @@ bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
|||
return external_assets_.remove_as(&asset);
|
||||
}
|
||||
|
||||
void AssetStorage::remap_ids_and_remove_invalid(const IDRemapper &mappings)
|
||||
void AssetStorage::remap_ids_and_remove_invalid(const blender::bke::id::IDRemapper &mappings)
|
||||
{
|
||||
Set<AssetRepresentation *> removed_assets{};
|
||||
|
||||
|
@ -51,8 +51,8 @@ void AssetStorage::remap_ids_and_remove_invalid(const IDRemapper &mappings)
|
|||
AssetRepresentation &asset = *asset_ptr;
|
||||
BLI_assert(asset.is_local_id());
|
||||
|
||||
const IDRemapperApplyResult result = BKE_id_remapper_apply(
|
||||
&mappings, &asset.local_asset_id_, ID_REMAP_APPLY_DEFAULT);
|
||||
const IDRemapperApplyResult result = mappings.apply(&asset.local_asset_id_,
|
||||
ID_REMAP_APPLY_DEFAULT);
|
||||
|
||||
/* Entirely remove assets whose ID is unset. We don't want assets with a null ID pointer. */
|
||||
if (result == ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
struct AssetMetaData;
|
||||
struct ID;
|
||||
struct IDRemapper;
|
||||
|
||||
namespace blender::bke::id {
|
||||
class IDRemapper;
|
||||
}
|
||||
|
||||
namespace blender::asset_system {
|
||||
|
||||
|
@ -49,7 +52,7 @@ class AssetStorage {
|
|||
bool remove_asset(AssetRepresentation &asset);
|
||||
|
||||
/** See #AssetLibrary::remap_ids_and_remove_nulled(). */
|
||||
void remap_ids_and_remove_invalid(const IDRemapper &mappings);
|
||||
void remap_ids_and_remove_invalid(const blender::bke::id::IDRemapper &mappings);
|
||||
};
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "blf_internal.hh"
|
||||
#include "blf_internal_types.hh"
|
||||
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_strict_flags.h" /* Keep last. */
|
||||
|
||||
#ifdef WIN32
|
||||
# define FT_New_Face FT_New_Face__win32_compat
|
||||
|
|
|
@ -38,9 +38,10 @@
|
|||
#include "blf_internal_types.hh"
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
|
||||
#include "BLI_strict_flags.h" /* Keep last. */
|
||||
|
||||
/**
|
||||
* Convert glyph coverage amounts to lightness values. Uses a LUT that perceptually improves
|
||||
* anti-aliasing and results in text that looks a bit fuller and slightly brighter. This should
|
||||
|
|
|
@ -11,13 +11,19 @@
|
|||
#include "GPU_texture.h"
|
||||
#include "GPU_vertex_buffer.h"
|
||||
|
||||
struct ColorManagedDisplay;
|
||||
struct FontBLF;
|
||||
struct GPUBatch;
|
||||
struct GPUVertBuf;
|
||||
struct GPUVertBufRaw;
|
||||
|
||||
#include FT_MULTIPLE_MASTERS_H /* Variable font support. */
|
||||
|
||||
/** Maximum variation axes per font. */
|
||||
#define BLF_VARIATIONS_MAX 16
|
||||
|
||||
#define MAKE_DVAR_TAG(a, b, c, d) \
|
||||
(((uint32_t)a << 24u) | ((uint32_t)b << 16u) | ((uint32_t)c << 8u) | ((uint32_t)d))
|
||||
((uint32_t(a) << 24u) | (uint32_t(b) << 16u) | (uint32_t(c) << 8u) | (uint32_t(d)))
|
||||
|
||||
#define BLF_VARIATION_AXIS_WEIGHT MAKE_DVAR_TAG('w', 'g', 'h', 't') /* 'wght' weight axis. */
|
||||
#define BLF_VARIATION_AXIS_SLANT MAKE_DVAR_TAG('s', 'l', 'n', 't') /* 'slnt' slant axis. */
|
||||
|
@ -44,27 +50,27 @@ typedef int32_t ft_pix;
|
|||
#define FT_PIX_ROUND(x) FT_PIX_FLOOR((x) + 32)
|
||||
#define FT_PIX_CEIL(x) ((x) + 63)
|
||||
|
||||
BLI_INLINE int ft_pix_to_int(ft_pix v)
|
||||
inline int ft_pix_to_int(ft_pix v)
|
||||
{
|
||||
return (int)(v >> 6);
|
||||
return int(v >> 6);
|
||||
}
|
||||
|
||||
BLI_INLINE int ft_pix_to_int_floor(ft_pix v)
|
||||
inline int ft_pix_to_int_floor(ft_pix v)
|
||||
{
|
||||
return (int)(v >> 6); /* No need for explicit floor as the bits are removed when shifting. */
|
||||
return int(v >> 6); /* No need for explicit floor as the bits are removed when shifting. */
|
||||
}
|
||||
|
||||
BLI_INLINE int ft_pix_to_int_ceil(ft_pix v)
|
||||
inline int ft_pix_to_int_ceil(ft_pix v)
|
||||
{
|
||||
return (int)(FT_PIX_CEIL(v) >> 6);
|
||||
return int(FT_PIX_CEIL(v) >> 6);
|
||||
}
|
||||
|
||||
BLI_INLINE ft_pix ft_pix_from_int(int v)
|
||||
inline ft_pix ft_pix_from_int(int v)
|
||||
{
|
||||
return v * 64;
|
||||
}
|
||||
|
||||
BLI_INLINE ft_pix ft_pix_from_float(float v)
|
||||
inline ft_pix ft_pix_from_float(float v)
|
||||
{
|
||||
return lroundf(v * 64.0f);
|
||||
}
|
||||
|
@ -79,12 +85,12 @@ BLI_INLINE ft_pix ft_pix_from_float(float v)
|
|||
/** A value in the kerning cache that indicates it is not yet set. */
|
||||
#define KERNING_ENTRY_UNSET INT_MAX
|
||||
|
||||
typedef struct BatchBLF {
|
||||
struct BatchBLF {
|
||||
/** Can only batch glyph from the same font. */
|
||||
struct FontBLF *font;
|
||||
struct GPUBatch *batch;
|
||||
struct GPUVertBuf *verts;
|
||||
struct GPUVertBufRaw pos_step, col_step, offset_step, glyph_size_step, glyph_comp_len_step,
|
||||
FontBLF *font;
|
||||
GPUBatch *batch;
|
||||
GPUVertBuf *verts;
|
||||
GPUVertBufRaw pos_step, col_step, offset_step, glyph_size_step, glyph_comp_len_step,
|
||||
glyph_mode_step;
|
||||
unsigned int pos_loc, col_loc, offset_loc, glyph_size_loc, glyph_comp_len_loc, glyph_mode_loc;
|
||||
unsigned int glyph_len;
|
||||
|
@ -93,22 +99,22 @@ typedef struct BatchBLF {
|
|||
/* Previous call `modelmatrix`. */
|
||||
float mat[4][4];
|
||||
bool enabled, active, simple_shader;
|
||||
struct GlyphCacheBLF *glyph_cache;
|
||||
} BatchBLF;
|
||||
GlyphCacheBLF *glyph_cache;
|
||||
};
|
||||
|
||||
extern BatchBLF g_batch;
|
||||
|
||||
typedef struct KerningCacheBLF {
|
||||
struct KerningCacheBLF {
|
||||
/**
|
||||
* Cache a ascii glyph pairs. Only store the x offset we are interested in,
|
||||
* instead of the full #FT_Vector since it's not used for drawing at the moment.
|
||||
*/
|
||||
int ascii_table[KERNING_CACHE_TABLE_SIZE][KERNING_CACHE_TABLE_SIZE];
|
||||
} KerningCacheBLF;
|
||||
};
|
||||
|
||||
typedef struct GlyphCacheBLF {
|
||||
struct GlyphCacheBLF *next;
|
||||
struct GlyphCacheBLF *prev;
|
||||
struct GlyphCacheBLF {
|
||||
GlyphCacheBLF *next;
|
||||
GlyphCacheBLF *prev;
|
||||
|
||||
/** Font size. */
|
||||
float size;
|
||||
|
@ -133,12 +139,11 @@ typedef struct GlyphCacheBLF {
|
|||
int bitmap_len;
|
||||
int bitmap_len_landed;
|
||||
int bitmap_len_alloc;
|
||||
};
|
||||
|
||||
} GlyphCacheBLF;
|
||||
|
||||
typedef struct GlyphBLF {
|
||||
struct GlyphBLF *next;
|
||||
struct GlyphBLF *prev;
|
||||
struct GlyphBLF {
|
||||
GlyphBLF *next;
|
||||
GlyphBLF *prev;
|
||||
|
||||
/** The character, as UTF-32. */
|
||||
unsigned int c;
|
||||
|
@ -183,10 +188,10 @@ typedef struct GlyphBLF {
|
|||
*/
|
||||
int pos[2];
|
||||
|
||||
struct GlyphCacheBLF *glyph_cache;
|
||||
} GlyphBLF;
|
||||
GlyphCacheBLF *glyph_cache;
|
||||
};
|
||||
|
||||
typedef struct FontBufInfoBLF {
|
||||
struct FontBufInfoBLF {
|
||||
/** For draw to buffer, always set this to NULL after finish! */
|
||||
float *fbuf;
|
||||
|
||||
|
@ -200,17 +205,16 @@ typedef struct FontBufInfoBLF {
|
|||
int ch;
|
||||
|
||||
/** Display device used for color management. */
|
||||
struct ColorManagedDisplay *display;
|
||||
ColorManagedDisplay *display;
|
||||
|
||||
/** The color, the alphas is get from the glyph! (color is sRGB space). */
|
||||
float col_init[4];
|
||||
/** Cached conversion from 'col_init'. */
|
||||
unsigned char col_char[4];
|
||||
float col_float[4];
|
||||
};
|
||||
|
||||
} FontBufInfoBLF;
|
||||
|
||||
typedef struct FontMetrics {
|
||||
struct FontMetrics {
|
||||
/** Indicate that these values have been properly loaded. */
|
||||
bool valid;
|
||||
/** This font's default weight, 100-900, 400 is normal. */
|
||||
|
@ -274,9 +278,9 @@ typedef struct FontMetrics {
|
|||
short superscript_xoffset;
|
||||
/** Positive (!) number of font units below baseline for subscript characters. */
|
||||
short superscript_yoffset;
|
||||
} FontMetrics;
|
||||
};
|
||||
|
||||
typedef struct FontBLF {
|
||||
struct FontBLF {
|
||||
/** Full path to font file or NULL if from memory. */
|
||||
char *filepath;
|
||||
|
||||
|
@ -382,4 +386,4 @@ typedef struct FontBLF {
|
|||
|
||||
/** Mutex lock for glyph cache. */
|
||||
ThreadMutex glyph_cache_mutex;
|
||||
} FontBLF;
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "BLF_api.hh"
|
||||
|
||||
#include "BLI_strict_flags.h"
|
||||
#include "BLI_strict_flags.h" /* Keep last. */
|
||||
|
||||
/* Maximum length of text sample in char32_t, including nullptr terminator. */
|
||||
#define BLF_SAMPLE_LEN 5
|
||||
|
|
|
@ -35,7 +35,8 @@ inline void convert_to_static_type(const CPPType &cpp_type, const Func &func)
|
|||
int8_t,
|
||||
ColorGeometry4f,
|
||||
ColorGeometry4b,
|
||||
math::Quaternion>([&](auto type_tag) {
|
||||
math::Quaternion,
|
||||
float4x4>([&](auto type_tag) {
|
||||
using T = typename decltype(type_tag)::type;
|
||||
if constexpr (std::is_same_v<T, void>) {
|
||||
/* It's expected that the given cpp type is one of the supported ones. */
|
||||
|
@ -517,6 +518,26 @@ class ColorGeometry4bMixer {
|
|||
void finalize(const IndexMask &mask);
|
||||
};
|
||||
|
||||
class float4x4Mixer {
|
||||
private:
|
||||
MutableSpan<float4x4> buffer_;
|
||||
Array<float> total_weights_;
|
||||
Array<float3> location_buffer_;
|
||||
Array<float3> expmap_buffer_;
|
||||
Array<float3> scale_buffer_;
|
||||
|
||||
public:
|
||||
float4x4Mixer(MutableSpan<float4x4> buffer);
|
||||
/**
|
||||
* \param mask: Only initialize these indices. Other indices in the buffer will be invalid.
|
||||
*/
|
||||
float4x4Mixer(MutableSpan<float4x4> buffer, const IndexMask &mask);
|
||||
void set(int64_t index, const float4x4 &value, float weight = 1.0f);
|
||||
void mix_in(int64_t index, const float4x4 &value, float weight = 1.0f);
|
||||
void finalize();
|
||||
void finalize(const IndexMask &mask);
|
||||
};
|
||||
|
||||
template<typename T> struct DefaultMixerStruct {
|
||||
/* Use void by default. This can be checked for in `if constexpr` statements. */
|
||||
using type = void;
|
||||
|
@ -538,6 +559,9 @@ template<> struct DefaultMixerStruct<ColorGeometry4f> {
|
|||
template<> struct DefaultMixerStruct<ColorGeometry4b> {
|
||||
using type = ColorGeometry4bMixer;
|
||||
};
|
||||
template<> struct DefaultMixerStruct<float4x4> {
|
||||
using type = float4x4Mixer;
|
||||
};
|
||||
template<> struct DefaultMixerStruct<int> {
|
||||
static double int_to_double(const int &value)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 2
|
||||
#define BLENDER_FILE_SUBVERSION 3
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
|
|
@ -75,10 +75,10 @@ struct BPathForeachPathData;
|
|||
* \return `true` if the path has been changed, and in that case,
|
||||
* result must be written to `path_dst`.
|
||||
*/
|
||||
typedef bool (*BPathForeachPathFunctionCallback)(BPathForeachPathData *bpath_data,
|
||||
char *path_dst,
|
||||
size_t path_dst_maxncpy,
|
||||
const char *path_src);
|
||||
using BPathForeachPathFunctionCallback = bool (*)(BPathForeachPathData *bpath_data,
|
||||
char *path_dst,
|
||||
size_t path_dst_maxncpy,
|
||||
const char *path_src);
|
||||
|
||||
/** Storage for common data needed across the BPath 'foreach_path' code. */
|
||||
struct BPathForeachPathData {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <mutex>
|
||||
|
||||
#include "BLI_bit_span.hh"
|
||||
#include "BLI_index_mask_fwd.hh"
|
||||
#include "BLI_kdopbvh.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
@ -114,6 +115,13 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
|
|||
BVHCacheType bvh_cache_type,
|
||||
int tree_type);
|
||||
|
||||
/**
|
||||
* Build a bvh tree from the triangles in the mesh that correspond to the faces in the given mask.
|
||||
*/
|
||||
void BKE_bvhtree_from_mesh_tris_init(const Mesh &mesh,
|
||||
const blender::IndexMask &faces_mask,
|
||||
BVHTreeFromMesh &r_data);
|
||||
|
||||
/**
|
||||
* Frees data allocated by a call to `bvhtree_from_mesh_*`.
|
||||
*/
|
||||
|
|
|
@ -69,7 +69,7 @@ struct PointerRNA;
|
|||
* All callbacks here must be exposed via the Python module `bpy.app.handlers`,
|
||||
* see `bpy_app_handlers.cc`.
|
||||
*/
|
||||
typedef enum {
|
||||
enum eCbEvent {
|
||||
BKE_CB_EVT_FRAME_CHANGE_PRE,
|
||||
BKE_CB_EVT_FRAME_CHANGE_POST,
|
||||
BKE_CB_EVT_RENDER_PRE,
|
||||
|
@ -111,7 +111,7 @@ typedef enum {
|
|||
BKE_CB_EVT_EXTENSION_REPOS_SYNC,
|
||||
BKE_CB_EVT_EXTENSION_REPOS_UPGRADE,
|
||||
BKE_CB_EVT_TOT,
|
||||
} eCbEvent;
|
||||
};
|
||||
|
||||
struct bCallbackFuncStore {
|
||||
bCallbackFuncStore *next, *prev;
|
||||
|
|
|
@ -312,8 +312,8 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
|
|||
|
||||
/* Iteration callbacks. */
|
||||
|
||||
typedef void (*BKE_scene_objects_Cb)(Object *ob, void *data);
|
||||
typedef void (*BKE_scene_collections_Cb)(Collection *ob, void *data);
|
||||
using BKE_scene_objects_Cb = void (*)(Object *ob, void *data);
|
||||
using BKE_scene_collections_Cb = void (*)(Collection *ob, void *data);
|
||||
|
||||
/* Iteration over objects in collection. */
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ struct Object;
|
|||
struct rctf;
|
||||
struct TextBox;
|
||||
|
||||
typedef int eBezTriple_Flag__Alias;
|
||||
using eBezTriple_Flag__Alias = int;
|
||||
|
||||
struct CurveCache {
|
||||
ListBase disp;
|
||||
|
|
|
@ -73,7 +73,7 @@ extern const CustomData_MeshMasks CD_MASK_EVERYTHING;
|
|||
* CD_NUMTYPES elements, that indicate if a layer can be copied. */
|
||||
|
||||
/** Add/copy/merge allocation types. */
|
||||
typedef enum eCDAllocType {
|
||||
enum eCDAllocType {
|
||||
/** Allocate and set to default, which is usually just zeroed memory. */
|
||||
CD_SET_DEFAULT = 2,
|
||||
/**
|
||||
|
@ -81,18 +81,18 @@ typedef enum eCDAllocType {
|
|||
* if all layer values will be set by the caller after creating the layer.
|
||||
*/
|
||||
CD_CONSTRUCT = 5,
|
||||
} eCDAllocType;
|
||||
};
|
||||
|
||||
#define CD_TYPE_AS_MASK(_type) (eCustomDataMask)((eCustomDataMask)1 << (eCustomDataMask)(_type))
|
||||
|
||||
void customData_mask_layers__print(const CustomData_MeshMasks *mask);
|
||||
|
||||
typedef void (*cd_interp)(
|
||||
using cd_interp = void (*)(
|
||||
const void **sources, const float *weights, const float *sub_weights, int count, void *dest);
|
||||
typedef void (*cd_copy)(const void *source, void *dest, int count);
|
||||
typedef void (*cd_set_default_value)(void *data, int count);
|
||||
typedef void (*cd_free)(void *data, int count);
|
||||
typedef bool (*cd_validate)(void *item, uint totitems, bool do_fixes);
|
||||
using cd_copy = void (*)(const void *source, void *dest, int count);
|
||||
using cd_set_default_value = void (*)(void *data, int count);
|
||||
using cd_free = void (*)(void *data, int count);
|
||||
using cd_validate = bool (*)(void *item, uint totitems, bool do_fixes);
|
||||
|
||||
/**
|
||||
* Update mask_dst with layers defined in mask_src (equivalent to a bit-wise OR).
|
||||
|
|
|
@ -1,25 +1,13 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace blender::bke {
|
||||
struct GeometrySet;
|
||||
}
|
||||
using GeometrySetHandle = blender::bke::GeometrySet;
|
||||
#else
|
||||
typedef struct GeometrySetHandle GeometrySetHandle;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Depsgraph;
|
||||
struct ID;
|
||||
struct ListBase;
|
||||
|
@ -28,6 +16,9 @@ struct ParticleSystem;
|
|||
struct Scene;
|
||||
struct ViewLayer;
|
||||
struct ViewerPath;
|
||||
namespace blender::bke {
|
||||
struct GeometrySet;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
/* Dupli-Geometry */
|
||||
|
@ -35,31 +26,29 @@ struct ViewerPath;
|
|||
/**
|
||||
* \return a #ListBase of #DupliObject.
|
||||
*/
|
||||
struct ListBase *object_duplilist(struct Depsgraph *depsgraph,
|
||||
struct Scene *sce,
|
||||
struct Object *ob);
|
||||
ListBase *object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob);
|
||||
/**
|
||||
* \return a #ListBase of #DupliObject for the preview geometry referenced by the #ViewerPath.
|
||||
*/
|
||||
struct ListBase *object_duplilist_preview(struct Depsgraph *depsgraph,
|
||||
struct Scene *scene,
|
||||
struct Object *ob,
|
||||
const struct ViewerPath *viewer_path);
|
||||
void free_object_duplilist(struct ListBase *lb);
|
||||
ListBase *object_duplilist_preview(Depsgraph *depsgraph,
|
||||
Scene *scene,
|
||||
Object *ob,
|
||||
const ViewerPath *viewer_path);
|
||||
void free_object_duplilist(ListBase *lb);
|
||||
|
||||
typedef struct DupliObject {
|
||||
struct DupliObject *next, *prev;
|
||||
struct DupliObject {
|
||||
DupliObject *next, *prev;
|
||||
/* Object whose geometry is instanced. */
|
||||
struct Object *ob;
|
||||
Object *ob;
|
||||
/* Data owned by the object above that is instanced. This might not be the same as `ob->data`. */
|
||||
struct ID *ob_data;
|
||||
ID *ob_data;
|
||||
float mat[4][4];
|
||||
float orco[3], uv[2];
|
||||
|
||||
short type; /* from Object.transflag */
|
||||
short type; /* From #Object::transflag. */
|
||||
char no_draw;
|
||||
/* If this dupli object is belongs to a preview, this is non-null. */
|
||||
const GeometrySetHandle *preview_base_geometry;
|
||||
const blender::bke::GeometrySet *preview_base_geometry;
|
||||
/* Index of the top-level instance this dupli is part of or -1 when unused. */
|
||||
int preview_instance_index;
|
||||
|
||||
|
@ -68,7 +57,7 @@ typedef struct DupliObject {
|
|||
int persistent_id[8]; /* MAX_DUPLI_RECUR */
|
||||
|
||||
/* Particle this dupli was generated from. */
|
||||
struct ParticleSystem *particle_system;
|
||||
ParticleSystem *particle_system;
|
||||
|
||||
/* Geometry set stack for instance attributes; for each level lists the
|
||||
* geometry set and instance index within it.
|
||||
|
@ -79,19 +68,19 @@ typedef struct DupliObject {
|
|||
* size between 1 and MAX_DUPLI_RECUR can be used without issues.
|
||||
*/
|
||||
int instance_idx[4];
|
||||
const GeometrySetHandle *instance_data[4];
|
||||
const blender::bke::GeometrySet *instance_data[4];
|
||||
|
||||
/* Random ID for shading */
|
||||
unsigned int random_id;
|
||||
} DupliObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up the RGBA value of a uniform shader attribute.
|
||||
* \return true if the attribute was found; if not, r_value is also set to zero.
|
||||
*/
|
||||
bool BKE_object_dupli_find_rgba_attribute(const struct Object *ob,
|
||||
const struct DupliObject *dupli,
|
||||
const struct Object *dupli_parent,
|
||||
bool BKE_object_dupli_find_rgba_attribute(const Object *ob,
|
||||
const DupliObject *dupli,
|
||||
const Object *dupli_parent,
|
||||
const char *name,
|
||||
float r_value[4]);
|
||||
|
||||
|
@ -99,11 +88,7 @@ bool BKE_object_dupli_find_rgba_attribute(const struct Object *ob,
|
|||
* Look up the RGBA value of a view layer/scene/world shader attribute.
|
||||
* \return true if the attribute was found; if not, r_value is also set to zero.
|
||||
*/
|
||||
bool BKE_view_layer_find_rgba_attribute(const struct Scene *scene,
|
||||
const struct ViewLayer *layer,
|
||||
bool BKE_view_layer_find_rgba_attribute(const Scene *scene,
|
||||
const ViewLayer *layer,
|
||||
const char *name,
|
||||
float r_value[4]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -212,12 +212,13 @@ enum {
|
|||
G_DEBUG_GPU = (1 << 16), /* gpu debug */
|
||||
G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
|
||||
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
|
||||
G_DEBUG_GPU_RENDERDOC = (1 << 19), /* Enable RenderDoc integration. */
|
||||
G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */
|
||||
G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */
|
||||
G_DEBUG_GPU_COMPILE_SHADERS = (1 << 19), /* Compile all statically defined shaders. . */
|
||||
G_DEBUG_GPU_RENDERDOC = (1 << 20), /* Enable RenderDoc integration. */
|
||||
G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
|
||||
G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
|
||||
|
||||
G_DEBUG_GHOST = (1 << 22), /* Debug GHOST module. */
|
||||
G_DEBUG_WINTAB = (1 << 23), /* Debug Wintab. */
|
||||
G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
|
||||
G_DEBUG_WINTAB = (1 << 24), /* Debug Wintab. */
|
||||
};
|
||||
|
||||
#define G_DEBUG_ALL \
|
||||
|
|
|
@ -513,6 +513,8 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
|
|||
LayerGroup(const LayerGroup &other);
|
||||
~LayerGroup();
|
||||
|
||||
LayerGroup &operator=(const LayerGroup &other);
|
||||
|
||||
public:
|
||||
/* Define the common functions for #TreeNode. */
|
||||
TREENODE_COMMON_METHODS;
|
||||
|
|
|
@ -60,40 +60,40 @@ bool BKE_idtype_cache_key_cmp(const void *key_a_v, const void *key_b_v);
|
|||
|
||||
/* ********** Prototypes for #IDTypeInfo callbacks. ********** */
|
||||
|
||||
typedef void (*IDTypeInitDataFunction)(ID *id);
|
||||
using IDTypeInitDataFunction = void (*)(ID *id);
|
||||
|
||||
/** \param flag: Copying options (see BKE_lib_id.hh's LIB_ID_COPY_... flags for more). */
|
||||
typedef void (*IDTypeCopyDataFunction)(Main *bmain, ID *id_dst, const ID *id_src, int flag);
|
||||
using IDTypeCopyDataFunction = void (*)(Main *bmain, ID *id_dst, const ID *id_src, int flag);
|
||||
|
||||
typedef void (*IDTypeFreeDataFunction)(ID *id);
|
||||
using IDTypeFreeDataFunction = void (*)(ID *id);
|
||||
|
||||
/** \param flags: See BKE_lib_id.hh's LIB_ID_MAKELOCAL_... flags. */
|
||||
typedef void (*IDTypeMakeLocalFunction)(Main *bmain, ID *id, int flags);
|
||||
using IDTypeMakeLocalFunction = void (*)(Main *bmain, ID *id, int flags);
|
||||
|
||||
typedef void (*IDTypeForeachIDFunction)(ID *id, LibraryForeachIDData *data);
|
||||
using IDTypeForeachIDFunction = void (*)(ID *id, LibraryForeachIDData *data);
|
||||
|
||||
typedef enum eIDTypeInfoCacheCallbackFlags {
|
||||
enum eIDTypeInfoCacheCallbackFlags {
|
||||
/** Indicates to the callback that cache may be stored in the .blend file,
|
||||
* so its pointer should not be cleared at read-time. */
|
||||
IDTYPE_CACHE_CB_FLAGS_PERSISTENT = 1 << 0,
|
||||
} eIDTypeInfoCacheCallbackFlags;
|
||||
typedef void (*IDTypeForeachCacheFunctionCallback)(
|
||||
ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data);
|
||||
typedef void (*IDTypeForeachCacheFunction)(ID *id,
|
||||
IDTypeForeachCacheFunctionCallback function_callback,
|
||||
void *user_data);
|
||||
};
|
||||
using IDTypeForeachCacheFunctionCallback =
|
||||
void (*)(ID *id, const IDCacheKey *cache_key, void **cache_p, uint flags, void *user_data);
|
||||
using IDTypeForeachCacheFunction = void (*)(ID *id,
|
||||
IDTypeForeachCacheFunctionCallback function_callback,
|
||||
void *user_data);
|
||||
|
||||
typedef void (*IDTypeForeachPathFunction)(ID *id, BPathForeachPathData *bpath_data);
|
||||
using IDTypeForeachPathFunction = void (*)(ID *id, BPathForeachPathData *bpath_data);
|
||||
|
||||
typedef ID **(*IDTypeEmbeddedOwnerPointerGetFunction)(ID *id);
|
||||
using IDTypeEmbeddedOwnerPointerGetFunction = ID **(*)(ID *id);
|
||||
|
||||
typedef void (*IDTypeBlendWriteFunction)(BlendWriter *writer, ID *id, const void *id_address);
|
||||
typedef void (*IDTypeBlendReadDataFunction)(BlendDataReader *reader, ID *id);
|
||||
typedef void (*IDTypeBlendReadAfterLiblinkFunction)(BlendLibReader *reader, ID *id);
|
||||
using IDTypeBlendWriteFunction = void (*)(BlendWriter *writer, ID *id, const void *id_address);
|
||||
using IDTypeBlendReadDataFunction = void (*)(BlendDataReader *reader, ID *id);
|
||||
using IDTypeBlendReadAfterLiblinkFunction = void (*)(BlendLibReader *reader, ID *id);
|
||||
|
||||
typedef void (*IDTypeBlendReadUndoPreserve)(BlendLibReader *reader, ID *id_new, ID *id_old);
|
||||
using IDTypeBlendReadUndoPreserve = void (*)(BlendLibReader *reader, ID *id_new, ID *id_old);
|
||||
|
||||
typedef void (*IDTypeLibOverrideApplyPost)(ID *id_dst, ID *id_src);
|
||||
using IDTypeLibOverrideApplyPost = void (*)(ID *id_dst, ID *id_src);
|
||||
|
||||
struct IDTypeInfo {
|
||||
/* ********** General IDType data. ********** */
|
||||
|
@ -109,6 +109,14 @@ struct IDTypeInfo {
|
|||
*/
|
||||
uint64_t id_filter;
|
||||
|
||||
/**
|
||||
* Known types of ID dependencies.
|
||||
*
|
||||
* Used by #BKE_library_id_can_use_filter_id, together with additional runtime heuristics, to
|
||||
* generate a filter value containing only ID types that given ID could be using.
|
||||
*/
|
||||
uint64_t dependencies_id_types;
|
||||
|
||||
/**
|
||||
* Define the position of this data-block type in the virtual list of all data in a Main that is
|
||||
* returned by `set_listbasepointers()`.
|
||||
|
@ -337,6 +345,24 @@ bool BKE_idtype_idcode_append_is_reusable(short idcode);
|
|||
*/
|
||||
short BKE_idtype_idcode_from_name(const char *idtype_name);
|
||||
|
||||
/**
|
||||
* Convert an \a idcode into an \a idtype_index (e.g. #ID_OB -> #INDEX_ID_OB).
|
||||
*/
|
||||
int BKE_idtype_idcode_to_index(short idcode);
|
||||
/**
|
||||
* Convert an \a idfilter into an \a idtype_index (e.g. #FILTER_ID_OB -> #INDEX_ID_OB).
|
||||
*/
|
||||
int BKE_idtype_idfilter_to_index(uint64_t idfilter);
|
||||
|
||||
/**
|
||||
* Convert an \a idtype_index into an \a idcode (e.g. #INDEX_ID_OB -> #ID_OB).
|
||||
*/
|
||||
short BKE_idtype_index_to_idcode(int idtype_index);
|
||||
/**
|
||||
* Convert an \a idtype_index into an \a idfilter (e.g. #INDEX_ID_OB -> #FILTER_ID_OB).
|
||||
*/
|
||||
uint64_t BKE_idtype_index_to_idfilter(int idtype_index);
|
||||
|
||||
/**
|
||||
* Convert an \a idcode into an \a idfilter (e.g. #ID_OB -> #FILTER_ID_OB).
|
||||
*/
|
||||
|
@ -344,16 +370,7 @@ uint64_t BKE_idtype_idcode_to_idfilter(short idcode);
|
|||
/**
|
||||
* Convert an \a idfilter into an \a idcode (e.g. #FILTER_ID_OB -> #ID_OB).
|
||||
*/
|
||||
short BKE_idtype_idcode_from_idfilter(uint64_t idfilter);
|
||||
|
||||
/**
|
||||
* Convert an \a idcode into an index (e.g. #ID_OB -> #INDEX_ID_OB).
|
||||
*/
|
||||
int BKE_idtype_idcode_to_index(short idcode);
|
||||
/**
|
||||
* Get an \a idcode from an index (e.g. #INDEX_ID_OB -> #ID_OB).
|
||||
*/
|
||||
short BKE_idtype_idcode_from_index(int index);
|
||||
short BKE_idtype_idfilter_to_idcode(uint64_t idfilter);
|
||||
|
||||
/**
|
||||
* Return an ID code and steps the index forward 1.
|
||||
|
@ -361,7 +378,7 @@ short BKE_idtype_idcode_from_index(int index);
|
|||
* \param index: start as 0.
|
||||
* \return the code, 0 when all codes have been returned.
|
||||
*/
|
||||
short BKE_idtype_idcode_iter_step(int *index);
|
||||
short BKE_idtype_idcode_iter_step(int *idtype_index);
|
||||
|
||||
/* Some helpers/wrappers around callbacks defined in #IDTypeInfo, dealing e.g. with embedded IDs.
|
||||
* XXX Ideally those would rather belong to #BKE_lib_id, but using callback function pointers makes
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "DNA_userdef_enums.h"
|
||||
|
||||
struct BlendWriter;
|
||||
|
@ -212,7 +214,7 @@ ID *BKE_libblock_find_name_and_library(Main *bmain,
|
|||
* Duplicate (a.k.a. deep copy) common processing options.
|
||||
* See also eDupli_ID_Flags for options controlling what kind of IDs to duplicate.
|
||||
*/
|
||||
typedef enum eLibIDDuplicateFlags {
|
||||
enum eLibIDDuplicateFlags {
|
||||
/** This call to a duplicate function is part of another call for some parent ID.
|
||||
* Therefore, this sub-process should not clear `newid` pointers, nor handle remapping itself.
|
||||
* NOTE: In some cases (like Object one), the duplicate function may be called on the root ID
|
||||
|
@ -222,7 +224,7 @@ typedef enum eLibIDDuplicateFlags {
|
|||
/** This call is performed on a 'root' ID, and should therefore perform some decisions regarding
|
||||
* sub-IDs (dependencies), check for linked vs. locale data, etc. */
|
||||
LIB_ID_DUPLICATE_IS_ROOT_ID = 1 << 1,
|
||||
} eLibIDDuplicateFlags;
|
||||
};
|
||||
|
||||
ENUM_OPERATORS(eLibIDDuplicateFlags, LIB_ID_DUPLICATE_IS_ROOT_ID)
|
||||
|
||||
|
@ -319,11 +321,23 @@ void BKE_id_delete_ex(Main *bmain, void *idv, const int extra_remapping_flags) A
|
|||
* This is more efficient than calling #BKE_id_delete repetitively on a large set of IDs
|
||||
* (several times faster when deleting most of the IDs at once).
|
||||
*
|
||||
* \warning Considered experimental for now, seems to be working OK but this is
|
||||
* risky code in a complicated area.
|
||||
* \return Number of deleted data-blocks.
|
||||
*/
|
||||
size_t BKE_id_multi_tagged_delete(Main *bmain) ATTR_NONNULL();
|
||||
/**
|
||||
* Properly delete all IDs from \a ids_to_delete, from given \a bmain database.
|
||||
*
|
||||
* This is more efficient than calling #BKE_id_delete repetitively on a large set of IDs
|
||||
* (several times faster when deleting most of the IDs at once).
|
||||
*
|
||||
* \note The ID pointers are not removed from the Set (which may contain more pointers than
|
||||
* originally given, when extra users or dependencies also had to be deleted with the original set
|
||||
* of IDs). They are all freed though, so these pointers are all invalid after calling this
|
||||
* function.
|
||||
*
|
||||
* \return Number of deleted data-blocks.
|
||||
*/
|
||||
size_t BKE_id_multi_delete(Main *bmain, blender::Set<ID *> &ids_to_delete);
|
||||
|
||||
/**
|
||||
* Add a 'NO_MAIN' data-block to given main (also sets user-counts of its IDs if needed).
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
struct IDTypeInfo;
|
||||
struct LibraryForeachIDData;
|
||||
struct Main;
|
||||
|
||||
|
@ -141,7 +142,7 @@ struct LibraryIDLinkCallbackData {
|
|||
*
|
||||
* \return a set of flags to control further iteration (0 to keep going).
|
||||
*/
|
||||
typedef int (*LibraryIDLinkCallback)(LibraryIDLinkCallbackData *cb_data);
|
||||
using LibraryIDLinkCallback = int (*)(LibraryIDLinkCallbackData *cb_data);
|
||||
|
||||
/* Flags for the foreach function itself. */
|
||||
enum {
|
||||
|
@ -299,7 +300,9 @@ bool BKE_library_id_can_use_idtype(ID *owner_id, short id_type_used);
|
|||
/**
|
||||
* Given the owner_id return the type of id_types it can use as a filter_id.
|
||||
*/
|
||||
uint64_t BKE_library_id_can_use_filter_id(const ID *owner_id, const bool include_ui);
|
||||
uint64_t BKE_library_id_can_use_filter_id(const ID *owner_id,
|
||||
const bool include_ui,
|
||||
const IDTypeInfo *owner_id_type = nullptr);
|
||||
|
||||
/**
|
||||
* Check whether given ID is used locally (i.e. by another non-linked ID).
|
||||
|
|
|
@ -21,13 +21,18 @@
|
|||
*/
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
struct ID;
|
||||
struct IDRemapper;
|
||||
struct Main;
|
||||
|
||||
namespace blender::bke::id {
|
||||
class IDRemapper;
|
||||
}
|
||||
|
||||
/* BKE_libblock_free, delete are declared in BKE_lib_id.hh for convenience. */
|
||||
|
||||
/* Also IDRemap->flag. */
|
||||
|
@ -44,10 +49,11 @@ enum {
|
|||
*/
|
||||
ID_REMAP_SKIP_NEVER_NULL_USAGE = 1 << 1,
|
||||
/**
|
||||
* This tells the callback func to flag with #LIB_DOIT all IDs
|
||||
* using target one with a 'never NULL' pointer (like e.g. #Object.data).
|
||||
* Store in the #IDRemapper all IDs using target one with a 'never NULL' pointer (like e.g.
|
||||
* #Object.data), when such ID usage has (or should have) been remapped to `nullptr`. See also
|
||||
* #ID_REMAP_FORCE_NEVER_NULL_USAGE and #ID_REMAP_SKIP_NEVER_NULL_USAGE.
|
||||
*/
|
||||
ID_REMAP_FLAG_NEVER_NULL_USAGE = 1 << 2,
|
||||
ID_REMAP_STORE_NEVER_NULL_USAGE = 1 << 2,
|
||||
/**
|
||||
* This tells the callback func to force setting IDs
|
||||
* using target one with a 'never NULL' pointer to NULL.
|
||||
|
@ -124,9 +130,13 @@ enum eIDRemapType {
|
|||
*
|
||||
* \note Is preferred over BKE_libblock_remap_locked due to performance.
|
||||
*/
|
||||
void BKE_libblock_remap_multiple_locked(Main *bmain, IDRemapper *mappings, const int remap_flags);
|
||||
void BKE_libblock_remap_multiple_locked(Main *bmain,
|
||||
blender::bke::id::IDRemapper &mappings,
|
||||
const int remap_flags);
|
||||
|
||||
void BKE_libblock_remap_multiple(Main *bmain, IDRemapper *mappings, const int remap_flags);
|
||||
void BKE_libblock_remap_multiple(Main *bmain,
|
||||
blender::bke::id::IDRemapper &mappings,
|
||||
const int remap_flags);
|
||||
|
||||
/**
|
||||
* Bare raw remapping of IDs, with no other processing than actually updating the ID pointers.
|
||||
|
@ -137,7 +147,9 @@ void BKE_libblock_remap_multiple(Main *bmain, IDRemapper *mappings, const int re
|
|||
* case e.g. in read-file process.
|
||||
*
|
||||
* WARNING: This call will likely leave the given BMain in invalid state in many aspects. */
|
||||
void BKE_libblock_remap_multiple_raw(Main *bmain, IDRemapper *mappings, const int remap_flags);
|
||||
void BKE_libblock_remap_multiple_raw(Main *bmain,
|
||||
blender::bke::id::IDRemapper &mappings,
|
||||
const int remap_flags);
|
||||
/**
|
||||
* Replace all references in given Main to \a old_id by \a new_id
|
||||
* (if \a new_id is NULL, it unlinks \a old_id).
|
||||
|
@ -153,12 +165,8 @@ void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, int remap_fla
|
|||
/**
|
||||
* Unlink given \a id from given \a bmain
|
||||
* (does not touch to indirect, i.e. library, usages of the ID).
|
||||
*
|
||||
* \param do_flag_never_null: If true, all IDs using \a idv in a 'non-NULL' way are flagged by
|
||||
* #LIB_TAG_DOIT flag (quite obviously, 'non-NULL' usages can never be unlinked by this function).
|
||||
*/
|
||||
void BKE_libblock_unlink(Main *bmain, void *idv, bool do_flag_never_null, bool do_skip_indirect)
|
||||
ATTR_NONNULL();
|
||||
void BKE_libblock_unlink(Main *bmain, void *idv, bool do_skip_indirect) ATTR_NONNULL();
|
||||
|
||||
/**
|
||||
* Similar to libblock_remap, but only affects IDs used by given \a idv ID.
|
||||
|
@ -178,7 +186,7 @@ void BKE_libblock_relink_ex(Main *bmain, void *idv, void *old_idv, void *new_idv
|
|||
void BKE_libblock_relink_multiple(Main *bmain,
|
||||
const blender::Span<ID *> ids,
|
||||
eIDRemapType remap_type,
|
||||
IDRemapper *id_remapper,
|
||||
blender::bke::id::IDRemapper &id_remapper,
|
||||
int remap_flags);
|
||||
|
||||
/**
|
||||
|
@ -193,7 +201,8 @@ void BKE_libblock_relink_multiple(Main *bmain,
|
|||
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL();
|
||||
|
||||
using BKE_library_free_notifier_reference_cb = void (*)(const void *);
|
||||
using BKE_library_remap_editor_id_reference_cb = void (*)(const IDRemapper *mappings);
|
||||
using BKE_library_remap_editor_id_reference_cb =
|
||||
void (*)(const blender::bke::id::IDRemapper &mappings);
|
||||
|
||||
void BKE_library_callback_free_notifier_reference_set(BKE_library_free_notifier_reference_cb func);
|
||||
void BKE_library_callback_remap_editor_id_reference_set(
|
||||
|
@ -220,7 +229,7 @@ enum IDRemapperApplyOptions {
|
|||
*
|
||||
* NOTE: Currently unused by main remapping code, since user-count is handled by
|
||||
* `foreach_libblock_remap_callback_apply` there, depending on whether the remapped pointer does
|
||||
* use it or not. Need for rare cases in UI handling though (see e.g. `image_id_remap` in
|
||||
* use it or not. Needed for rare cases in UI handling though (see e.g. `image_id_remap` in
|
||||
* `space_image.cc`).
|
||||
*/
|
||||
ID_REMAP_APPLY_UPDATE_REFCOUNT = (1 << 0),
|
||||
|
@ -233,9 +242,9 @@ enum IDRemapperApplyOptions {
|
|||
ID_REMAP_APPLY_ENSURE_REAL = (1 << 1),
|
||||
|
||||
/**
|
||||
* Unassign in stead of remap when the new ID data-block would become id_self.
|
||||
* Unassign instead of remap when the new ID pointer would point to itself.
|
||||
*
|
||||
* To use this option 'BKE_id_remapper_apply_ex' must be used with a not-null id_self parameter.
|
||||
* To use this option #IDRemapper::apply must be used with a non-null id_self parameter.
|
||||
*/
|
||||
ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF = (1 << 2),
|
||||
|
||||
|
@ -244,58 +253,83 @@ enum IDRemapperApplyOptions {
|
|||
ENUM_OPERATORS(IDRemapperApplyOptions, ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF)
|
||||
|
||||
using IDRemapperIterFunction = void (*)(ID *old_id, ID *new_id, void *user_data);
|
||||
using IDTypeFilter = uint64_t;
|
||||
|
||||
/**
|
||||
* Create a new ID Remapper.
|
||||
*
|
||||
* An ID remapper stores multiple remapping rules.
|
||||
*/
|
||||
IDRemapper *BKE_id_remapper_create();
|
||||
namespace blender::bke::id {
|
||||
|
||||
void BKE_id_remapper_clear(IDRemapper *id_remapper);
|
||||
bool BKE_id_remapper_is_empty(const IDRemapper *id_remapper);
|
||||
/** Free the given ID Remapper. */
|
||||
void BKE_id_remapper_free(IDRemapper *id_remapper);
|
||||
/** Add a new remapping. Does not replace an existing mapping for `old_id`, if any. */
|
||||
void BKE_id_remapper_add(IDRemapper *id_remapper, ID *old_id, ID *new_id);
|
||||
/** Add a new remapping, replacing a potential already existing mapping of `old_id`. */
|
||||
void BKE_id_remapper_add_overwrite(IDRemapper *id_remapper, ID *old_id, ID *new_id);
|
||||
class IDRemapper {
|
||||
blender::Map<ID *, ID *> mappings_;
|
||||
IDTypeFilter source_types_ = 0;
|
||||
|
||||
/**
|
||||
* Apply a remapping.
|
||||
*
|
||||
* Update the id pointer stored in the given r_id_ptr if a remapping rule exists.
|
||||
*/
|
||||
IDRemapperApplyResult BKE_id_remapper_apply(const IDRemapper *id_remapper,
|
||||
ID **r_id_ptr,
|
||||
IDRemapperApplyOptions options);
|
||||
/**
|
||||
* Apply a remapping.
|
||||
*
|
||||
* Use this function when `ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF`. In this case
|
||||
* the #id_self parameter is required. Otherwise the #BKE_id_remapper_apply can be used.
|
||||
*
|
||||
* \param id_self: required for ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF.
|
||||
* When remapping to id_self it will then be remapped to NULL.
|
||||
*/
|
||||
IDRemapperApplyResult BKE_id_remapper_apply_ex(const IDRemapper *id_remapper,
|
||||
ID **r_id_ptr,
|
||||
IDRemapperApplyOptions options,
|
||||
ID *id_self);
|
||||
bool BKE_id_remapper_has_mapping_for(const IDRemapper *id_remapper, uint64_t type_filter);
|
||||
/**
|
||||
* Store all IDs using another ID with the 'NEVER_NULL' flag, which have (or
|
||||
* should have been) remapped to `nullptr`.
|
||||
*/
|
||||
blender::Set<ID *> never_null_users_;
|
||||
|
||||
/**
|
||||
* Determine the mapping result, without applying the mapping.
|
||||
*/
|
||||
IDRemapperApplyResult BKE_id_remapper_get_mapping_result(const IDRemapper *id_remapper,
|
||||
ID *id,
|
||||
IDRemapperApplyOptions options,
|
||||
const ID *id_self);
|
||||
void BKE_id_remapper_iter(const IDRemapper *id_remapper,
|
||||
IDRemapperIterFunction func,
|
||||
void *user_data);
|
||||
public:
|
||||
void clear(void)
|
||||
{
|
||||
mappings_.clear();
|
||||
never_null_users_.clear();
|
||||
source_types_ = 0;
|
||||
}
|
||||
|
||||
/** Returns a readable string for the given result. Can be used for debugging purposes. */
|
||||
const char *BKE_id_remapper_result_string(const IDRemapperApplyResult result);
|
||||
/** Prints out the rules inside the given id_remapper. Can be used for debugging purposes. */
|
||||
void BKE_id_remapper_print(const IDRemapper *id_remapper);
|
||||
bool is_empty(void) const
|
||||
{
|
||||
return mappings_.is_empty();
|
||||
}
|
||||
|
||||
bool contains_mappings_for_any(IDTypeFilter filter) const
|
||||
{
|
||||
return (source_types_ & filter) != 0;
|
||||
}
|
||||
|
||||
/** Add a new remapping. Does not replace an existing mapping for `old_id`, if any. */
|
||||
void add(ID *old_id, ID *new_id);
|
||||
/** Add a new remapping, replacing a potential already existing mapping of `old_id`. */
|
||||
void add_overwrite(ID *old_id, ID *new_id);
|
||||
|
||||
/** Determine the mapping result, without applying the mapping. */
|
||||
IDRemapperApplyResult get_mapping_result(ID *id,
|
||||
IDRemapperApplyOptions options,
|
||||
const ID *id_self) const;
|
||||
|
||||
/**
|
||||
* Apply a remapping.
|
||||
*
|
||||
* Update the id pointer stored in the given r_id_ptr if a remapping rule exists.
|
||||
*
|
||||
* \param id_self: Only for ID_REMAP_APPLY_UNMAP_WHEN_REMAPPING_TO_SELF.
|
||||
* When remapping to `id_self` it will then be remapped to `nullptr` instead.
|
||||
*/
|
||||
IDRemapperApplyResult apply(ID **r_id_ptr,
|
||||
IDRemapperApplyOptions options,
|
||||
ID *id_self = nullptr) const;
|
||||
|
||||
void never_null_users_add(ID *id)
|
||||
{
|
||||
never_null_users_.add(id);
|
||||
}
|
||||
|
||||
const blender::Set<ID *> &never_null_users(void) const
|
||||
{
|
||||
return never_null_users_;
|
||||
}
|
||||
|
||||
/** Iterate over all remapping pairs in the remapper, and call the callback function on them. */
|
||||
void iter(IDRemapperIterFunction func, void *user_data) const
|
||||
{
|
||||
for (auto item : mappings_.items()) {
|
||||
func(item.key, item.value, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a readable string for the given result. Can be used for debugging purposes. */
|
||||
static const blender::StringRefNull result_to_string(const IDRemapperApplyResult result);
|
||||
|
||||
/** Print out the rules inside the given id_remapper. Can be used for debugging purposes. */
|
||||
void print(void) const;
|
||||
};
|
||||
|
||||
} // namespace blender::bke::id
|
||||
|
|
|
@ -290,6 +290,17 @@ inline int face_triangles_num(const int face_size)
|
|||
return face_size - 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the range of triangles that belong to the given face.
|
||||
*/
|
||||
inline IndexRange face_triangles_range(OffsetIndices<int> faces, int face_i)
|
||||
{
|
||||
const IndexRange face = faces[face_i];
|
||||
/* This is the same as #poly_to_tri_count which is not included here. */
|
||||
const int start_triangle = face.start() - face_i * 2;
|
||||
return IndexRange(start_triangle, face_triangles_num(face.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the index of the edge's vertex that is not the \a vert.
|
||||
*/
|
||||
|
@ -306,6 +317,9 @@ inline int edge_other_vert(const int2 edge, const int vert)
|
|||
|
||||
} // namespace mesh
|
||||
|
||||
/** Create a mesh with no built-in attributes. */
|
||||
Mesh *mesh_new_no_attributes(int verts_num, int edges_num, int faces_num, int corners_num);
|
||||
|
||||
/** Calculate edges from faces. */
|
||||
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges);
|
||||
|
||||
|
|
|
@ -1366,6 +1366,13 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define FN_NODE_ROTATE_VECTOR 1229
|
||||
#define FN_NODE_ROTATE_ROTATION 1230
|
||||
#define FN_NODE_INVERT_ROTATION 1231
|
||||
#define FN_NODE_TRANSFORM_POINT 1232
|
||||
#define FN_NODE_TRANSFORM_DIRECTION 1233
|
||||
#define FN_NODE_MATRIX_MULTIPLY 1234
|
||||
#define FN_NODE_COMBINE_TRANSFORM 1235
|
||||
#define FN_NODE_SEPARATE_TRANSFORM 1236
|
||||
#define FN_NODE_INVERT_MATRIX 1237
|
||||
#define FN_NODE_TRANSPOSE_MATRIX 1238
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ static const bNodeSocketStaticTypeInfo node_socket_subtypes[] = {
|
|||
{"NodeSocketIntFactor", "NodeTreeInterfaceSocketIntFactor", SOCK_INT, PROP_FACTOR},
|
||||
{"NodeSocketBool", "NodeTreeInterfaceSocketBool", SOCK_BOOLEAN, PROP_NONE},
|
||||
{"NodeSocketRotation", "NodeTreeInterfaceSocketRotation", SOCK_ROTATION, PROP_NONE},
|
||||
{"NodeSocketMatrix", "NodeTreeInterfaceSocketMatrix", SOCK_MATRIX, PROP_NONE},
|
||||
{"NodeSocketVector", "NodeTreeInterfaceSocketVector", SOCK_VECTOR, PROP_NONE},
|
||||
{"NodeSocketVectorTranslation",
|
||||
"NodeTreeInterfaceSocketVectorTranslation",
|
||||
|
@ -206,6 +207,7 @@ template<typename Fn> bool socket_data_to_static_type(const eNodeSocketDatatype
|
|||
|
||||
case SOCK_CUSTOM:
|
||||
case SOCK_SHADER:
|
||||
case SOCK_MATRIX:
|
||||
case SOCK_GEOMETRY:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ blender::Vector<Base *> BKE_object_pose_base_array_get(const Scene *scene,
|
|||
void BKE_object_get_parent_matrix(Object *ob, Object *par, float r_parentmat[4][4]);
|
||||
|
||||
/**
|
||||
* Compute object world transform and store it in `ob->object_to_world`.
|
||||
* Compute object world transform and store it in `ob->object_to_world().ptr()`.
|
||||
*/
|
||||
void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob);
|
||||
void BKE_object_where_is_calc_ex(
|
||||
|
|
|
@ -26,6 +26,9 @@ namespace blender::bke {
|
|||
struct GeometrySet;
|
||||
|
||||
struct ObjectRuntime {
|
||||
/** Final transformation matrices with constraints & animsys applied. */
|
||||
float4x4 object_to_world;
|
||||
float4x4 world_to_object;
|
||||
/**
|
||||
* The custom data layer mask that was last used
|
||||
* to calculate data_eval and mesh_deform_eval.
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
#include "BKE_context.hh"
|
||||
|
||||
namespace blender::bke::id {
|
||||
class IDRemapper;
|
||||
}
|
||||
|
||||
namespace blender::asset_system {
|
||||
class AssetRepresentation;
|
||||
}
|
||||
|
@ -28,7 +32,6 @@ struct BlendLibReader;
|
|||
struct BlendWriter;
|
||||
struct Header;
|
||||
struct ID;
|
||||
struct IDRemapper;
|
||||
struct LayoutPanelState;
|
||||
struct LibraryForeachIDData;
|
||||
struct ListBase;
|
||||
|
@ -109,7 +112,7 @@ struct SpaceType {
|
|||
bContextDataCallback context;
|
||||
|
||||
/* Used when we want to replace an ID by another (or NULL). */
|
||||
void (*id_remap)(ScrArea *area, SpaceLink *sl, const IDRemapper *mappings);
|
||||
void (*id_remap)(ScrArea *area, SpaceLink *sl, const blender::bke::id::IDRemapper &mappings);
|
||||
|
||||
/**
|
||||
* foreach_id callback to process all ID pointers of the editor. Used indirectly by lib_query's
|
||||
|
|
|
@ -17,6 +17,7 @@ struct UndoType;
|
|||
struct bContext;
|
||||
|
||||
/* IDs */
|
||||
struct GreasePencil;
|
||||
struct Main;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
|
@ -33,6 +34,7 @@ struct UndoRefID {
|
|||
struct ptr_ty *ptr; \
|
||||
char name[MAX_ID_NAME]; \
|
||||
}
|
||||
UNDO_REF_ID_TYPE(GreasePencil);
|
||||
UNDO_REF_ID_TYPE(Mesh);
|
||||
UNDO_REF_ID_TYPE(Object);
|
||||
UNDO_REF_ID_TYPE(Scene);
|
||||
|
|
|
@ -29,7 +29,10 @@ struct BlendDataReader;
|
|||
struct BlendLibReader;
|
||||
struct LibraryForeachIDData;
|
||||
struct Library;
|
||||
struct IDRemapper;
|
||||
|
||||
namespace blender::bke::id {
|
||||
class IDRemapper;
|
||||
}
|
||||
|
||||
enum ViewerPathEqualFlag {
|
||||
VIEWER_PATH_EQUAL_FLAG_IGNORE_REPEAT_ITERATION = (1 << 0),
|
||||
|
@ -44,7 +47,8 @@ bool BKE_viewer_path_equal(const ViewerPath *a,
|
|||
void BKE_viewer_path_blend_write(BlendWriter *writer, const ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_blend_read_data(BlendDataReader *reader, ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_foreach_id(LibraryForeachIDData *data, ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_id_remap(ViewerPath *viewer_path, const IDRemapper *mappings);
|
||||
void BKE_viewer_path_id_remap(ViewerPath *viewer_path,
|
||||
const blender::bke::id::IDRemapper &mappings);
|
||||
|
||||
ViewerPathElem *BKE_viewer_path_elem_new(ViewerPathElemType type);
|
||||
IDViewerPathElem *BKE_viewer_path_elem_new_id();
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
class WindowManagerRuntime {
|
||||
public:
|
||||
/** Indicates whether interface is locked for user interaction. */
|
||||
bool is_interface_locked = false;
|
||||
|
||||
/** Information and error reports. */
|
||||
ReportList reports;
|
||||
|
||||
WindowManagerRuntime();
|
||||
~WindowManagerRuntime();
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
|
@ -71,8 +71,18 @@ bool BKE_ffmpeg_alpha_channel_is_supported(const RenderData *rd);
|
|||
void *BKE_ffmpeg_context_create(void);
|
||||
void BKE_ffmpeg_context_free(void *context_v);
|
||||
|
||||
void BKE_ffmpeg_exit();
|
||||
|
||||
/**
|
||||
* Gets a `libswscale` context for given size and format parameters.
|
||||
* After you're done using the context, call #BKE_ffmpeg_sws_release_context
|
||||
* to release it. Internally the contexts are coming from the context
|
||||
* pool/cache.
|
||||
*/
|
||||
SwsContext *BKE_ffmpeg_sws_get_context(
|
||||
int width, int height, int av_src_format, int av_dst_format, int sws_flags);
|
||||
void BKE_ffmpeg_sws_release_context(SwsContext *ctx);
|
||||
|
||||
void BKE_ffmpeg_sws_scale_frame(SwsContext *ctx, AVFrame *dst, const AVFrame *src);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -315,6 +315,7 @@ set(SRC
|
|||
intern/volume_grid_file_cache.cc
|
||||
intern/volume_render.cc
|
||||
intern/volume_to_mesh.cc
|
||||
intern/wm_runtime.cc
|
||||
intern/workspace.cc
|
||||
intern/world.cc
|
||||
intern/writeavi.cc
|
||||
|
@ -381,7 +382,7 @@ set(SRC
|
|||
BKE_data_transfer.h
|
||||
BKE_deform.hh
|
||||
BKE_displist.h
|
||||
BKE_duplilist.h
|
||||
BKE_duplilist.hh
|
||||
BKE_dynamicpaint.h
|
||||
BKE_editlattice.h
|
||||
BKE_editmesh.hh
|
||||
|
@ -522,6 +523,7 @@ set(SRC
|
|||
BKE_volume_openvdb.hh
|
||||
BKE_volume_render.hh
|
||||
BKE_volume_to_mesh.hh
|
||||
BKE_wm_runtime.hh
|
||||
BKE_workspace.h
|
||||
BKE_world.h
|
||||
BKE_writeavi.h
|
||||
|
|
|
@ -268,6 +268,7 @@ static AssetTypeInfo AssetType_AC = {
|
|||
IDTypeInfo IDType_ID_AC = {
|
||||
/*id_code*/ ID_AC,
|
||||
/*id_filter*/ FILTER_ID_AC,
|
||||
/*dependencies_id_types*/ 0,
|
||||
/*main_listbase_index*/ INDEX_ID_AC,
|
||||
/*struct_size*/ sizeof(bAction),
|
||||
/*name*/ "Action",
|
||||
|
@ -1711,7 +1712,7 @@ void what_does_obaction(Object *ob,
|
|||
workob->runtime = &workob_runtime;
|
||||
|
||||
/* init workob */
|
||||
copy_m4_m4(workob->object_to_world, ob->object_to_world);
|
||||
copy_m4_m4(workob->runtime->object_to_world.ptr(), ob->object_to_world().ptr());
|
||||
copy_m4_m4(workob->parentinv, ob->parentinv);
|
||||
copy_m4_m4(workob->constinv, ob->constinv);
|
||||
workob->parent = ob->parent;
|
||||
|
|
|
@ -475,6 +475,8 @@ static void armature_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *
|
|||
IDTypeInfo IDType_ID_AR = {
|
||||
/*id_code*/ ID_AR,
|
||||
/*id_filter*/ FILTER_ID_AR,
|
||||
/* IDProps of armature bones can use any type of ID. */
|
||||
/*dependencies_id_types*/ FILTER_ID_ALL,
|
||||
/*main_listbase_index*/ INDEX_ID_AR,
|
||||
/*struct_size*/ sizeof(bArmature),
|
||||
/*name*/ "Armature",
|
||||
|
@ -1992,7 +1994,7 @@ void BKE_armature_mat_world_to_pose(Object *ob, const float inmat[4][4], float o
|
|||
}
|
||||
|
||||
/* Get inverse of (armature) object's matrix. */
|
||||
invert_m4_m4(obmat, ob->object_to_world);
|
||||
invert_m4_m4(obmat, ob->object_to_world().ptr());
|
||||
|
||||
/* multiply given matrix by object's-inverse to find pose-space matrix */
|
||||
mul_m4_m4m4(outmat, inmat, obmat);
|
||||
|
@ -2967,7 +2969,7 @@ void BKE_pose_where_is(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
|||
}
|
||||
}
|
||||
else {
|
||||
invert_m4_m4(ob->world_to_object, ob->object_to_world); /* world_to_object is needed */
|
||||
invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
|
||||
|
||||
/* 1. clear flags */
|
||||
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
|
||||
|
@ -3068,16 +3070,16 @@ void BKE_pchan_minmax(const Object *ob,
|
|||
pchan->custom_translation[0],
|
||||
pchan->custom_translation[1],
|
||||
pchan->custom_translation[2]);
|
||||
mul_m4_series(mat, ob->object_to_world, tmp, rmat, smat);
|
||||
mul_m4_series(mat, ob->object_to_world().ptr(), tmp, rmat, smat);
|
||||
BoundBox bb;
|
||||
BKE_boundbox_init_from_minmax(&bb, bb_custom->min, bb_custom->max);
|
||||
BKE_boundbox_minmax(&bb, mat, r_min, r_max);
|
||||
}
|
||||
else {
|
||||
float vec[3];
|
||||
mul_v3_m4v3(vec, ob->object_to_world, pchan_tx->pose_head);
|
||||
mul_v3_m4v3(vec, ob->object_to_world().ptr(), pchan_tx->pose_head);
|
||||
minmax_v3v3_v3(r_min, r_max, vec);
|
||||
mul_v3_m4v3(vec, ob->object_to_world, pchan_tx->pose_tail);
|
||||
mul_v3_m4v3(vec, ob->object_to_world().ptr(), pchan_tx->pose_tail);
|
||||
minmax_v3v3_v3(r_min, r_max, vec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -600,9 +600,9 @@ static void armature_deform_coords_impl(const Object *ob_arm,
|
|||
data.bmesh.cd_dvert_offset = cd_dvert_offset;
|
||||
|
||||
float obinv[4][4];
|
||||
invert_m4_m4(obinv, ob_target->object_to_world);
|
||||
invert_m4_m4(obinv, ob_target->object_to_world().ptr());
|
||||
|
||||
mul_m4_m4m4(data.postmat, obinv, ob_arm->object_to_world);
|
||||
mul_m4_m4m4(data.postmat, obinv, ob_arm->object_to_world().ptr());
|
||||
invert_m4_m4(data.premat, data.postmat);
|
||||
|
||||
if (em_target != nullptr) {
|
||||
|
|
|
@ -254,11 +254,11 @@ static void apply_curve_transform(
|
|||
* unless the option to allow curve to be positioned elsewhere is activated (i.e. no root).
|
||||
*/
|
||||
if ((ik_data->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0) {
|
||||
mul_m4_v3(ik_data->tar->object_to_world, r_vec);
|
||||
mul_m4_v3(ik_data->tar->object_to_world().ptr(), r_vec);
|
||||
}
|
||||
|
||||
/* Convert the position to pose-space. */
|
||||
mul_m4_v3(ob->world_to_object, r_vec);
|
||||
mul_m4_v3(ob->world_to_object().ptr(), r_vec);
|
||||
|
||||
/* Set the new radius (it should be the average value). */
|
||||
*r_radius = (radius + *r_radius) / 2;
|
||||
|
@ -829,7 +829,7 @@ void BKE_pose_eval_init(Depsgraph *depsgraph, Scene * /*scene*/, Object *object)
|
|||
BLI_assert((object->pose->flag & POSE_RECALC) == 0);
|
||||
|
||||
/* world_to_object is needed for solvers. */
|
||||
invert_m4_m4(object->world_to_object, object->object_to_world);
|
||||
invert_m4_m4(object->runtime->world_to_object.ptr(), object->object_to_world().ptr());
|
||||
|
||||
/* clear flags */
|
||||
for (bPoseChannel *pchan = static_cast<bPoseChannel *>(pose->chanbase.first); pchan != nullptr;
|
||||
|
|
|
@ -52,18 +52,10 @@ AssetMetaData *BKE_asset_metadata_copy(const AssetMetaData *source)
|
|||
|
||||
BKE_asset_metadata_catalog_id_set(copy, source->catalog_id, source->catalog_simple_name);
|
||||
|
||||
if (source->author) {
|
||||
copy->author = BLI_strdup(source->author);
|
||||
}
|
||||
if (source->description) {
|
||||
copy->description = BLI_strdup(source->description);
|
||||
}
|
||||
if (source->copyright) {
|
||||
copy->copyright = BLI_strdup(source->copyright);
|
||||
}
|
||||
if (source->license) {
|
||||
copy->license = BLI_strdup(source->license);
|
||||
}
|
||||
copy->author = BLI_strdup_null(source->author);
|
||||
copy->description = BLI_strdup_null(source->description);
|
||||
copy->copyright = BLI_strdup_null(source->copyright);
|
||||
copy->license = BLI_strdup_null(source->license);
|
||||
|
||||
BLI_duplicatelist(©->tags, &source->tags);
|
||||
copy->active_tag = source->active_tag;
|
||||
|
|
|
@ -50,6 +50,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
|
|||
return &CPPType::get<ColorGeometry4b>();
|
||||
case CD_PROP_QUATERNION:
|
||||
return &CPPType::get<math::Quaternion>();
|
||||
case CD_PROP_FLOAT4X4:
|
||||
return &CPPType::get<float4x4>();
|
||||
case CD_PROP_STRING:
|
||||
return &CPPType::get<MStringProperty>();
|
||||
default:
|
||||
|
@ -89,6 +91,9 @@ eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
|
|||
if (type.is<math::Quaternion>()) {
|
||||
return CD_PROP_QUATERNION;
|
||||
}
|
||||
if (type.is<float4x4>()) {
|
||||
return CD_PROP_FLOAT4X4;
|
||||
}
|
||||
if (type.is<MStringProperty>()) {
|
||||
return CD_PROP_STRING;
|
||||
}
|
||||
|
@ -167,6 +172,8 @@ static int attribute_data_type_complexity(const eCustomDataType data_type)
|
|||
return 8;
|
||||
case CD_PROP_COLOR:
|
||||
return 9;
|
||||
case CD_PROP_FLOAT4X4:
|
||||
return 10;
|
||||
#if 0 /* These attribute types are not supported yet. */
|
||||
case CD_PROP_STRING:
|
||||
return 10;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_math_quaternion.hh"
|
||||
|
||||
#include "BKE_attribute_math.hh"
|
||||
|
@ -36,6 +37,40 @@ math::Quaternion mix4(const float4 &weights,
|
|||
return math::Quaternion::expmap(expmap_mixed);
|
||||
}
|
||||
|
||||
template<> float4x4 mix2(const float factor, const float4x4 &a, const float4x4 &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
}
|
||||
|
||||
template<>
|
||||
float4x4 mix3(const float3 &weights, const float4x4 &v0, const float4x4 &v1, const float4x4 &v2)
|
||||
{
|
||||
const float3 location = mix3(weights, v0.location(), v1.location(), v2.location());
|
||||
const math::Quaternion rotation = mix3(
|
||||
weights, math::to_quaternion(v0), math::to_quaternion(v1), math::to_quaternion(v2));
|
||||
const float3 scale = mix3(weights, math::to_scale(v0), math::to_scale(v1), math::to_scale(v2));
|
||||
return math::from_loc_rot_scale<float4x4>(location, rotation, scale);
|
||||
}
|
||||
|
||||
template<>
|
||||
float4x4 mix4(const float4 &weights,
|
||||
const float4x4 &v0,
|
||||
const float4x4 &v1,
|
||||
const float4x4 &v2,
|
||||
const float4x4 &v3)
|
||||
{
|
||||
const float3 location = mix4(
|
||||
weights, v0.location(), v1.location(), v2.location(), v3.location());
|
||||
const math::Quaternion rotation = mix4(weights,
|
||||
math::to_quaternion(v0),
|
||||
math::to_quaternion(v1),
|
||||
math::to_quaternion(v2),
|
||||
math::to_quaternion(v3));
|
||||
const float3 scale = mix4(
|
||||
weights, math::to_scale(v0), math::to_scale(v1), math::to_scale(v2), math::to_scale(v3));
|
||||
return math::from_loc_rot_scale<float4x4>(location, rotation, scale);
|
||||
}
|
||||
|
||||
ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer,
|
||||
ColorGeometry4f default_color)
|
||||
: ColorGeometry4fMixer(buffer, buffer.index_range(), default_color)
|
||||
|
@ -160,6 +195,58 @@ void ColorGeometry4bMixer::finalize(const IndexMask &mask)
|
|||
});
|
||||
}
|
||||
|
||||
float4x4Mixer::float4x4Mixer(MutableSpan<float4x4> buffer)
|
||||
: float4x4Mixer(buffer, buffer.index_range())
|
||||
{
|
||||
}
|
||||
|
||||
float4x4Mixer::float4x4Mixer(MutableSpan<float4x4> buffer, const IndexMask & /*mask*/)
|
||||
: buffer_(buffer),
|
||||
total_weights_(buffer.size(), 0.0f),
|
||||
location_buffer_(buffer.size(), float3(0)),
|
||||
expmap_buffer_(buffer.size(), float3(0)),
|
||||
scale_buffer_(buffer.size(), float3(0))
|
||||
{
|
||||
}
|
||||
|
||||
void float4x4Mixer::float4x4Mixer::set(int64_t index, const float4x4 &value, const float weight)
|
||||
{
|
||||
location_buffer_[index] = value.location() * weight;
|
||||
expmap_buffer_[index] = math::to_quaternion(value).expmap() * weight;
|
||||
scale_buffer_[index] = math::to_scale(value) * weight;
|
||||
total_weights_[index] = weight;
|
||||
}
|
||||
|
||||
void float4x4Mixer::mix_in(int64_t index, const float4x4 &value, float weight)
|
||||
{
|
||||
location_buffer_[index] += value.location() * weight;
|
||||
expmap_buffer_[index] += math::to_quaternion(value).expmap() * weight;
|
||||
scale_buffer_[index] += math::to_scale(value) * weight;
|
||||
total_weights_[index] += weight;
|
||||
}
|
||||
|
||||
void float4x4Mixer::finalize()
|
||||
{
|
||||
this->finalize(buffer_.index_range());
|
||||
}
|
||||
|
||||
void float4x4Mixer::finalize(const IndexMask &mask)
|
||||
{
|
||||
mask.foreach_index([&](const int64_t i) {
|
||||
const float weight = total_weights_[i];
|
||||
if (weight > 0.0f) {
|
||||
const float weight_inv = math::rcp(weight);
|
||||
buffer_[i] = math::from_loc_rot_scale<float4x4>(
|
||||
location_buffer_[i] * weight_inv,
|
||||
math::Quaternion::expmap(expmap_buffer_[i] * weight_inv),
|
||||
scale_buffer_[i] * weight_inv);
|
||||
}
|
||||
else {
|
||||
buffer_[i] = float4x4::identity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void gather(const GSpan src, const Span<int> map, GMutableSpan dst)
|
||||
{
|
||||
attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
|
||||
|
|
|
@ -1042,6 +1042,10 @@ static std::shared_ptr<io::serialize::Value> serialize_primitive_value(
|
|||
const math::Quaternion value = *static_cast<const math::Quaternion *>(value_ptr);
|
||||
return serialize_float_array({&value.x, 4});
|
||||
}
|
||||
case CD_PROP_FLOAT4X4: {
|
||||
const float4x4 value = *static_cast<const float4x4 *>(value_ptr);
|
||||
return serialize_float_array({value.base_ptr(), value.col_len * value.row_len});
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1160,6 +1164,9 @@ template<typename T>
|
|||
case CD_PROP_QUATERNION: {
|
||||
return deserialize_float_array(io_value, {static_cast<float *>(r_value), 4});
|
||||
}
|
||||
case CD_PROP_FLOAT4X4: {
|
||||
return deserialize_float_array(io_value, {static_cast<float *>(r_value), 4 * 4});
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<voi
|
|||
case SOCK_INT:
|
||||
case SOCK_BOOLEAN:
|
||||
case SOCK_ROTATION:
|
||||
case SOCK_MATRIX:
|
||||
case SOCK_RGBA: {
|
||||
auto &value_variant = *static_cast<SocketValueVariant *>(socket_value);
|
||||
if (value_variant.is_context_dependent_field()) {
|
||||
|
@ -131,6 +132,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(const Span<voi
|
|||
case SOCK_INT:
|
||||
case SOCK_BOOLEAN:
|
||||
case SOCK_ROTATION:
|
||||
case SOCK_MATRIX:
|
||||
case SOCK_RGBA: {
|
||||
const CPPType &base_type = *socket_type_to_geo_nodes_base_cpp_type(socket_type);
|
||||
if (const auto *item = dynamic_cast<const PrimitiveBakeItem *>(&bake_item)) {
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "BKE_report.hh"
|
||||
#include "BKE_screen.hh"
|
||||
#include "BKE_studiolight.h"
|
||||
#include "BKE_writeffmpeg.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
|
@ -74,6 +75,9 @@ void BKE_blender_free()
|
|||
BKE_callback_global_finalize();
|
||||
|
||||
IMB_moviecache_destruct();
|
||||
#ifdef WITH_FFMPEG
|
||||
BKE_ffmpeg_exit();
|
||||
#endif
|
||||
|
||||
BKE_node_system_exit();
|
||||
}
|
||||
|
@ -356,6 +360,11 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
|
|||
* - various minor settings (add as needed).
|
||||
*/
|
||||
|
||||
#define VALUE_SWAP(id) \
|
||||
{ \
|
||||
std::swap(userdef_a->id, userdef_b->id); \
|
||||
}
|
||||
|
||||
#define DATA_SWAP(id) \
|
||||
{ \
|
||||
UserDef userdef_tmp; \
|
||||
|
@ -376,12 +385,12 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
|
|||
} \
|
||||
((void)0)
|
||||
|
||||
std::swap(userdef_a->uistyles, userdef_b->uistyles);
|
||||
std::swap(userdef_a->uifonts, userdef_b->uifonts);
|
||||
std::swap(userdef_a->themes, userdef_b->themes);
|
||||
std::swap(userdef_a->addons, userdef_b->addons);
|
||||
std::swap(userdef_a->user_keymaps, userdef_b->user_keymaps);
|
||||
std::swap(userdef_a->user_keyconfig_prefs, userdef_b->user_keyconfig_prefs);
|
||||
VALUE_SWAP(uistyles);
|
||||
VALUE_SWAP(uifonts);
|
||||
VALUE_SWAP(themes);
|
||||
VALUE_SWAP(addons);
|
||||
VALUE_SWAP(user_keymaps);
|
||||
VALUE_SWAP(user_keyconfig_prefs);
|
||||
|
||||
DATA_SWAP(font_path_ui);
|
||||
DATA_SWAP(font_path_ui_mono);
|
||||
|
@ -395,9 +404,8 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
|
|||
|
||||
DATA_SWAP(ui_scale);
|
||||
|
||||
#undef SWAP_TYPELESS
|
||||
#undef VALUE_SWAP
|
||||
#undef DATA_SWAP
|
||||
#undef LISTBASE_SWAP
|
||||
#undef FLAG_SWAP
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
# include "BPY_extern.h"
|
||||
#endif
|
||||
|
||||
using namespace blender::bke;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Blend/Library Paths
|
||||
* \{ */
|
||||
|
@ -228,7 +230,7 @@ struct ReuseOldBMainData {
|
|||
|
||||
/** Storage for all remapping rules (old_id -> new_id) required by the preservation of old IDs
|
||||
* into the new Main. */
|
||||
IDRemapper *remapper;
|
||||
id::IDRemapper *remapper;
|
||||
bool is_libraries_remapped;
|
||||
|
||||
/** Used to find matching IDs by name/lib in new main, to remap ID usages of data ported over
|
||||
|
@ -246,25 +248,25 @@ struct ReuseOldBMainData {
|
|||
* double of a linked data as a local one, without any known relationships between them. In
|
||||
* practice, this latter case is not expected to commonly happen.
|
||||
*/
|
||||
static IDRemapper *reuse_bmain_data_remapper_ensure(ReuseOldBMainData *reuse_data)
|
||||
static id::IDRemapper &reuse_bmain_data_remapper_ensure(ReuseOldBMainData *reuse_data)
|
||||
{
|
||||
if (reuse_data->is_libraries_remapped) {
|
||||
return reuse_data->remapper;
|
||||
return *reuse_data->remapper;
|
||||
}
|
||||
|
||||
if (reuse_data->remapper == nullptr) {
|
||||
reuse_data->remapper = BKE_id_remapper_create();
|
||||
reuse_data->remapper = MEM_new<id::IDRemapper>(__func__);
|
||||
}
|
||||
|
||||
Main *new_bmain = reuse_data->new_bmain;
|
||||
Main *old_bmain = reuse_data->old_bmain;
|
||||
IDRemapper *remapper = reuse_data->remapper;
|
||||
id::IDRemapper &remapper = *reuse_data->remapper;
|
||||
|
||||
LISTBASE_FOREACH (Library *, old_lib_iter, &old_bmain->libraries) {
|
||||
/* In case newly opened `new_bmain` is a library of the `old_bmain`, remap it to null, since a
|
||||
* file should never ever have linked data from itself. */
|
||||
if (STREQ(old_lib_iter->filepath_abs, new_bmain->filepath)) {
|
||||
BKE_id_remapper_add(remapper, &old_lib_iter->id, nullptr);
|
||||
remapper.add(&old_lib_iter->id, nullptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -277,19 +279,18 @@ static IDRemapper *reuse_bmain_data_remapper_ensure(ReuseOldBMainData *reuse_dat
|
|||
continue;
|
||||
}
|
||||
|
||||
BKE_id_remapper_add(remapper, &old_lib_iter->id, &new_lib_iter->id);
|
||||
remapper.add(&old_lib_iter->id, &new_lib_iter->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
reuse_data->is_libraries_remapped = true;
|
||||
return reuse_data->remapper;
|
||||
return *reuse_data->remapper;
|
||||
}
|
||||
|
||||
static bool reuse_bmain_data_remapper_is_id_remapped(IDRemapper *remapper, ID *id)
|
||||
static bool reuse_bmain_data_remapper_is_id_remapped(id::IDRemapper &remapper, ID *id)
|
||||
{
|
||||
IDRemapperApplyResult result = BKE_id_remapper_get_mapping_result(
|
||||
remapper, id, ID_REMAP_APPLY_DEFAULT, nullptr);
|
||||
IDRemapperApplyResult result = remapper.get_mapping_result(id, ID_REMAP_APPLY_DEFAULT, nullptr);
|
||||
if (ELEM(result, ID_REMAP_RESULT_SOURCE_REMAPPED, ID_REMAP_RESULT_SOURCE_UNASSIGNED)) {
|
||||
/* ID is already remapped to its matching ID in the new main, or explicitly remapped to null,
|
||||
* nothing else to do here. */
|
||||
|
@ -319,7 +320,7 @@ static void swap_old_bmain_data_for_blendfile(ReuseOldBMainData *reuse_data, con
|
|||
ListBase *new_lb = which_libbase(new_bmain, id_code);
|
||||
ListBase *old_lb = which_libbase(old_bmain, id_code);
|
||||
|
||||
IDRemapper *remapper = reuse_bmain_data_remapper_ensure(reuse_data);
|
||||
id::IDRemapper &remapper = reuse_bmain_data_remapper_ensure(reuse_data);
|
||||
|
||||
/* NOTE: Full swapping is only supported for ID types that are assumed to be only local
|
||||
* data-blocks (like UI-like ones). Otherwise, the swapping could fail in many funny ways. */
|
||||
|
@ -346,14 +347,14 @@ static void swap_old_bmain_data_for_blendfile(ReuseOldBMainData *reuse_data, con
|
|||
const int strcmp_result = strcmp(discarded_id_iter->name + 2, reused_id_iter->name + 2);
|
||||
if (strcmp_result == 0) {
|
||||
/* Matching IDs, we can remap the discarded 'new' one to the re-used 'old' one. */
|
||||
BKE_id_remapper_add(remapper, discarded_id_iter, reused_id_iter);
|
||||
remapper.add(discarded_id_iter, reused_id_iter);
|
||||
|
||||
discarded_id_iter = static_cast<ID *>(discarded_id_iter->next);
|
||||
reused_id_iter = static_cast<ID *>(reused_id_iter->next);
|
||||
}
|
||||
else if (strcmp_result < 0) {
|
||||
/* No matching reused 'old' ID for this discarded 'new' one. */
|
||||
BKE_id_remapper_add(remapper, discarded_id_iter, nullptr);
|
||||
remapper.add(discarded_id_iter, nullptr);
|
||||
|
||||
discarded_id_iter = static_cast<ID *>(discarded_id_iter->next);
|
||||
}
|
||||
|
@ -365,7 +366,7 @@ static void swap_old_bmain_data_for_blendfile(ReuseOldBMainData *reuse_data, con
|
|||
for (; discarded_id_iter != nullptr;
|
||||
discarded_id_iter = static_cast<ID *>(discarded_id_iter->next))
|
||||
{
|
||||
BKE_id_remapper_add(remapper, discarded_id_iter, nullptr);
|
||||
remapper.add(discarded_id_iter, nullptr);
|
||||
}
|
||||
|
||||
FOREACH_MAIN_LISTBASE_ID_BEGIN (new_lb, reused_id_iter) {
|
||||
|
@ -374,7 +375,7 @@ static void swap_old_bmain_data_for_blendfile(ReuseOldBMainData *reuse_data, con
|
|||
|
||||
/* Ensure that the reused ID is remapped to itself, since it is known to be in the `new_bmain`.
|
||||
*/
|
||||
BKE_id_remapper_add_overwrite(remapper, reused_id_iter, reused_id_iter);
|
||||
remapper.add_overwrite(reused_id_iter, reused_id_iter);
|
||||
}
|
||||
FOREACH_MAIN_LISTBASE_ID_END;
|
||||
}
|
||||
|
@ -428,8 +429,8 @@ static void swap_wm_data_for_blendfile(ReuseOldBMainData *reuse_data, const bool
|
|||
* new WM, and is responsible to free it properly. */
|
||||
reuse_data->wm_setup_data->old_wm = old_wm;
|
||||
|
||||
IDRemapper *remapper = reuse_bmain_data_remapper_ensure(reuse_data);
|
||||
BKE_id_remapper_add(remapper, &old_wm->id, &new_wm->id);
|
||||
id::IDRemapper &remapper = reuse_bmain_data_remapper_ensure(reuse_data);
|
||||
remapper.add(&old_wm->id, &new_wm->id);
|
||||
}
|
||||
/* Current (old) WM, but no (new) one in file (should only happen when reading pre 2.5 files, no
|
||||
* WM back then), or not loading UI: Keep current WM. */
|
||||
|
@ -452,7 +453,7 @@ static int swap_old_bmain_data_for_blendfile_dependencies_process_cb(
|
|||
ReuseOldBMainData *reuse_data = static_cast<ReuseOldBMainData *>(cb_data->user_data);
|
||||
|
||||
/* First check if it has already been remapped. */
|
||||
IDRemapper *remapper = reuse_bmain_data_remapper_ensure(reuse_data);
|
||||
id::IDRemapper &remapper = reuse_bmain_data_remapper_ensure(reuse_data);
|
||||
if (reuse_bmain_data_remapper_is_id_remapped(remapper, id)) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
@ -461,7 +462,7 @@ static int swap_old_bmain_data_for_blendfile_dependencies_process_cb(
|
|||
BLI_assert(id_map != nullptr);
|
||||
|
||||
ID *id_new = BKE_main_idmap_lookup_id(id_map, id);
|
||||
BKE_id_remapper_add(remapper, id, id_new);
|
||||
remapper.add(id, id_new);
|
||||
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
@ -784,7 +785,7 @@ static void setup_app_data(bContext *C,
|
|||
|
||||
/* Handle all pending remapping from swapping old and new IDs around. */
|
||||
BKE_libblock_remap_multiple_raw(bfd->main,
|
||||
reuse_data.remapper,
|
||||
*reuse_data.remapper,
|
||||
(ID_REMAP_FORCE_UI_POINTERS | ID_REMAP_SKIP_USER_REFCOUNT |
|
||||
ID_REMAP_SKIP_UPDATE_TAGGING | ID_REMAP_SKIP_USER_CLEAR));
|
||||
|
||||
|
@ -793,7 +794,7 @@ static void setup_app_data(bContext *C,
|
|||
* library of the previous opened blendfile'. */
|
||||
reuse_bmain_data_invalid_local_usages_fix(&reuse_data);
|
||||
|
||||
BKE_id_remapper_free(reuse_data.remapper);
|
||||
MEM_delete(reuse_data.remapper);
|
||||
reuse_data.remapper = nullptr;
|
||||
|
||||
wm_data_consistency_ensure(CTX_wm_manager(C), curscene, cur_view_layer);
|
||||
|
@ -938,7 +939,7 @@ static void setup_app_data(bContext *C,
|
|||
BLI_assert(BKE_main_namemap_validate(bmain));
|
||||
|
||||
if (mode != LOAD_UNDO && !USER_EXPERIMENTAL_TEST(&U, no_override_auto_resync)) {
|
||||
reports->duration.lib_overrides_resync = BLI_check_seconds_timer();
|
||||
reports->duration.lib_overrides_resync = BLI_time_now_seconds();
|
||||
|
||||
BKE_lib_override_library_main_resync(
|
||||
bmain,
|
||||
|
@ -946,7 +947,7 @@ static void setup_app_data(bContext *C,
|
|||
bfd->cur_view_layer ? bfd->cur_view_layer : BKE_view_layer_default_view(curscene),
|
||||
reports);
|
||||
|
||||
reports->duration.lib_overrides_resync = BLI_check_seconds_timer() -
|
||||
reports->duration.lib_overrides_resync = BLI_time_now_seconds() -
|
||||
reports->duration.lib_overrides_resync;
|
||||
|
||||
/* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
|
||||
|
|
|
@ -962,7 +962,7 @@ void boids_precalc_rules(ParticleSettings *part, float cfra)
|
|||
if (flbr->ob && flbr->cfra != cfra) {
|
||||
/* save object locations for velocity calculations */
|
||||
copy_v3_v3(flbr->oloc, flbr->loc);
|
||||
copy_v3_v3(flbr->loc, flbr->ob->object_to_world[3]);
|
||||
copy_v3_v3(flbr->loc, flbr->ob->object_to_world().location());
|
||||
flbr->cfra = cfra;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
#include "SEQ_iterator.hh"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
# include "BLI_strict_flags.h"
|
||||
# include "BLI_strict_flags.h" /* Keep last. */
|
||||
#endif
|
||||
|
||||
static CLG_LogRef LOG = {"bke.bpath"};
|
||||
|
|
|
@ -409,6 +409,8 @@ static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
|
|||
IDTypeInfo IDType_ID_BR = {
|
||||
/*id_code*/ ID_BR,
|
||||
/*id_filter*/ FILTER_ID_BR,
|
||||
/*dependencies_id_types*/
|
||||
(FILTER_ID_BR | FILTER_ID_IM | FILTER_ID_PC | FILTER_ID_TE | FILTER_ID_MA),
|
||||
/*main_listbase_index*/ INDEX_ID_BR,
|
||||
/*struct_size*/ sizeof(Brush),
|
||||
/*name*/ "Brush",
|
||||
|
|
|
@ -932,6 +932,53 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
|
|||
return data->tree;
|
||||
}
|
||||
|
||||
void BKE_bvhtree_from_mesh_tris_init(const Mesh &mesh,
|
||||
const blender::IndexMask &faces_mask,
|
||||
BVHTreeFromMesh &r_data)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
|
||||
const Span<float3> positions = mesh.vert_positions();
|
||||
const Span<int2> edges = mesh.edges();
|
||||
const Span<int> corner_verts = mesh.corner_verts();
|
||||
const OffsetIndices faces = mesh.faces();
|
||||
const Span<int3> corner_tris = mesh.corner_tris();
|
||||
bvhtree_from_mesh_setup_data(nullptr,
|
||||
BVHTREE_FROM_CORNER_TRIS,
|
||||
positions,
|
||||
edges,
|
||||
corner_verts,
|
||||
corner_tris,
|
||||
nullptr,
|
||||
&r_data);
|
||||
|
||||
int tris_num = 0;
|
||||
faces_mask.foreach_index(
|
||||
[&](const int i) { tris_num += mesh::face_triangles_num(faces[i].size()); });
|
||||
|
||||
int active_num = -1;
|
||||
BVHTree *tree = bvhtree_new_common(0.0f, 2, 6, tris_num, active_num);
|
||||
r_data.tree = tree;
|
||||
if (tree == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
faces_mask.foreach_index([&](const int face_i) {
|
||||
const IndexRange triangles_range = mesh::face_triangles_range(faces, face_i);
|
||||
for (const int tri_i : triangles_range) {
|
||||
float co[3][3];
|
||||
copy_v3_v3(co[0], positions[corner_verts[corner_tris[tri_i][0]]]);
|
||||
copy_v3_v3(co[1], positions[corner_verts[corner_tris[tri_i][1]]]);
|
||||
copy_v3_v3(co[2], positions[corner_verts[corner_tris[tri_i][2]]]);
|
||||
|
||||
BLI_bvhtree_insert(tree, tri_i, co[0], 3);
|
||||
}
|
||||
});
|
||||
|
||||
BLI_bvhtree_balance(tree);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -121,6 +121,7 @@ static void cache_file_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
IDTypeInfo IDType_ID_CF = {
|
||||
/*id_code*/ ID_CF,
|
||||
/*id_filter*/ FILTER_ID_CF,
|
||||
/*dependencies_id_types*/ 0,
|
||||
/*main_listbase_index*/ INDEX_ID_CF,
|
||||
/*struct_size*/ sizeof(CacheFile),
|
||||
/*name*/ "CacheFile",
|
||||
|
|
|
@ -229,6 +229,7 @@ static void camera_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
IDTypeInfo IDType_ID_CA = {
|
||||
/*id_code*/ ID_CA,
|
||||
/*id_filter*/ FILTER_ID_CA,
|
||||
/*dependencies_id_types*/ FILTER_ID_OB | FILTER_ID_IM,
|
||||
/*main_listbase_index*/ INDEX_ID_CA,
|
||||
/*struct_size*/ sizeof(Camera),
|
||||
/*name*/ "Camera",
|
||||
|
@ -278,16 +279,18 @@ float BKE_camera_object_dof_distance(const Object *ob)
|
|||
}
|
||||
if (cam->dof.focus_object) {
|
||||
float view_dir[3], dof_dir[3];
|
||||
normalize_v3_v3(view_dir, ob->object_to_world[2]);
|
||||
normalize_v3_v3(view_dir, ob->object_to_world().ptr()[2]);
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(cam->dof.focus_object->pose,
|
||||
cam->dof.focus_subtarget);
|
||||
if (pchan) {
|
||||
float posemat[4][4];
|
||||
mul_m4_m4m4(posemat, cam->dof.focus_object->object_to_world, pchan->pose_mat);
|
||||
sub_v3_v3v3(dof_dir, ob->object_to_world[3], posemat[3]);
|
||||
mul_m4_m4m4(posemat, cam->dof.focus_object->object_to_world().ptr(), pchan->pose_mat);
|
||||
sub_v3_v3v3(dof_dir, ob->object_to_world().location(), posemat[3]);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(dof_dir, ob->object_to_world[3], cam->dof.focus_object->object_to_world[3]);
|
||||
sub_v3_v3v3(dof_dir,
|
||||
ob->object_to_world().location(),
|
||||
cam->dof.focus_object->object_to_world().location());
|
||||
}
|
||||
return fabsf(dot_v3v3(view_dir, dof_dir));
|
||||
}
|
||||
|
@ -682,7 +685,7 @@ static void camera_frame_fit_data_init(const Scene *scene,
|
|||
BKE_camera_params_compute_matrix(params);
|
||||
|
||||
/* initialize callback data */
|
||||
copy_m3_m4(data->camera_rotmat, (float(*)[4])ob->object_to_world);
|
||||
copy_m3_m4(data->camera_rotmat, (float(*)[4])ob->object_to_world().ptr());
|
||||
normalize_m3(data->camera_rotmat);
|
||||
/* To transform a plane which is in its homogeneous representation (4d vector),
|
||||
* we need the inverse of the transpose of the transform matrix... */
|
||||
|
@ -884,7 +887,7 @@ bool BKE_camera_view_frame_fit_to_coords(const Depsgraph *depsgraph,
|
|||
|
||||
static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
|
||||
{
|
||||
copy_m4_m4(r_modelmat, camera->object_to_world);
|
||||
copy_m4_m4(r_modelmat, camera->object_to_world().ptr());
|
||||
}
|
||||
|
||||
static void camera_stereo3d_model_matrix(const Object *camera,
|
||||
|
@ -910,7 +913,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
|
|||
}
|
||||
|
||||
float size[3];
|
||||
mat4_to_size(size, camera->object_to_world);
|
||||
mat4_to_size(size, camera->object_to_world().ptr());
|
||||
size_to_mat4(sizemat, size);
|
||||
|
||||
if (pivot == CAM_S3D_PIVOT_CENTER) {
|
||||
|
@ -950,7 +953,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
|
|||
toeinmat[3][0] = interocular_distance * fac_signed;
|
||||
|
||||
/* transform */
|
||||
normalize_m4_m4(r_modelmat, camera->object_to_world);
|
||||
normalize_m4_m4(r_modelmat, camera->object_to_world().ptr());
|
||||
mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
|
||||
|
||||
/* scale back to the original size */
|
||||
|
@ -958,7 +961,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
|
|||
}
|
||||
else { /* CAM_S3D_PIVOT_LEFT, CAM_S3D_PIVOT_RIGHT */
|
||||
/* rotate perpendicular to the interocular line */
|
||||
normalize_m4_m4(r_modelmat, camera->object_to_world);
|
||||
normalize_m4_m4(r_modelmat, camera->object_to_world().ptr());
|
||||
mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
|
||||
|
||||
/* translate along the interocular line */
|
||||
|
@ -974,7 +977,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
|
|||
}
|
||||
}
|
||||
else {
|
||||
normalize_m4_m4(r_modelmat, camera->object_to_world);
|
||||
normalize_m4_m4(r_modelmat, camera->object_to_world().ptr());
|
||||
|
||||
/* translate - no rotation in CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL */
|
||||
translate_m4(r_modelmat, -interocular_distance * fac_signed, 0.0f, 0.0f);
|
||||
|
|
|
@ -272,7 +272,7 @@ static int do_step_cloth(
|
|||
|
||||
/* Get the current position. */
|
||||
copy_v3_v3(verts->xconst, positions[i]);
|
||||
mul_m4_v3(ob->object_to_world, verts->xconst);
|
||||
mul_m4_v3(ob->object_to_world().ptr(), verts->xconst);
|
||||
|
||||
if (vert_mass_changed) {
|
||||
verts->mass = clmd->sim_parms->mass;
|
||||
|
@ -575,11 +575,11 @@ static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexC
|
|||
|
||||
if (clmd->clothObject) {
|
||||
/* Inverse matrix is not up to date. */
|
||||
invert_m4_m4(ob->world_to_object, ob->object_to_world);
|
||||
invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
|
||||
|
||||
for (i = 0; i < cloth->mvert_num; i++) {
|
||||
copy_v3_v3(vertexCos[i], cloth->verts[i].x);
|
||||
mul_m4_v3(ob->world_to_object, vertexCos[i]); /* cloth is in global coords */
|
||||
mul_m4_v3(ob->world_to_object().ptr(), vertexCos[i]); /* cloth is in global coords */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -759,11 +759,11 @@ static bool cloth_from_object(
|
|||
if (first) {
|
||||
copy_v3_v3(verts->x, positions[i]);
|
||||
|
||||
mul_m4_v3(ob->object_to_world, verts->x);
|
||||
mul_m4_v3(ob->object_to_world().ptr(), verts->x);
|
||||
|
||||
if (shapekey_rest) {
|
||||
copy_v3_v3(verts->xrest, shapekey_rest[i]);
|
||||
mul_m4_v3(ob->object_to_world, verts->xrest);
|
||||
mul_m4_v3(ob->object_to_world().ptr(), verts->xrest);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(verts->xrest, verts->x);
|
||||
|
@ -1153,7 +1153,7 @@ static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
|
|||
/* vertex count is already ensured to match */
|
||||
for (i = 0; i < mesh->verts_num; i++, verts++) {
|
||||
copy_v3_v3(verts->xrest, positions[i]);
|
||||
mul_m4_v3(ob->object_to_world, verts->xrest);
|
||||
mul_m4_v3(ob->object_to_world().ptr(), verts->xrest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -376,6 +376,7 @@ static void collection_blend_read_after_liblink(BlendLibReader * /*reader*/, ID
|
|||
IDTypeInfo IDType_ID_GR = {
|
||||
/*id_code*/ ID_GR,
|
||||
/*id_filter*/ FILTER_ID_GR,
|
||||
/*dependencies_id_types*/ FILTER_ID_OB | FILTER_ID_GR,
|
||||
/*main_listbase_index*/ INDEX_ID_GR,
|
||||
/*struct_size*/ sizeof(Collection),
|
||||
/*name*/ "Collection",
|
||||
|
|
|
@ -155,7 +155,7 @@ bConstraintOb *BKE_constraints_make_evalob(
|
|||
/* Quaternion/Axis-Angle, so Eulers should just use default order. */
|
||||
cob->rotOrder = EULER_ORDER_DEFAULT;
|
||||
}
|
||||
copy_m4_m4(cob->matrix, ob->object_to_world);
|
||||
copy_m4_m4(cob->matrix, ob->object_to_world().ptr());
|
||||
}
|
||||
else {
|
||||
unit_m4(cob->matrix);
|
||||
|
@ -181,7 +181,7 @@ bConstraintOb *BKE_constraints_make_evalob(
|
|||
}
|
||||
|
||||
/* matrix in world-space */
|
||||
mul_m4_m4m4(cob->matrix, ob->object_to_world, cob->pchan->pose_mat);
|
||||
mul_m4_m4m4(cob->matrix, ob->object_to_world().ptr(), cob->pchan->pose_mat);
|
||||
}
|
||||
else {
|
||||
unit_m4(cob->matrix);
|
||||
|
@ -222,7 +222,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
|
|||
/* cob->ob might not exist! */
|
||||
if (cob->ob) {
|
||||
/* copy new ob-matrix back to owner */
|
||||
copy_m4_m4(cob->ob->object_to_world, cob->matrix);
|
||||
copy_m4_m4(cob->ob->runtime->object_to_world.ptr(), cob->matrix);
|
||||
|
||||
/* copy inverse of delta back to owner */
|
||||
invert_m4_m4(cob->ob->constinv, delta);
|
||||
|
@ -233,7 +233,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob)
|
|||
/* cob->ob or cob->pchan might not exist */
|
||||
if (cob->ob && cob->pchan) {
|
||||
/* copy new pose-matrix back to owner */
|
||||
mul_m4_m4m4(cob->pchan->pose_mat, cob->ob->world_to_object, cob->matrix);
|
||||
mul_m4_m4m4(cob->pchan->pose_mat, cob->ob->world_to_object().ptr(), cob->matrix);
|
||||
|
||||
/* copy inverse of delta back to owner */
|
||||
invert_m4_m4(cob->pchan->constinv, delta);
|
||||
|
@ -282,7 +282,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
|
|||
}
|
||||
else {
|
||||
/* World to pose. */
|
||||
invert_m4_m4(imat, ob->object_to_world);
|
||||
invert_m4_m4(imat, ob->object_to_world().ptr());
|
||||
mul_m4_m4m4(mat, imat, mat);
|
||||
|
||||
/* Use pose-space as stepping stone for other spaces. */
|
||||
|
@ -326,7 +326,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
|
|||
}
|
||||
else {
|
||||
/* Pose to world. */
|
||||
mul_m4_m4m4(mat, ob->object_to_world, mat);
|
||||
mul_m4_m4m4(mat, ob->object_to_world().ptr(), mat);
|
||||
/* Use world-space as stepping stone for other spaces. */
|
||||
if (to != CONSTRAINT_SPACE_WORLD) {
|
||||
/* Call self with slightly different values. */
|
||||
|
@ -436,7 +436,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
|
|||
/* Check if object has a parent. */
|
||||
if (ob->parent) {
|
||||
/* 'subtract' parent's effects from owner. */
|
||||
mul_m4_m4m4(diff_mat, ob->parent->object_to_world, ob->parentinv);
|
||||
mul_m4_m4m4(diff_mat, ob->parent->object_to_world().ptr(), ob->parentinv);
|
||||
invert_m4_m4_safe(imat, diff_mat);
|
||||
mul_m4_m4m4(mat, imat, mat);
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ void BKE_constraint_mat_convertspace(Object *ob,
|
|||
/* check that object has a parent - otherwise this won't work */
|
||||
if (ob->parent) {
|
||||
/* 'add' parent's effect back to owner */
|
||||
mul_m4_m4m4(diff_mat, ob->parent->object_to_world, ob->parentinv);
|
||||
mul_m4_m4m4(diff_mat, ob->parent->object_to_world().ptr(), ob->parentinv);
|
||||
mul_m4_m4m4(mat, diff_mat, mat);
|
||||
}
|
||||
else {
|
||||
|
@ -525,7 +525,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
|
|||
const int defgroup = BKE_object_defgroup_name_index(ob, substring);
|
||||
|
||||
/* initialize target matrix using target matrix */
|
||||
copy_m4_m4(mat, ob->object_to_world);
|
||||
copy_m4_m4(mat, ob->object_to_world().ptr());
|
||||
|
||||
/* get index of vertex group */
|
||||
if (defgroup == -1) {
|
||||
|
@ -591,7 +591,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
|
|||
* calc_gizmo_stats, V3D_ORIENT_NORMAL case */
|
||||
|
||||
/* We need the transpose of the inverse for a normal. */
|
||||
copy_m3_m4(imat, ob->object_to_world);
|
||||
copy_m3_m4(imat, ob->object_to_world().ptr());
|
||||
|
||||
invert_m3_m3(tmat, imat);
|
||||
transpose_m3(tmat);
|
||||
|
@ -612,7 +612,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
|
|||
normalize_m4(mat);
|
||||
|
||||
/* apply the average coordinate as the new location */
|
||||
mul_v3_m4v3(mat[3], ob->object_to_world, vec);
|
||||
mul_v3_m4v3(mat[3], ob->object_to_world().ptr(), vec);
|
||||
}
|
||||
|
||||
/* function that sets the given matrix based on given vertex group in lattice */
|
||||
|
@ -634,7 +634,7 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
|
|||
const int defgroup = BKE_object_defgroup_name_index(ob, substring);
|
||||
|
||||
/* initialize target matrix using target matrix */
|
||||
copy_m4_m4(mat, ob->object_to_world);
|
||||
copy_m4_m4(mat, ob->object_to_world().ptr());
|
||||
|
||||
/* get index of vertex group */
|
||||
if (defgroup == -1) {
|
||||
|
@ -668,11 +668,12 @@ static void contarget_get_lattice_mat(Object *ob, const char *substring, float m
|
|||
}
|
||||
}
|
||||
|
||||
/* find average location, then multiply by ob->object_to_world to find world-space location */
|
||||
/* find average location, then multiply by ob->object_to_world().ptr() to find world-space
|
||||
* location */
|
||||
if (grouped) {
|
||||
mul_v3_fl(vec, 1.0f / grouped);
|
||||
}
|
||||
mul_v3_m4v3(tvec, ob->object_to_world, vec);
|
||||
mul_v3_m4v3(tvec, ob->object_to_world().ptr(), vec);
|
||||
|
||||
/* copy new location to matrix */
|
||||
copy_v3_v3(mat[3], tvec);
|
||||
|
@ -691,7 +692,7 @@ static void constraint_target_to_mat4(Object *ob,
|
|||
{
|
||||
/* Case OBJECT */
|
||||
if (substring[0] == '\0') {
|
||||
copy_m4_m4(mat, ob->object_to_world);
|
||||
copy_m4_m4(mat, ob->object_to_world().ptr());
|
||||
BKE_constraint_mat_convertspace(ob, nullptr, cob, mat, from, to, false);
|
||||
}
|
||||
/* Case VERTEXGROUP */
|
||||
|
@ -726,7 +727,7 @@ static void constraint_target_to_mat4(Object *ob,
|
|||
|
||||
if (headtail < 0.000001f && !(is_bbone && full_bbone)) {
|
||||
/* skip length interpolation if set to head */
|
||||
mul_m4_m4m4(mat, ob->object_to_world, pchan->pose_mat);
|
||||
mul_m4_m4m4(mat, ob->object_to_world().ptr(), pchan->pose_mat);
|
||||
}
|
||||
else if (is_bbone && pchan->bone->segments == pchan->runtime.bbone_segments) {
|
||||
/* use point along bbone */
|
||||
|
@ -752,7 +753,7 @@ static void constraint_target_to_mat4(Object *ob,
|
|||
mul_v3_m4v3(tempmat[3], pchan->pose_mat, loc);
|
||||
}
|
||||
|
||||
mul_m4_m4m4(mat, ob->object_to_world, tempmat);
|
||||
mul_m4_m4m4(mat, ob->object_to_world().ptr(), tempmat);
|
||||
}
|
||||
else {
|
||||
float tempmat[4][4], loc[3];
|
||||
|
@ -764,11 +765,11 @@ static void constraint_target_to_mat4(Object *ob,
|
|||
copy_m4_m4(tempmat, pchan->pose_mat);
|
||||
copy_v3_v3(tempmat[3], loc);
|
||||
|
||||
mul_m4_m4m4(mat, ob->object_to_world, tempmat);
|
||||
mul_m4_m4m4(mat, ob->object_to_world().ptr(), tempmat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(mat, ob->object_to_world);
|
||||
copy_m4_m4(mat, ob->object_to_world().ptr());
|
||||
}
|
||||
|
||||
/* convert matrix space as required */
|
||||
|
@ -1078,7 +1079,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
|
|||
if (data->flag & CHILDOF_SET_INVERSE) {
|
||||
invert_m4_m4(data->invmat, parmat);
|
||||
if (cob->pchan != nullptr) {
|
||||
mul_m4_series(data->invmat, data->invmat, cob->ob->object_to_world);
|
||||
mul_m4_series(data->invmat, data->invmat, cob->ob->object_to_world().ptr());
|
||||
}
|
||||
|
||||
copy_m4_m4(inverse_matrix, data->invmat);
|
||||
|
@ -1398,8 +1399,8 @@ static void kinematic_get_tarmat(Depsgraph * /*depsgraph*/,
|
|||
else {
|
||||
float vec[3];
|
||||
/* move grabtarget into world space */
|
||||
mul_v3_m4v3(vec, ob->object_to_world, data->grabtarget);
|
||||
copy_m4_m4(ct->matrix, ob->object_to_world);
|
||||
mul_v3_m4v3(vec, ob->object_to_world().ptr(), data->grabtarget);
|
||||
copy_m4_m4(ct->matrix, ob->object_to_world().ptr());
|
||||
copy_v3_v3(ct->matrix[3], vec);
|
||||
}
|
||||
}
|
||||
|
@ -1539,7 +1540,7 @@ static void followpath_get_tarmat(Depsgraph * /*depsgraph*/,
|
|||
|
||||
copy_v3_v3(totmat[3], vec);
|
||||
|
||||
mul_m4_m4m4(ct->matrix, ct->tar->object_to_world, totmat);
|
||||
mul_m4_m4m4(ct->matrix, ct->tar->object_to_world().ptr(), totmat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2569,7 +2570,7 @@ static void armdef_get_tarmat(Depsgraph * /*depsgraph*/,
|
|||
bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget);
|
||||
|
||||
if (pchan != nullptr) {
|
||||
mul_m4_m4m4(ct->matrix, ct->tar->object_to_world, pchan->pose_mat);
|
||||
mul_m4_m4m4(ct->matrix, ct->tar->object_to_world().ptr(), pchan->pose_mat);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2626,7 +2627,7 @@ static void armdef_accumulate_bone(const bConstraintTarget *ct,
|
|||
float weight = ct->weight;
|
||||
|
||||
/* Our object's location in target pose space. */
|
||||
invert_m4_m4(iobmat, ct->tar->object_to_world);
|
||||
invert_m4_m4(iobmat, ct->tar->object_to_world().ptr());
|
||||
mul_v3_m4v3(co, iobmat, wco);
|
||||
|
||||
/* Multiply by the envelope weight when appropriate. */
|
||||
|
@ -2651,7 +2652,7 @@ static void armdef_accumulate_bone(const bConstraintTarget *ct,
|
|||
mul_m4_m4m4(basemat, bone->arm_mat, b_bone_rest_mats[index].mat);
|
||||
}
|
||||
|
||||
armdef_accumulate_matrix(ct->tar->object_to_world,
|
||||
armdef_accumulate_matrix(ct->tar->object_to_world().ptr(),
|
||||
iobmat,
|
||||
basemat,
|
||||
b_bone_mats[index + 1].mat,
|
||||
|
@ -2665,7 +2666,7 @@ static void armdef_accumulate_bone(const bConstraintTarget *ct,
|
|||
mul_m4_m4m4(basemat, bone->arm_mat, b_bone_rest_mats[index + 1].mat);
|
||||
}
|
||||
|
||||
armdef_accumulate_matrix(ct->tar->object_to_world,
|
||||
armdef_accumulate_matrix(ct->tar->object_to_world().ptr(),
|
||||
iobmat,
|
||||
basemat,
|
||||
b_bone_mats[index + 2].mat,
|
||||
|
@ -2676,7 +2677,7 @@ static void armdef_accumulate_bone(const bConstraintTarget *ct,
|
|||
}
|
||||
else {
|
||||
/* Simple bone. This requires DEG_OPCODE_BONE_DONE dependency due to chan_mat. */
|
||||
armdef_accumulate_matrix(ct->tar->object_to_world,
|
||||
armdef_accumulate_matrix(ct->tar->object_to_world().ptr(),
|
||||
iobmat,
|
||||
bone->arm_mat,
|
||||
pchan->chan_mat,
|
||||
|
@ -2709,7 +2710,7 @@ static void armdef_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ
|
|||
/* For constraints on bones, use the rest position to bind b-bone segments
|
||||
* and envelopes, to allow safely changing the bone location as if parented. */
|
||||
copy_v3_v3(input_co, cob->pchan->bone->arm_head);
|
||||
mul_m4_v3(cob->ob->object_to_world, input_co);
|
||||
mul_m4_v3(cob->ob->object_to_world().ptr(), input_co);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(input_co, cob->matrix[3]);
|
||||
|
@ -3941,7 +3942,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
|
|||
unit_m4(totmat);
|
||||
copy_v3_v3(totmat[3], vec);
|
||||
|
||||
mul_m4_m4m4(targetMatrix, ct->tar->object_to_world, totmat);
|
||||
mul_m4_m4m4(targetMatrix, ct->tar->object_to_world().ptr(), totmat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4242,7 +4243,7 @@ static void shrinkwrap_get_tarmat(Depsgraph * /*depsgraph*/,
|
|||
if (BKE_shrinkwrap_init_tree(
|
||||
&tree, target_eval, scon->shrinkType, scon->shrinkMode, do_track_normal))
|
||||
{
|
||||
BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->object_to_world);
|
||||
BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->object_to_world().ptr());
|
||||
|
||||
switch (scon->shrinkType) {
|
||||
case MOD_SHRINKWRAP_NEAREST_SURFACE:
|
||||
|
@ -4916,7 +4917,7 @@ static void followtrack_evaluate_using_3d_position_object(FollowTrackContext *co
|
|||
|
||||
/* Object matrix of the camera. */
|
||||
float camera_obmat[4][4];
|
||||
copy_m4_m4(camera_obmat, camera_object->object_to_world);
|
||||
copy_m4_m4(camera_obmat, camera_object->object_to_world().ptr());
|
||||
|
||||
/* Calculate inverted matrix of the solved camera at the current time. */
|
||||
float reconstructed_camera_mat[4][4];
|
||||
|
@ -5068,10 +5069,11 @@ static void followtrack_project_to_depth_object_if_needed(FollowTrackContext *co
|
|||
}
|
||||
|
||||
float depth_object_mat_inv[4][4];
|
||||
invert_m4_m4(depth_object_mat_inv, depth_object->object_to_world);
|
||||
invert_m4_m4(depth_object_mat_inv, depth_object->object_to_world().ptr());
|
||||
|
||||
float ray_start[3], ray_end[3];
|
||||
mul_v3_m4v3(ray_start, depth_object_mat_inv, context->camera_object->object_to_world[3]);
|
||||
mul_v3_m4v3(
|
||||
ray_start, depth_object_mat_inv, context->camera_object->object_to_world().location());
|
||||
mul_v3_m4v3(ray_end, depth_object_mat_inv, cob->matrix[3]);
|
||||
|
||||
float ray_direction[3];
|
||||
|
@ -5094,7 +5096,7 @@ static void followtrack_project_to_depth_object_if_needed(FollowTrackContext *co
|
|||
&tree_data);
|
||||
|
||||
if (result != -1) {
|
||||
mul_v3_m4v3(cob->matrix[3], depth_object->object_to_world, hit.co);
|
||||
mul_v3_m4v3(cob->matrix[3], depth_object->object_to_world().ptr(), hit.co);
|
||||
}
|
||||
|
||||
free_bvhtree_from_mesh(&tree_data);
|
||||
|
@ -5142,9 +5144,9 @@ static void followtrack_evaluate_using_2d_position(FollowTrackContext *context,
|
|||
}
|
||||
|
||||
float disp[3];
|
||||
mul_v3_m4v3(disp, camera_object->object_to_world, vec);
|
||||
mul_v3_m4v3(disp, camera_object->object_to_world().ptr(), vec);
|
||||
|
||||
copy_m4_m4(rmat, camera_object->object_to_world);
|
||||
copy_m4_m4(rmat, camera_object->object_to_world().ptr());
|
||||
zero_v3(rmat[3]);
|
||||
mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
|
||||
|
||||
|
@ -5166,10 +5168,10 @@ static void followtrack_evaluate_using_2d_position(FollowTrackContext *context,
|
|||
}
|
||||
|
||||
float disp[3];
|
||||
mul_v3_m4v3(disp, camera_object->object_to_world, vec);
|
||||
mul_v3_m4v3(disp, camera_object->object_to_world().ptr(), vec);
|
||||
|
||||
/* apply camera rotation so Z-axis would be co-linear */
|
||||
copy_m4_m4(rmat, camera_object->object_to_world);
|
||||
copy_m4_m4(rmat, camera_object->object_to_world().ptr());
|
||||
zero_v3(rmat[3]);
|
||||
mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
|
||||
|
||||
|
@ -5315,7 +5317,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
|
|||
BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, mat);
|
||||
|
||||
invert_m4_m4(imat, mat);
|
||||
mul_m4_m4m4(parmat, camob->object_to_world, imat);
|
||||
mul_m4_m4m4(parmat, camob->object_to_world().ptr(), imat);
|
||||
|
||||
copy_m4_m4(obmat, cob->matrix);
|
||||
|
||||
|
@ -5668,7 +5670,7 @@ bool BKE_constraint_apply_for_object(Depsgraph *depsgraph,
|
|||
BLI_freelinkN(&single_con, new_con);
|
||||
|
||||
/* Apply transform from matrix. */
|
||||
BKE_object_apply_mat4(ob, ob_eval->object_to_world, true, true);
|
||||
BKE_object_apply_mat4(ob, ob_eval->object_to_world().ptr(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -6261,7 +6263,7 @@ void BKE_constraint_target_matrix_get(Depsgraph *depsgraph,
|
|||
cob->ob = (Object *)ownerdata;
|
||||
cob->pchan = nullptr;
|
||||
if (cob->ob) {
|
||||
copy_m4_m4(cob->matrix, cob->ob->object_to_world);
|
||||
copy_m4_m4(cob->matrix, cob->ob->object_to_world().ptr());
|
||||
copy_m4_m4(cob->startmat, cob->matrix);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "BKE_scene.hh"
|
||||
#include "BKE_screen.hh"
|
||||
#include "BKE_sound.h"
|
||||
#include "BKE_wm_runtime.hh"
|
||||
#include "BKE_workspace.h"
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
@ -706,7 +707,7 @@ wmWindowManager *CTX_wm_manager(const bContext *C)
|
|||
|
||||
bool CTX_wm_interface_locked(const bContext *C)
|
||||
{
|
||||
return bool(C->wm.manager->is_interface_locked);
|
||||
return C->wm.manager->runtime->is_interface_locked;
|
||||
}
|
||||
|
||||
wmWindow *CTX_wm_window(const bContext *C)
|
||||
|
@ -766,7 +767,7 @@ wmMsgBus *CTX_wm_message_bus(const bContext *C)
|
|||
ReportList *CTX_wm_reports(const bContext *C)
|
||||
{
|
||||
if (C->wm.manager) {
|
||||
return &(C->wm.manager->reports);
|
||||
return &(C->wm.manager->runtime->reports);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -271,6 +271,7 @@ static void curve_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
IDTypeInfo IDType_ID_CU_LEGACY = {
|
||||
/*id_code*/ ID_CU_LEGACY,
|
||||
/*id_filter*/ FILTER_ID_CU_LEGACY,
|
||||
/*dependencies_id_types*/ FILTER_ID_OB | FILTER_ID_MA | FILTER_ID_VF | FILTER_ID_KE,
|
||||
/*main_listbase_index*/ INDEX_ID_CU_LEGACY,
|
||||
/*struct_size*/ sizeof(Curve),
|
||||
/*name*/ "Curve",
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
/* Needed with MSVC for M_PI & M_PI_2 */
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_math_base.h" /* Needed with MSVC for M_PI & M_PI_2. */
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ extern "C" {
|
|||
#include "curve_fit_nd.h"
|
||||
}
|
||||
|
||||
#include "BLI_strict_flags.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "BLI_strict_flags.h" /* Keep last. */
|
||||
|
||||
struct Knot {
|
||||
Knot *next, *prev;
|
||||
uint point_index; /* Index in point array. */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue