Mesh: Replace auto smooth with node group #108014
|
@ -8,7 +8,7 @@
|
|||
# It also supports non-standard names for the library components.
|
||||
#
|
||||
# To use a custom IlmBase:
|
||||
# - Set the variable ILMBASE_CUSTOM to True
|
||||
# - Set the variable ILMBASE_CUSTOM to TRUE
|
||||
# - Set the variable ILMBASE_CUSTOM_LIBRARIES to a list of the libraries to
|
||||
# use, e.g. "SpiImath SpiHalf SpiIlmThread SpiIex"
|
||||
# - Optionally set the variable ILMBASE_CUSTOM_INCLUDE_DIR to any
|
||||
|
@ -20,7 +20,7 @@
|
|||
#
|
||||
# ILMBASE_INCLUDE_DIR - where to find half.h, IlmBaseConfig.h, etc.
|
||||
# ILMBASE_LIBRARIES - list of libraries to link against when using IlmBase.
|
||||
# ILMBASE_FOUND - True if IlmBase was found.
|
||||
# ILMBASE_FOUND - TRUE if IlmBase was found.
|
||||
|
||||
# Other standard issue macros
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# It also supports non-standard names for the library components.
|
||||
#
|
||||
# To use a custom OpenEXR
|
||||
# - Set the variable OPENEXR_CUSTOM to True
|
||||
# - Set the variable OPENEXR_CUSTOM to TRUE
|
||||
# - Set the variable OPENEXR_CUSTOM_LIBRARY to the name of the library to
|
||||
# use, e.g. "SpiIlmImf"
|
||||
# - Optionally set the variable OPENEXR_CUSTOM_INCLUDE_DIR to any
|
||||
|
@ -22,7 +22,7 @@
|
|||
# OPENEXR_LIBRARIES - list of libraries to link against when using OpenEXR.
|
||||
# This list does NOT include the IlmBase libraries.
|
||||
# These are defined by the FindIlmBase module.
|
||||
# OPENEXR_FOUND - True if OpenEXR was found.
|
||||
# OPENEXR_FOUND - TRUE if OpenEXR was found.
|
||||
|
||||
# Other standard issue macros
|
||||
include(SelectLibraryConfigurations)
|
||||
|
|
|
@ -20,14 +20,14 @@ else()
|
|||
# Choose the best suitable libraries.
|
||||
if(EXISTS ${LIBDIR_NATIVE_ABI})
|
||||
set(LIBDIR ${LIBDIR_NATIVE_ABI})
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND TRUE)
|
||||
elseif(EXISTS ${LIBDIR_GLIBC228_ABI})
|
||||
set(LIBDIR ${LIBDIR_GLIBC228_ABI})
|
||||
if(WITH_MEM_JEMALLOC)
|
||||
# jemalloc provides malloc hooks.
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False)
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND FALSE)
|
||||
else()
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1034,7 +1034,7 @@ endif()
|
|||
|
||||
if(WITH_VULKAN_BACKEND)
|
||||
if(EXISTS ${LIBDIR}/vulkan)
|
||||
set(VULKAN_FOUND On)
|
||||
set(VULKAN_FOUND ON)
|
||||
set(VULKAN_ROOT_DIR ${LIBDIR}/vulkan)
|
||||
set(VULKAN_INCLUDE_DIR ${VULKAN_ROOT_DIR}/include)
|
||||
set(VULKAN_INCLUDE_DIRS ${VULKAN_INCLUDE_DIR})
|
||||
|
@ -1048,7 +1048,7 @@ endif()
|
|||
|
||||
if(WITH_VULKAN_BACKEND)
|
||||
if(EXISTS ${LIBDIR}/shaderc)
|
||||
set(SHADERC_FOUND On)
|
||||
set(SHADERC_FOUND ON)
|
||||
set(SHADERC_ROOT_DIR ${LIBDIR}/shaderc)
|
||||
set(SHADERC_INCLUDE_DIR ${SHADERC_ROOT_DIR}/include)
|
||||
set(SHADERC_INCLUDE_DIRS ${SHADERC_INCLUDE_DIR})
|
||||
|
|
|
@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
|||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = V3.6
|
||||
PROJECT_NUMBER = V4.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
|
|
@ -67,7 +67,7 @@ if(UNIX AND NOT APPLE)
|
|||
add_subdirectory(libc_compat)
|
||||
endif()
|
||||
|
||||
if (WITH_RENDERDOC)
|
||||
if(WITH_RENDERDOC)
|
||||
add_subdirectory(renderdoc_dynload)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -262,6 +262,11 @@ string OneapiDevice::oneapi_error_message()
|
|||
return string(oneapi_error_string_);
|
||||
}
|
||||
|
||||
int OneapiDevice::scene_max_shaders()
|
||||
{
|
||||
return scene_max_shaders_;
|
||||
}
|
||||
|
||||
void *OneapiDevice::kernel_globals_device_pointer()
|
||||
{
|
||||
return kg_memory_device_;
|
||||
|
@ -436,6 +441,9 @@ void OneapiDevice::const_copy_to(const char *name, void *host, size_t size)
|
|||
/* Update scene handle(since it is different for each device on multi devices) */
|
||||
KernelData *const data = (KernelData *)host;
|
||||
data->device_bvh = embree_scene;
|
||||
|
||||
/* We need this number later for proper local memory allocation. */
|
||||
scene_max_shaders_ = data->max_shaders;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ class OneapiDevice : public Device {
|
|||
std::string oneapi_error_string_;
|
||||
bool use_hardware_raytracing = false;
|
||||
unsigned int kernel_features = 0;
|
||||
int scene_max_shaders_ = 0;
|
||||
|
||||
public:
|
||||
virtual BVHLayoutMask get_bvh_layout_mask(uint kernel_features) const override;
|
||||
|
@ -61,6 +62,8 @@ class OneapiDevice : public Device {
|
|||
|
||||
string oneapi_error_message();
|
||||
|
||||
int scene_max_shaders();
|
||||
|
||||
void *kernel_globals_device_pointer();
|
||||
|
||||
void mem_alloc(device_memory &mem) override;
|
||||
|
|
|
@ -59,7 +59,7 @@ void OneapiDeviceQueue::init_execution()
|
|||
void *kg_dptr = (void *)oneapi_device_->kernel_globals_device_pointer();
|
||||
assert(device_queue);
|
||||
assert(kg_dptr);
|
||||
kernel_context_ = new KernelContext{device_queue, kg_dptr};
|
||||
kernel_context_ = new KernelContext{device_queue, kg_dptr, 0};
|
||||
|
||||
debug_init_execution();
|
||||
}
|
||||
|
@ -78,12 +78,13 @@ bool OneapiDeviceQueue::enqueue(DeviceKernel kernel,
|
|||
assert(signed_kernel_work_size >= 0);
|
||||
size_t kernel_work_size = (size_t)signed_kernel_work_size;
|
||||
|
||||
assert(kernel_context_);
|
||||
kernel_context_->scene_max_shaders = oneapi_device_->scene_max_shaders();
|
||||
|
||||
size_t kernel_local_size = oneapi_kernel_preferred_local_size(
|
||||
kernel_context_->queue, (::DeviceKernel)kernel, kernel_work_size);
|
||||
size_t uniformed_kernel_work_size = round_up(kernel_work_size, kernel_local_size);
|
||||
|
||||
assert(kernel_context_);
|
||||
|
||||
/* Call the oneAPI kernel DLL to launch the requested kernel. */
|
||||
bool is_finished_ok = oneapi_device_->enqueue_kernel(
|
||||
kernel_context_, kernel, uniformed_kernel_work_size, args);
|
||||
|
|
|
@ -39,6 +39,11 @@ class OneapiDeviceQueue : public DeviceQueue {
|
|||
virtual void copy_to_device(device_memory &mem) override;
|
||||
virtual void copy_from_device(device_memory &mem) override;
|
||||
|
||||
virtual bool supports_local_atomic_sort() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
OneapiDevice *oneapi_device_;
|
||||
KernelContext *kernel_context_;
|
||||
|
|
|
@ -385,11 +385,17 @@ void PathTraceWorkGPU::enqueue_reset()
|
|||
|
||||
queue_->enqueue(DEVICE_KERNEL_INTEGRATOR_RESET, max_num_paths_, args);
|
||||
queue_->zero_to_device(integrator_queue_counter_);
|
||||
queue_->zero_to_device(integrator_shader_sort_counter_);
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
|
||||
if (integrator_shader_sort_counter_.size() != 0) {
|
||||
queue_->zero_to_device(integrator_shader_sort_counter_);
|
||||
}
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_NODE_RAYTRACE &&
|
||||
integrator_shader_raytrace_sort_counter_.size() != 0)
|
||||
{
|
||||
queue_->zero_to_device(integrator_shader_raytrace_sort_counter_);
|
||||
}
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_MNEE) {
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_MNEE &&
|
||||
integrator_shader_mnee_sort_counter_.size() != 0)
|
||||
{
|
||||
queue_->zero_to_device(integrator_shader_mnee_sort_counter_);
|
||||
}
|
||||
|
||||
|
|
|
@ -847,6 +847,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
-DWITH_ONEAPI
|
||||
-ffast-math
|
||||
-O2
|
||||
-D__KERNEL_LOCAL_ATOMIC_SORT__
|
||||
-o"${cycles_kernel_oneapi_lib}"
|
||||
-I"${CMAKE_CURRENT_SOURCE_DIR}/.."
|
||||
${SYCL_CPP_FLAGS}
|
||||
|
|
|
@ -432,6 +432,17 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
|
|||
}
|
||||
ccl_gpu_kernel_postfix
|
||||
|
||||
/* oneAPI verion needs the local_mem accessor in the arguments. */
|
||||
#ifdef __KERNEL_ONEAPI__
|
||||
ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
||||
ccl_gpu_kernel_signature(integrator_sort_bucket_pass,
|
||||
int num_states,
|
||||
int partition_size,
|
||||
int num_states_limit,
|
||||
ccl_global int *indices,
|
||||
int kernel_index,
|
||||
sycl::local_accessor<int> &local_mem)
|
||||
#else
|
||||
ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
||||
ccl_gpu_kernel_signature(integrator_sort_bucket_pass,
|
||||
int num_states,
|
||||
|
@ -439,9 +450,9 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
int num_states_limit,
|
||||
ccl_global int *indices,
|
||||
int kernel_index)
|
||||
#endif
|
||||
{
|
||||
#if defined(__KERNEL_LOCAL_ATOMIC_SORT__)
|
||||
int max_shaders = context.launch_params_metal.data.max_shaders;
|
||||
ccl_global ushort *d_queued_kernel = (ccl_global ushort *)
|
||||
kernel_integrator_state.path.queued_kernel;
|
||||
ccl_global uint *d_shader_sort_key = (ccl_global uint *)
|
||||
|
@ -449,6 +460,20 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
ccl_global int *key_offsets = (ccl_global int *)
|
||||
kernel_integrator_state.sort_partition_key_offsets;
|
||||
|
||||
# ifdef __KERNEL_METAL__
|
||||
int max_shaders = context.launch_params_metal.data.max_shaders;
|
||||
# endif
|
||||
|
||||
# ifdef __KERNEL_ONEAPI__
|
||||
/* Metal backend doesn't have these particular ccl_gpu_* defines and current kernel code
|
||||
* uses metal_*, we need the below to be compatible with these kernels. */
|
||||
int max_shaders = ((ONEAPIKernelContext *)kg)->__data->max_shaders;
|
||||
int metal_local_id = ccl_gpu_thread_idx_x;
|
||||
int metal_local_size = ccl_gpu_block_dim_x;
|
||||
int metal_grid_id = ccl_gpu_block_idx_x;
|
||||
ccl_gpu_shared int *threadgroup_array = local_mem.get_pointer();
|
||||
# endif
|
||||
|
||||
gpu_parallel_sort_bucket_pass(num_states,
|
||||
partition_size,
|
||||
max_shaders,
|
||||
|
@ -456,7 +481,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
d_queued_kernel,
|
||||
d_shader_sort_key,
|
||||
key_offsets,
|
||||
(threadgroup int *)threadgroup_array,
|
||||
(ccl_gpu_shared int *)threadgroup_array,
|
||||
metal_local_id,
|
||||
metal_local_size,
|
||||
metal_grid_id);
|
||||
|
@ -464,6 +489,17 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
}
|
||||
ccl_gpu_kernel_postfix
|
||||
|
||||
/* oneAPI verion needs the local_mem accessor in the arguments. */
|
||||
#ifdef __KERNEL_ONEAPI__
|
||||
ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
||||
ccl_gpu_kernel_signature(integrator_sort_write_pass,
|
||||
int num_states,
|
||||
int partition_size,
|
||||
int num_states_limit,
|
||||
ccl_global int *indices,
|
||||
int kernel_index,
|
||||
sycl::local_accessor<int> &local_mem)
|
||||
#else
|
||||
ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
||||
ccl_gpu_kernel_signature(integrator_sort_write_pass,
|
||||
int num_states,
|
||||
|
@ -471,9 +507,10 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
int num_states_limit,
|
||||
ccl_global int *indices,
|
||||
int kernel_index)
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(__KERNEL_LOCAL_ATOMIC_SORT__)
|
||||
int max_shaders = context.launch_params_metal.data.max_shaders;
|
||||
ccl_global ushort *d_queued_kernel = (ccl_global ushort *)
|
||||
kernel_integrator_state.path.queued_kernel;
|
||||
ccl_global uint *d_shader_sort_key = (ccl_global uint *)
|
||||
|
@ -481,6 +518,20 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
ccl_global int *key_offsets = (ccl_global int *)
|
||||
kernel_integrator_state.sort_partition_key_offsets;
|
||||
|
||||
# ifdef __KERNEL_METAL__
|
||||
int max_shaders = context.launch_params_metal.data.max_shaders;
|
||||
# endif
|
||||
|
||||
# ifdef __KERNEL_ONEAPI__
|
||||
/* Metal backend doesn't have these particular ccl_gpu_* defines and current kernel code
|
||||
* uses metal_*, we need the below to be compatible with these kernels. */
|
||||
int max_shaders = ((ONEAPIKernelContext *)kg)->__data->max_shaders;
|
||||
int metal_local_id = ccl_gpu_thread_idx_x;
|
||||
int metal_local_size = ccl_gpu_block_dim_x;
|
||||
int metal_grid_id = ccl_gpu_block_idx_x;
|
||||
ccl_gpu_shared int *threadgroup_array = local_mem.get_pointer();
|
||||
# endif
|
||||
|
||||
gpu_parallel_sort_write_pass(num_states,
|
||||
partition_size,
|
||||
max_shaders,
|
||||
|
@ -490,7 +541,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
|
|||
d_queued_kernel,
|
||||
d_shader_sort_key,
|
||||
key_offsets,
|
||||
(threadgroup int *)threadgroup_array,
|
||||
(ccl_gpu_shared int *)threadgroup_array,
|
||||
metal_local_id,
|
||||
metal_local_size,
|
||||
metal_grid_id);
|
||||
|
|
|
@ -23,11 +23,6 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
#if defined(__KERNEL_LOCAL_ATOMIC_SORT__)
|
||||
|
||||
# define atomic_store_local(p, x) \
|
||||
atomic_store_explicit((threadgroup atomic_int *)p, x, memory_order_relaxed)
|
||||
# define atomic_load_local(p) \
|
||||
atomic_load_explicit((threadgroup atomic_int *)p, memory_order_relaxed)
|
||||
|
||||
ccl_device_inline void gpu_parallel_sort_bucket_pass(const uint num_states,
|
||||
const uint partition_size,
|
||||
const uint max_shaders,
|
||||
|
@ -45,7 +40,13 @@ ccl_device_inline void gpu_parallel_sort_bucket_pass(const uint num_states,
|
|||
atomic_store_local(&buckets[local_id], 0);
|
||||
}
|
||||
|
||||
# ifdef __KERNEL_ONEAPI__
|
||||
/* NOTE(@nsirgien): For us here only local memory writing (buckets) is important,
|
||||
* so faster local barriers can be used. */
|
||||
ccl_gpu_local_syncthreads();
|
||||
# else
|
||||
ccl_gpu_syncthreads();
|
||||
# endif
|
||||
|
||||
/* Determine bucket sizes within the partitions. */
|
||||
|
||||
|
@ -58,11 +59,17 @@ ccl_device_inline void gpu_parallel_sort_bucket_pass(const uint num_states,
|
|||
ushort kernel_index = d_queued_kernel[state_index];
|
||||
if (kernel_index == queued_kernel) {
|
||||
uint key = d_shader_sort_key[state_index] % max_shaders;
|
||||
atomic_fetch_and_add_uint32(&buckets[key], 1);
|
||||
atomic_fetch_and_add_uint32_shared(&buckets[key], 1);
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef __KERNEL_ONEAPI__
|
||||
/* NOTE(@nsirgien): For us here only local memory writing (buckets) is important,
|
||||
* so faster local barriers can be used. */
|
||||
ccl_gpu_local_syncthreads();
|
||||
# else
|
||||
ccl_gpu_syncthreads();
|
||||
# endif
|
||||
|
||||
/* Calculate the partition's local offsets from the prefix sum of bucket sizes. */
|
||||
|
||||
|
@ -106,7 +113,13 @@ ccl_device_inline void gpu_parallel_sort_write_pass(const uint num_states,
|
|||
atomic_store_local(&local_offset[local_id], key_offsets[local_id] + partition_offset);
|
||||
}
|
||||
|
||||
# ifdef __KERNEL_ONEAPI__
|
||||
/* NOTE(@nsirgien): For us here only local memory writing (local_offset) is important,
|
||||
* so faster local barriers can be used. */
|
||||
ccl_gpu_local_syncthreads();
|
||||
# else
|
||||
ccl_gpu_syncthreads();
|
||||
# endif
|
||||
|
||||
/* Write the sorted active indices. */
|
||||
|
||||
|
@ -121,7 +134,7 @@ ccl_device_inline void gpu_parallel_sort_write_pass(const uint num_states,
|
|||
ushort kernel_index = d_queued_kernel[state_index];
|
||||
if (kernel_index == queued_kernel) {
|
||||
uint key = d_shader_sort_key[state_index] % max_shaders;
|
||||
int index = atomic_fetch_and_add_uint32(&local_offset[key], 1);
|
||||
int index = atomic_fetch_and_add_uint32_shared(&local_offset[key], 1);
|
||||
if (index < num_states_limit) {
|
||||
indices[index] = state_index;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define ccl_loop_no_unroll
|
||||
#define ccl_optional_struct_init
|
||||
#define ccl_private
|
||||
#define ccl_gpu_shared
|
||||
#define ATTR_FALLTHROUGH __attribute__((fallthrough))
|
||||
#define ccl_constant const
|
||||
#define ccl_try_align(...) __attribute__((aligned(__VA_ARGS__)))
|
||||
|
|
|
@ -2,8 +2,40 @@
|
|||
* Copyright 2021-2022 Intel Corporation */
|
||||
|
||||
#ifdef WITH_NANOVDB
|
||||
/* Data type to replace `double` used in the NanoVDB headers. Cycles don't need doubles, and is
|
||||
* safer and more portable to never use double datatype on GPU.
|
||||
* Use a special structure, so that the following is true:
|
||||
* - No unnoticed implicit cast or mathematical operations used on scalar 64bit type
|
||||
* (which rules out trick like using `uint64_t` as a drop-in replacement for double).
|
||||
* - Padding rules are matching exactly `double`
|
||||
* (which rules out array of `uint8_t`). */
|
||||
typedef struct ccl_vdb_double_t {
|
||||
union ccl_vdb_helper_t {
|
||||
double d;
|
||||
uint64_t i;
|
||||
};
|
||||
|
||||
uint64_t i;
|
||||
ccl_vdb_double_t(double value)
|
||||
{
|
||||
ccl_vdb_helper_t helper;
|
||||
helper.d = value;
|
||||
i = helper.i;
|
||||
}
|
||||
/* We intentionally allow conversion to float in order to workaround compilation errors
|
||||
* for defined math functions that take doubles. */
|
||||
operator float() const
|
||||
{
|
||||
ccl_vdb_helper_t helper;
|
||||
helper.i = i;
|
||||
return (float)helper.d;
|
||||
}
|
||||
} ccl_vdb_double_t;
|
||||
|
||||
# define double ccl_vdb_double_t
|
||||
# include <nanovdb/NanoVDB.h>
|
||||
# include <nanovdb/util/SampleFromVoxels.h>
|
||||
# undef double
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
|
|
|
@ -109,7 +109,10 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue,
|
|||
assert(queue);
|
||||
(void)kernel_global_size;
|
||||
const static size_t preferred_work_group_size_intersect_shading = 32;
|
||||
const static size_t preferred_work_group_size_technical = 1024;
|
||||
/* Shader evalutation kernels seems to use some amount of shared memory, so better
|
||||
* to avoid usage of maximum work group sizes for them. */
|
||||
const static size_t preferred_work_group_size_shader_evaluation = 256;
|
||||
const static size_t preferred_work_group_size_default = 1024;
|
||||
|
||||
size_t preferred_work_group_size = 0;
|
||||
switch (kernel) {
|
||||
|
@ -133,19 +136,36 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue,
|
|||
case DEVICE_KERNEL_INTEGRATOR_QUEUED_SHADOW_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_TERMINATED_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_STATES:
|
||||
case DEVICE_KERNEL_INTEGRATOR_TERMINATED_SHADOW_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_PATHS_ARRAY:
|
||||
preferred_work_group_size = GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE;
|
||||
break;
|
||||
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_STATES:
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES:
|
||||
case DEVICE_KERNEL_INTEGRATOR_RESET:
|
||||
case DEVICE_KERNEL_INTEGRATOR_SHADOW_CATCHER_COUNT_POSSIBLE_SPLITS:
|
||||
preferred_work_group_size = preferred_work_group_size_technical;
|
||||
preferred_work_group_size = GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE;
|
||||
break;
|
||||
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORT_BUCKET_PASS:
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORT_WRITE_PASS:
|
||||
preferred_work_group_size = GPU_PARALLEL_SORT_BLOCK_SIZE;
|
||||
break;
|
||||
|
||||
case DEVICE_KERNEL_PREFIX_SUM:
|
||||
preferred_work_group_size = GPU_PARALLEL_PREFIX_SUM_DEFAULT_BLOCK_SIZE;
|
||||
break;
|
||||
|
||||
case DEVICE_KERNEL_SHADER_EVAL_DISPLACE:
|
||||
case DEVICE_KERNEL_SHADER_EVAL_BACKGROUND:
|
||||
case DEVICE_KERNEL_SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY:
|
||||
preferred_work_group_size = preferred_work_group_size_shader_evaluation;
|
||||
break;
|
||||
|
||||
default:
|
||||
preferred_work_group_size = 512;
|
||||
preferred_work_group_size = preferred_work_group_size_default;
|
||||
break;
|
||||
}
|
||||
|
||||
const size_t limit_work_group_size = reinterpret_cast<sycl::queue *>(queue)
|
||||
|
@ -316,12 +336,6 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context,
|
|||
kernel_context->queue, device_kernel, global_size);
|
||||
assert(global_size % local_size == 0);
|
||||
|
||||
/* Local size for DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY needs to be enforced so we
|
||||
* overwrite it outside of oneapi_kernel_preferred_local_size. */
|
||||
if (device_kernel == DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY) {
|
||||
local_size = GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Kernels listed below need a specific number of work groups. */
|
||||
if (device_kernel == DEVICE_KERNEL_INTEGRATOR_ACTIVE_PATHS_ARRAY ||
|
||||
device_kernel == DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY ||
|
||||
|
@ -353,6 +367,14 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context,
|
|||
# pragma GCC diagnostic error "-Wswitch"
|
||||
# endif
|
||||
|
||||
int max_shaders = 0;
|
||||
|
||||
if (device_kernel == DEVICE_KERNEL_INTEGRATOR_SORT_BUCKET_PASS ||
|
||||
device_kernel == DEVICE_KERNEL_INTEGRATOR_SORT_WRITE_PASS)
|
||||
{
|
||||
max_shaders = (kernel_context->scene_max_shaders);
|
||||
}
|
||||
|
||||
try {
|
||||
queue->submit([&](sycl::handler &cgh) {
|
||||
# ifdef WITH_EMBREE_GPU
|
||||
|
@ -495,13 +517,31 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context,
|
|||
break;
|
||||
}
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORT_BUCKET_PASS: {
|
||||
oneapi_call(
|
||||
kg, cgh, global_size, local_size, args, oneapi_kernel_integrator_sort_bucket_pass);
|
||||
sycl::local_accessor<int> local_mem(max_shaders, cgh);
|
||||
oneapi_kernel_integrator_sort_bucket_pass(kg,
|
||||
global_size,
|
||||
local_size,
|
||||
cgh,
|
||||
*(int *)(args[0]),
|
||||
*(int *)(args[1]),
|
||||
*(int *)(args[2]),
|
||||
*(int **)(args[3]),
|
||||
*(int *)(args[4]),
|
||||
local_mem);
|
||||
break;
|
||||
}
|
||||
case DEVICE_KERNEL_INTEGRATOR_SORT_WRITE_PASS: {
|
||||
oneapi_call(
|
||||
kg, cgh, global_size, local_size, args, oneapi_kernel_integrator_sort_write_pass);
|
||||
sycl::local_accessor<int> local_mem(max_shaders, cgh);
|
||||
oneapi_kernel_integrator_sort_write_pass(kg,
|
||||
global_size,
|
||||
local_size,
|
||||
cgh,
|
||||
*(int *)(args[0]),
|
||||
*(int *)(args[1]),
|
||||
*(int *)(args[2]),
|
||||
*(int **)(args[3]),
|
||||
*(int *)(args[4]),
|
||||
local_mem);
|
||||
break;
|
||||
}
|
||||
case DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY: {
|
||||
|
|
|
@ -32,6 +32,8 @@ struct KernelContext {
|
|||
SyclQueue *queue;
|
||||
/* Pointer to USM device memory with all global/constant allocation on this device */
|
||||
void *kernel_globals;
|
||||
/* We needs this additional data for some kernels. */
|
||||
int scene_max_shaders;
|
||||
};
|
||||
|
||||
/* Use extern C linking so that the symbols can be easily load from the dynamic library at runtime.
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
|
||||
#else /* __KERNEL_GPU__ */
|
||||
|
||||
# ifndef __KERNEL_ONEAPI__
|
||||
# define atomic_fetch_and_add_uint32_shared atomic_fetch_and_add_uint32
|
||||
# endif
|
||||
|
||||
# if defined(__KERNEL_CUDA__) || defined(__KERNEL_HIP__)
|
||||
|
||||
# define atomic_add_and_fetch_float(p, x) (atomicAdd((float *)(p), (float)(x)) + (float)(x))
|
||||
|
@ -140,6 +144,11 @@ ccl_device_inline float atomic_compare_and_swap_float(volatile ccl_global float
|
|||
# define atomic_store(p, x) atomic_store_explicit(p, x, memory_order_relaxed)
|
||||
# define atomic_fetch(p) atomic_load_explicit(p, memory_order_relaxed)
|
||||
|
||||
# define atomic_store_local(p, x) \
|
||||
atomic_store_explicit((ccl_gpu_shared atomic_int *)p, x, memory_order_relaxed)
|
||||
# define atomic_load_local(p) \
|
||||
atomic_load_explicit((ccl_gpu_shared atomic_int *)p, memory_order_relaxed)
|
||||
|
||||
# define CCL_LOCAL_MEM_FENCE mem_flags::mem_threadgroup
|
||||
# define ccl_barrier(flags) threadgroup_barrier(flags)
|
||||
|
||||
|
@ -191,6 +200,16 @@ ccl_device_inline int atomic_fetch_and_add_uint32(ccl_global int *p, int x)
|
|||
return atomic.fetch_add(x);
|
||||
}
|
||||
|
||||
ccl_device_inline int atomic_fetch_and_add_uint32_shared(int *p, int x)
|
||||
{
|
||||
sycl::atomic_ref<int,
|
||||
sycl::memory_order::relaxed,
|
||||
sycl::memory_scope::device,
|
||||
sycl::access::address_space::local_space>
|
||||
atomic(*p);
|
||||
return atomic.fetch_add(x);
|
||||
}
|
||||
|
||||
ccl_device_inline unsigned int atomic_fetch_and_sub_uint32(ccl_global unsigned int *p,
|
||||
unsigned int x)
|
||||
{
|
||||
|
@ -253,6 +272,26 @@ ccl_device_inline int atomic_fetch_and_or_uint32(ccl_global int *p, int x)
|
|||
return atomic.fetch_or(x);
|
||||
}
|
||||
|
||||
ccl_device_inline void atomic_store_local(int *p, int x)
|
||||
{
|
||||
sycl::atomic_ref<int,
|
||||
sycl::memory_order::relaxed,
|
||||
sycl::memory_scope::device,
|
||||
sycl::access::address_space::local_space>
|
||||
atomic(*p);
|
||||
atomic.store(x);
|
||||
}
|
||||
|
||||
ccl_device_inline int atomic_load_local(int *p)
|
||||
{
|
||||
sycl::atomic_ref<int,
|
||||
sycl::memory_order::relaxed,
|
||||
sycl::memory_scope::device,
|
||||
sycl::access::address_space::local_space>
|
||||
atomic(*p);
|
||||
return atomic.load();
|
||||
}
|
||||
|
||||
# endif /* __KERNEL_ONEAPI__ */
|
||||
|
||||
#endif /* __KERNEL_GPU__ */
|
||||
|
|
|
@ -9,9 +9,9 @@ set(INC_SYS
|
|||
)
|
||||
|
||||
set(SRC
|
||||
intern/renderdoc_api.cc
|
||||
intern/renderdoc_api.cc
|
||||
|
||||
include/renderdoc_api.hh
|
||||
include/renderdoc_api.hh
|
||||
)
|
||||
|
||||
blender_add_lib(bf_intern_renderdoc_dynload "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
|
Binary file not shown.
|
@ -78,29 +78,30 @@ class PREFERENCES_OT_copy_prev(Operator):
|
|||
|
||||
@classmethod
|
||||
def previous_version(cls):
|
||||
# Find config folder from previous version.
|
||||
import os
|
||||
version = bpy.app.version
|
||||
version_new = ((version[0] * 100) + version[1])
|
||||
version_old = ((version[0] * 100) + version[1]) - 1
|
||||
# Find config folder from previous version.
|
||||
#
|
||||
# Always allow to load startup data from any release from current major release cycle, and the previous one.
|
||||
|
||||
# Ensure we only try to copy files from a point release.
|
||||
# The check below ensures the second numbers match.
|
||||
while (version_new % 100) // 10 == (version_old % 100) // 10:
|
||||
version_split = version_old // 100, version_old % 100
|
||||
if os.path.isdir(cls._old_version_path(version_split)):
|
||||
return version_split
|
||||
version_old = version_old - 1
|
||||
# NOTE: This value may need to be updated when the release cycle system is modified.
|
||||
# Here could be `6` in theory (Blender 3.6 LTS), just give it a bit of extra room, such that it does not have to
|
||||
# be updated if there ever exist a 3.7 release e.g.
|
||||
MAX_MINOR_VERSION_FOR_PREVIOUS_MAJOR_LOOKUP = 10
|
||||
|
||||
# Support loading 2.8x..2.9x startup (any older isn't so useful to load).
|
||||
# NOTE: remove this block for Blender 4.0 and later.
|
||||
if version_old == 299:
|
||||
version_old = 294
|
||||
while version_old >= 280:
|
||||
version_split = version_old // 100, version_old % 100
|
||||
if os.path.isdir(cls._old_version_path(version_split)):
|
||||
return version_split
|
||||
version_old = version_old - 1
|
||||
version_new = bpy.app.version[:2]
|
||||
version_old = [version_new[0], version_new[1] - 1]
|
||||
|
||||
while True:
|
||||
while version_old[1] >= 0:
|
||||
if os.path.isdir(cls._old_version_path(version_old)):
|
||||
return tuple(version_old)
|
||||
version_old[1] -= 1
|
||||
if version_new[0] == version_old[0]:
|
||||
# Retry with older major version.
|
||||
version_old[0] -= 1
|
||||
version_old[1] = MAX_MINOR_VERSION_FOR_PREVIOUS_MAJOR_LOOKUP
|
||||
else:
|
||||
break
|
||||
|
||||
return None
|
||||
|
||||
|
|
|
@ -613,6 +613,7 @@ class NODE_MT_category_GEO_VOLUME(Menu):
|
|||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeMeanFilterSDFVolume")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeOffsetSDFVolume")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSampleVolume")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSDFVolumeSphere")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeInputSignedDistance")
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
|
|
@ -147,6 +147,9 @@ class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
|
|||
col.prop(view_layer_eevee, "use_pass_bloom", text="Bloom")
|
||||
col.active = scene_eevee.use_bloom
|
||||
|
||||
col = layout.column()
|
||||
col.prop(view_layer_eevee, "use_pass_transparent")
|
||||
|
||||
|
||||
class ViewLayerAOVPanel(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Shader AOV"
|
||||
|
|
|
@ -61,8 +61,8 @@ set(SRC_DNA_INC
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_pointcache_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_pointcloud_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_rigidbody_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_enums.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_scene_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_screen_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sdna_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_sequence_types.h
|
||||
|
|
|
@ -17,7 +17,7 @@ extern "C" {
|
|||
*/
|
||||
|
||||
/* Blender major and minor version. */
|
||||
#define BLENDER_VERSION 306
|
||||
#define BLENDER_VERSION 400
|
||||
/* Blender patch version for bugfix releases. */
|
||||
#define BLENDER_VERSION_PATCH 0
|
||||
/** Blender release cycle stage: alpha/beta/rc/release. */
|
||||
|
@ -25,12 +25,12 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 10
|
||||
#define BLENDER_FILE_SUBVERSION 1
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
* was written with too new a version. */
|
||||
#define BLENDER_FILE_MIN_VERSION 305
|
||||
#define BLENDER_FILE_MIN_VERSION 306
|
||||
#define BLENDER_FILE_MIN_SUBVERSION 9
|
||||
|
||||
/** User readable version string. */
|
||||
|
|
|
@ -322,7 +322,7 @@ void BKE_collection_blend_read_expand(struct BlendExpander *expander,
|
|||
void BKE_collection_compat_blend_read_data(struct BlendDataReader *reader,
|
||||
struct SceneCollection *sc);
|
||||
void BKE_collection_compat_blend_read_lib(struct BlendLibReader *reader,
|
||||
struct Library *lib,
|
||||
struct ID *self_id,
|
||||
struct SceneCollection *sc);
|
||||
void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
|
||||
struct SceneCollection *sc);
|
||||
|
|
|
@ -314,6 +314,9 @@ void CustomData_free_layers(struct CustomData *data, eCustomDataType type, int t
|
|||
* Returns true if a layer with the specified type exists.
|
||||
*/
|
||||
bool CustomData_has_layer(const struct CustomData *data, eCustomDataType type);
|
||||
bool CustomData_has_layer_named(const struct CustomData *data,
|
||||
eCustomDataType type,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* Returns the number of layers with this type.
|
||||
|
|
|
@ -315,7 +315,7 @@ void IDP_BlendReadData_impl(struct BlendDataReader *reader,
|
|||
struct IDProperty **prop,
|
||||
const char *caller_func_id);
|
||||
#define IDP_BlendDataRead(reader, prop) IDP_BlendReadData_impl(reader, prop, __func__)
|
||||
void IDP_BlendReadLib(struct BlendLibReader *reader, struct Library *lib, struct IDProperty *prop);
|
||||
void IDP_BlendReadLib(struct BlendLibReader *reader, struct ID *self_id, struct IDProperty *prop);
|
||||
void IDP_BlendReadExpand(struct BlendExpander *expander, struct IDProperty *prop);
|
||||
|
||||
typedef enum eIDPropertyUIDataType {
|
||||
|
|
|
@ -275,7 +275,7 @@ void BKE_view_layer_blend_write(struct BlendWriter *writer,
|
|||
struct ViewLayer *view_layer);
|
||||
void BKE_view_layer_blend_read_data(struct BlendDataReader *reader, struct ViewLayer *view_layer);
|
||||
void BKE_view_layer_blend_read_lib(struct BlendLibReader *reader,
|
||||
struct Library *lib,
|
||||
struct ID *self_id,
|
||||
struct ViewLayer *view_layer);
|
||||
|
||||
/* iterators */
|
||||
|
|
|
@ -111,12 +111,12 @@ typedef struct LibraryIDLinkCallbackData {
|
|||
* 'Real' ID, the one that might be in bmain, only differs from self_id when the later is an
|
||||
* embedded one.
|
||||
*/
|
||||
struct ID *id_owner;
|
||||
struct ID *owner_id;
|
||||
/**
|
||||
* ID from which the current ID pointer is being processed. It may be an embedded ID like master
|
||||
* collection or root node tree.
|
||||
*/
|
||||
struct ID *id_self;
|
||||
struct ID *self_id;
|
||||
struct ID **id_pointer;
|
||||
int cb_flag;
|
||||
} LibraryIDLinkCallbackData;
|
||||
|
@ -259,17 +259,17 @@ void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, int c
|
|||
int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
|
||||
|
||||
/**
|
||||
* Say whether given \a id_owner may use (in any way) a data-block of \a id_type_used.
|
||||
* Say whether given \a owner_id may use (in any way) a data-block of \a id_type_used.
|
||||
*
|
||||
* This is a 'simplified' abstract version of #BKE_library_foreach_ID_link() above,
|
||||
* quite useful to reduce useless iterations in some cases.
|
||||
*/
|
||||
bool BKE_library_id_can_use_idtype(struct ID *id_owner, short id_type_used);
|
||||
bool BKE_library_id_can_use_idtype(struct ID *owner_id, short id_type_used);
|
||||
|
||||
/**
|
||||
* Given the id_owner return the type of id_types it can use as a filter_id.
|
||||
* 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 struct ID *id_owner, const bool include_ui);
|
||||
uint64_t BKE_library_id_can_use_filter_id(const struct ID *owner_id, const bool include_ui);
|
||||
|
||||
/**
|
||||
* Check whether given ID is used locally (i.e. by another non-linked ID).
|
||||
|
|
|
@ -120,7 +120,18 @@ enum {
|
|||
|
||||
typedef struct Main {
|
||||
struct Main *next, *prev;
|
||||
/** The file-path of this blend file, an empty string indicates an unsaved file. */
|
||||
/**
|
||||
* The file-path of this blend file, an empty string indicates an unsaved file.
|
||||
*
|
||||
* \note For the current loaded blend file this path should be absolute & normalized
|
||||
* to prevent redundant leading slashes or current-working-directory relative paths
|
||||
* from causing problems with absolute/relative patch conversion that relies on this being
|
||||
* an absolute path. See #BLI_path_canonicalize_native.
|
||||
*
|
||||
* This rule is not strictly enforced as in some cases loading a #Main is performed
|
||||
* to read data temporarily (preferences & startup) for e.g.
|
||||
* where the `filepath` is not persistent or used as a basis for other paths.
|
||||
*/
|
||||
char filepath[1024]; /* 1024 = FILE_MAX */
|
||||
short versionfile, subversionfile; /* see BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION */
|
||||
short minversionfile, minsubversionfile;
|
||||
|
|
|
@ -30,107 +30,51 @@ void BKE_mesh_legacy_convert_uvs_to_struct(
|
|||
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write);
|
||||
void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Move face sets to the legacy type from a generic type.
|
||||
*/
|
||||
void BKE_mesh_legacy_face_set_from_generic(
|
||||
blender::MutableSpan<CustomDataLayer> poly_layers_to_write);
|
||||
/**
|
||||
* Copy face sets to the generic data type from the legacy type.
|
||||
*/
|
||||
void BKE_mesh_legacy_face_set_to_generic(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Copy edge creases from a separate layer into edges.
|
||||
*/
|
||||
void BKE_mesh_legacy_edge_crease_from_layers(struct Mesh *mesh);
|
||||
/**
|
||||
* Copy edge creases from edges to a separate layer.
|
||||
*/
|
||||
void BKE_mesh_legacy_edge_crease_to_layers(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Copy bevel weights from separate layers into vertices and edges.
|
||||
*/
|
||||
void BKE_mesh_legacy_bevel_weight_from_layers(struct Mesh *mesh);
|
||||
/**
|
||||
* Copy bevel weights from vertices and edges to separate layers.
|
||||
*/
|
||||
void BKE_mesh_legacy_bevel_weight_to_layers(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Convert the hidden element attributes to the old flag format for writing.
|
||||
*/
|
||||
void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys);
|
||||
/**
|
||||
* Convert the old hide flags (#ME_HIDE) to the hidden element attribute for reading.
|
||||
* Only add the attributes when there are any elements in each domain hidden.
|
||||
*/
|
||||
void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Convert the selected element attributes to the old flag format for writing.
|
||||
*/
|
||||
void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys);
|
||||
/**
|
||||
* Convert the old selection flags (#SELECT/#ME_FACE_SEL) to the selected element attribute for
|
||||
* reading. Only add the attributes when there are any elements in each domain selected.
|
||||
*/
|
||||
void BKE_mesh_legacy_convert_flags_to_selection_layers(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Move material indices from a generic attribute to #MPoly.
|
||||
*/
|
||||
void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys);
|
||||
/**
|
||||
* Move material indices from the #MPoly struct to a generic attributes.
|
||||
* Only add the attribute when the indices are not all zero.
|
||||
*/
|
||||
void BKE_mesh_legacy_convert_mpoly_to_material_indices(struct Mesh *mesh);
|
||||
|
||||
/** Convert from runtime loose edge cache to legacy edge flag. */
|
||||
void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh);
|
||||
|
||||
void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh);
|
||||
void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh);
|
||||
|
||||
void BKE_mesh_legacy_sharp_faces_to_flags(struct Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys);
|
||||
void BKE_mesh_legacy_sharp_faces_from_flags(struct Mesh *mesh);
|
||||
|
||||
void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh);
|
||||
void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh);
|
||||
|
||||
void BKE_mesh_legacy_uv_seam_to_flags(struct Mesh *mesh);
|
||||
void BKE_mesh_legacy_uv_seam_from_flags(struct Mesh *mesh);
|
||||
|
||||
struct MVert *BKE_mesh_legacy_convert_positions_to_verts(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &vert_layers_to_write);
|
||||
|
||||
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh);
|
||||
|
||||
MEdge *BKE_mesh_legacy_convert_edges_to_medge(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &edge_layers_to_write);
|
||||
|
||||
void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh);
|
||||
|
||||
struct MLoop *BKE_mesh_legacy_convert_corners_to_loops(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write);
|
||||
|
||||
blender::MutableSpan<MPoly> BKE_mesh_legacy_convert_offsets_to_polys(
|
||||
const Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &poly_layers_to_write);
|
||||
|
||||
void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh);
|
||||
|
||||
void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh);
|
||||
|
|
|
@ -1304,6 +1304,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define GEO_NODE_SIMULATION_INPUT 2100
|
||||
#define GEO_NODE_SIMULATION_OUTPUT 2101
|
||||
#define GEO_NODE_INPUT_SIGNED_DISTANCE 2102
|
||||
#define GEO_NODE_SAMPLE_VOLUME 2103
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree);
|
|||
|
||||
void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node);
|
||||
|
||||
|
||||
void ntreeUpdateAllNew(Main *main);
|
||||
|
||||
void ntreeNodeFlagSet(const bNodeTree *ntree, int flag, bool enable);
|
||||
|
|
|
@ -154,6 +154,8 @@ void BKE_sound_set_scene_sound_volume(void *handle, float volume, char animated)
|
|||
|
||||
void BKE_sound_set_scene_sound_pitch(void *handle, float pitch, char animated);
|
||||
|
||||
void BKE_sound_set_scene_sound_pitch_at_frame(void *handle, int frame, float pitch, char animated);
|
||||
|
||||
void BKE_sound_set_scene_sound_pitch_constant_range(void *handle,
|
||||
int frame_start,
|
||||
int frame_end,
|
||||
|
|
|
@ -40,7 +40,7 @@ bool BKE_viewer_path_equal(const ViewerPath *a, const ViewerPath *b);
|
|||
void BKE_viewer_path_blend_write(struct BlendWriter *writer, const ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_blend_read_data(struct BlendDataReader *reader, ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_blend_read_lib(struct BlendLibReader *reader,
|
||||
struct Library *lib,
|
||||
struct ID *self_id,
|
||||
ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_foreach_id(struct LibraryForeachIDData *data, ViewerPath *viewer_path);
|
||||
void BKE_viewer_path_id_remap(ViewerPath *viewer_path, const struct IDRemapper *mappings);
|
||||
|
|
|
@ -443,6 +443,7 @@ set(SRC
|
|||
BKE_multires.h
|
||||
BKE_nla.h
|
||||
BKE_node.h
|
||||
BKE_node.hh
|
||||
BKE_node_runtime.hh
|
||||
BKE_node_tree_update.h
|
||||
BKE_node_tree_zones.hh
|
||||
|
|
|
@ -222,7 +222,7 @@ static void action_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void blend_read_lib_constraint_channels(BlendLibReader *reader, ID *id, ListBase *chanbase)
|
||||
{
|
||||
LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
|
||||
BLO_read_id_address(reader, id->lib, &chan->ipo);
|
||||
BLO_read_id_address(reader, id, &chan->ipo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,16 +232,16 @@ static void action_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
|
||||
/* XXX deprecated - old animation system <<< */
|
||||
LISTBASE_FOREACH (bActionChannel *, chan, &act->chanbase) {
|
||||
BLO_read_id_address(reader, act->id.lib, &chan->ipo);
|
||||
BLO_read_id_address(reader, id, &chan->ipo);
|
||||
blend_read_lib_constraint_channels(reader, &act->id, &chan->constraintChannels);
|
||||
}
|
||||
/* >>> XXX deprecated - old animation system */
|
||||
|
||||
BKE_fcurve_blend_read_lib(reader, &act->id, &act->curves);
|
||||
BKE_fcurve_blend_read_lib(reader, id, &act->curves);
|
||||
|
||||
LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
|
||||
if (marker->camera) {
|
||||
BLO_read_id_address(reader, act->id.lib, &marker->camera);
|
||||
BLO_read_id_address(reader, id, &marker->camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1952,9 +1952,9 @@ void BKE_pose_blend_read_lib(BlendLibReader *reader, Object *ob, bPose *pose)
|
|||
|
||||
pchan->bone = BKE_armature_find_bone_name(arm, pchan->name);
|
||||
|
||||
IDP_BlendReadLib(reader, ob->id.lib, pchan->prop);
|
||||
IDP_BlendReadLib(reader, &ob->id, pchan->prop);
|
||||
|
||||
BLO_read_id_address(reader, ob->id.lib, &pchan->custom);
|
||||
BLO_read_id_address(reader, &ob->id, &pchan->custom);
|
||||
if (UNLIKELY(pchan->bone == NULL)) {
|
||||
rebuild = true;
|
||||
}
|
||||
|
|
|
@ -1479,8 +1479,8 @@ void BKE_animdata_blend_read_lib(BlendLibReader *reader, ID *id, AnimData *adt)
|
|||
}
|
||||
|
||||
/* link action data */
|
||||
BLO_read_id_address(reader, id->lib, &adt->action);
|
||||
BLO_read_id_address(reader, id->lib, &adt->tmpact);
|
||||
BLO_read_id_address(reader, id, &adt->action);
|
||||
BLO_read_id_address(reader, id, &adt->tmpact);
|
||||
|
||||
/* link drivers */
|
||||
BKE_fcurve_blend_read_lib(reader, id, &adt->drivers);
|
||||
|
|
|
@ -329,7 +329,7 @@ void BKE_keyingsets_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *lis
|
|||
{
|
||||
LISTBASE_FOREACH (KeyingSet *, ks, list) {
|
||||
LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
|
||||
BLO_read_id_address(reader, id->lib, &ksp->id);
|
||||
BLO_read_id_address(reader, id, &ksp->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -897,8 +897,7 @@ void BKE_appdir_program_path_init(const char *argv0)
|
|||
* Otherwise other methods of detecting the binary that override this argument
|
||||
* which must point to the Python module for data-files to be detected. */
|
||||
STRNCPY(g_app.program_filepath, argv0);
|
||||
BLI_path_abs_from_cwd(g_app.program_filepath, sizeof(g_app.program_filepath));
|
||||
BLI_path_normalize_native(g_app.program_filepath);
|
||||
BLI_path_canonicalize_native(g_app.program_filepath, sizeof(g_app.program_filepath));
|
||||
|
||||
if (g_app.program_dirname[0] == '\0') {
|
||||
/* First time initializing, the file binary path isn't valid from a Python module.
|
||||
|
|
|
@ -261,12 +261,12 @@ static void armature_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
BKE_armature_bone_hash_make(arm);
|
||||
}
|
||||
|
||||
static void lib_link_bones(BlendLibReader *reader, Library *lib, Bone *bone)
|
||||
static void lib_link_bones(BlendLibReader *reader, ID *self_id, Bone *bone)
|
||||
{
|
||||
IDP_BlendReadLib(reader, lib, bone->prop);
|
||||
IDP_BlendReadLib(reader, self_id, bone->prop);
|
||||
|
||||
LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
|
||||
lib_link_bones(reader, lib, curbone);
|
||||
lib_link_bones(reader, self_id, curbone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,7 +274,7 @@ static void armature_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
bArmature *arm = (bArmature *)id;
|
||||
LISTBASE_FOREACH (Bone *, curbone, &arm->bonebase) {
|
||||
lib_link_bones(reader, id->lib, curbone);
|
||||
lib_link_bones(reader, id, curbone);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -446,7 +446,7 @@ bool BuiltinCustomDataLayerProvider::try_create(void *owner,
|
|||
|
||||
const int element_num = custom_data_access_.get_element_num(owner);
|
||||
if (stored_as_named_attribute_) {
|
||||
if (CustomData_get_layer_named(custom_data, data_type_, name_.c_str())) {
|
||||
if (CustomData_has_layer_named(custom_data, data_type_, name_.c_str())) {
|
||||
/* Exists already. */
|
||||
return false;
|
||||
}
|
||||
|
@ -469,7 +469,7 @@ bool BuiltinCustomDataLayerProvider::exists(const void *owner) const
|
|||
return false;
|
||||
}
|
||||
if (stored_as_named_attribute_) {
|
||||
return CustomData_get_layer_named(custom_data, stored_type_, name_.c_str()) != nullptr;
|
||||
return CustomData_has_layer_named(custom_data, stored_type_, name_.c_str());
|
||||
}
|
||||
return CustomData_get_layer(custom_data, stored_type_) != nullptr;
|
||||
}
|
||||
|
|
|
@ -952,7 +952,7 @@ static int foreach_libblock_link_append_callback(LibraryIDLinkCallbackData *cb_d
|
|||
* meshes for shape keys e.g.), or this is an unsupported case (two shape-keys depending on
|
||||
* each-other need to be also 'linked' in by their respective meshes, independent shape-keys
|
||||
* are not allowed). ref #96048. */
|
||||
if (id != cb_data->id_self && BKE_idtype_idcode_is_linkable(GS(cb_data->id_self->name))) {
|
||||
if (id != cb_data->self_id && BKE_idtype_idcode_is_linkable(GS(cb_data->self_id->name))) {
|
||||
BKE_library_foreach_ID_link(
|
||||
cb_data->bmain, id, foreach_libblock_link_append_callback, data, IDWALK_NOP);
|
||||
}
|
||||
|
@ -972,7 +972,7 @@ static int foreach_libblock_link_append_callback(LibraryIDLinkCallbackData *cb_d
|
|||
const bool do_recursive = (data->lapp_context->params->flag & BLO_LIBLINK_APPEND_RECURSIVE) !=
|
||||
0 ||
|
||||
do_link;
|
||||
if (!do_recursive && cb_data->id_owner->lib != id->lib) {
|
||||
if (!do_recursive && cb_data->owner_id->lib != id->lib) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
|
|
|
@ -513,7 +513,14 @@ static bool relative_convert_foreach_path_cb(BPathForeachPathData *bpath_data,
|
|||
data->count_changed++;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made relative", path_src);
|
||||
const char *type_name = BKE_idtype_get_info_from_id(bpath_data->owner_id)->name;
|
||||
const char *id_name = bpath_data->owner_id->name + 2;
|
||||
BKE_reportf(data->reports,
|
||||
RPT_WARNING,
|
||||
"Path '%s' cannot be made relative for %s '%s'",
|
||||
path_src,
|
||||
type_name,
|
||||
id_name);
|
||||
data->count_failed++;
|
||||
}
|
||||
return true;
|
||||
|
@ -537,7 +544,14 @@ static bool absolute_convert_foreach_path_cb(BPathForeachPathData *bpath_data,
|
|||
data->count_changed++;
|
||||
}
|
||||
else {
|
||||
BKE_reportf(data->reports, RPT_WARNING, "Path '%s' cannot be made absolute", path_src);
|
||||
const char *type_name = BKE_idtype_get_info_from_id(bpath_data->owner_id)->name;
|
||||
const char *id_name = bpath_data->owner_id->name + 2;
|
||||
BKE_reportf(data->reports,
|
||||
RPT_WARNING,
|
||||
"Path '%s' cannot be made absolute for %s '%s'",
|
||||
path_src,
|
||||
type_name,
|
||||
id_name);
|
||||
data->count_failed++;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -361,16 +361,16 @@ static void brush_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
Brush *brush = (Brush *)id;
|
||||
|
||||
/* brush->(mask_)mtex.obj is ignored on purpose? */
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->mtex.tex);
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->mask_mtex.tex);
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->clone.image);
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->toggle_brush);
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->paint_curve);
|
||||
BLO_read_id_address(reader, id, &brush->mtex.tex);
|
||||
BLO_read_id_address(reader, id, &brush->mask_mtex.tex);
|
||||
BLO_read_id_address(reader, id, &brush->clone.image);
|
||||
BLO_read_id_address(reader, id, &brush->toggle_brush);
|
||||
BLO_read_id_address(reader, id, &brush->paint_curve);
|
||||
|
||||
/* link default grease pencil palette */
|
||||
if (brush->gpencil_settings != nullptr) {
|
||||
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->gpencil_settings->material);
|
||||
BLO_read_id_address(reader, id, &brush->gpencil_settings->material);
|
||||
|
||||
if (!brush->gpencil_settings->material) {
|
||||
brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
|
||||
|
@ -379,7 +379,7 @@ static void brush_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
else {
|
||||
brush->gpencil_settings->material = nullptr;
|
||||
}
|
||||
BLO_read_id_address(reader, brush->id.lib, &brush->gpencil_settings->material_alt);
|
||||
BLO_read_id_address(reader, id, &brush->gpencil_settings->material_alt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,10 +399,12 @@ static void brush_blend_read_expand(BlendExpander *expander, ID *id)
|
|||
static int brush_undo_preserve_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
BlendLibReader *reader = (BlendLibReader *)cb_data->user_data;
|
||||
ID *self_id = cb_data->self_id;
|
||||
ID *id_old = *cb_data->id_pointer;
|
||||
/* Old data has not been remapped to new values of the pointers, if we want to keep the old
|
||||
* pointer here we need its new address. */
|
||||
ID *id_old_new = id_old != nullptr ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) :
|
||||
ID *id_old_new = id_old != nullptr ? BLO_read_get_new_id_address(
|
||||
reader, self_id, ID_IS_LINKED(self_id), id_old) :
|
||||
nullptr;
|
||||
BLI_assert(id_old_new == nullptr || ELEM(id_old, id_old_new, id_old_new->orig_id));
|
||||
if (cb_data->cb_flag & IDWALK_CB_USER) {
|
||||
|
|
|
@ -142,14 +142,14 @@ static void camera_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void camera_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
Camera *ca = (Camera *)id;
|
||||
BLO_read_id_address(reader, ca->id.lib, &ca->ipo); /* deprecated, for versioning */
|
||||
BLO_read_id_address(reader, id, &ca->ipo); /* deprecated, for versioning */
|
||||
|
||||
BLO_read_id_address(reader, ca->id.lib, &ca->dof_ob); /* deprecated, for versioning */
|
||||
BLO_read_id_address(reader, ca->id.lib, &ca->dof.focus_object);
|
||||
BLO_read_id_address(reader, id, &ca->dof_ob); /* deprecated, for versioning */
|
||||
BLO_read_id_address(reader, id, &ca->dof.focus_object);
|
||||
|
||||
LISTBASE_FOREACH (CameraBGImage *, bgpic, &ca->bg_images) {
|
||||
BLO_read_id_address(reader, ca->id.lib, &bgpic->ima);
|
||||
BLO_read_id_address(reader, ca->id.lib, &bgpic->clip);
|
||||
BLO_read_id_address(reader, id, &bgpic->ima);
|
||||
BLO_read_id_address(reader, id, &bgpic->clip);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -325,11 +325,11 @@ static void collection_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
BKE_collection_blend_read_data(reader, collection, NULL);
|
||||
}
|
||||
|
||||
static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection)
|
||||
static void lib_link_collection_data(BlendLibReader *reader, ID *self_id, Collection *collection)
|
||||
{
|
||||
BLI_assert(collection->runtime.gobject_hash == NULL);
|
||||
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) {
|
||||
BLO_read_id_address(reader, lib, &cob->ob);
|
||||
BLO_read_id_address(reader, self_id, &cob->ob);
|
||||
|
||||
if (cob->ob == NULL) {
|
||||
BLI_freelinkN(&collection->gobject, cob);
|
||||
|
@ -337,22 +337,20 @@ static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Colle
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||
BLO_read_id_address(reader, lib, &child->collection);
|
||||
BLO_read_id_address(reader, self_id, &child->collection);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_COLLECTION_COMPAT_28
|
||||
void BKE_collection_compat_blend_read_lib(BlendLibReader *reader,
|
||||
Library *lib,
|
||||
SceneCollection *sc)
|
||||
void BKE_collection_compat_blend_read_lib(BlendLibReader *reader, ID *self_id, SceneCollection *sc)
|
||||
{
|
||||
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
|
||||
BLO_read_id_address(reader, lib, &link->data);
|
||||
BLO_read_id_address(reader, self_id, &link->data);
|
||||
BLI_assert(link->data);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
|
||||
BKE_collection_compat_blend_read_lib(reader, lib, nsc);
|
||||
BKE_collection_compat_blend_read_lib(reader, self_id, nsc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -361,15 +359,15 @@ void BKE_collection_blend_read_lib(BlendLibReader *reader, Collection *collectio
|
|||
{
|
||||
#ifdef USE_COLLECTION_COMPAT_28
|
||||
if (collection->collection) {
|
||||
BKE_collection_compat_blend_read_lib(reader, collection->id.lib, collection->collection);
|
||||
BKE_collection_compat_blend_read_lib(reader, &collection->id, collection->collection);
|
||||
}
|
||||
|
||||
if (collection->view_layer) {
|
||||
BKE_view_layer_blend_read_lib(reader, collection->id.lib, collection->view_layer);
|
||||
BKE_view_layer_blend_read_lib(reader, &collection->id, collection->view_layer);
|
||||
}
|
||||
#endif
|
||||
|
||||
lib_link_collection_data(reader, collection->id.lib, collection);
|
||||
lib_link_collection_data(reader, &collection->id, collection);
|
||||
}
|
||||
|
||||
static void collection_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
|
|
|
@ -6556,7 +6556,7 @@ static void lib_link_constraint_cb(bConstraint *UNUSED(con),
|
|||
void *userdata)
|
||||
{
|
||||
tConstraintLinkData *cld = (tConstraintLinkData *)userdata;
|
||||
BLO_read_id_address(cld->reader, cld->id->lib, idpoin);
|
||||
BLO_read_id_address(cld->reader, cld->id, idpoin);
|
||||
}
|
||||
|
||||
void BKE_constraint_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *conlist)
|
||||
|
@ -6571,7 +6571,7 @@ void BKE_constraint_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *con
|
|||
con->type = CONSTRAINT_TYPE_NULL;
|
||||
}
|
||||
/* own ipo, all constraints have it */
|
||||
BLO_read_id_address(reader, id->lib, &con->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, id, &con->ipo); /* XXX deprecated - old animation system */
|
||||
|
||||
/* If linking from a library, clear 'local' library override flag. */
|
||||
if (ID_IS_LINKED(id)) {
|
||||
|
|
|
@ -270,19 +270,19 @@ static void curve_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
Curve *cu = (Curve *)id;
|
||||
for (int a = 0; a < cu->totcol; a++) {
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->mat[a]);
|
||||
BLO_read_id_address(reader, id, &cu->mat[a]);
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->bevobj);
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->taperobj);
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->textoncurve);
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->vfont);
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->vfontb);
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->vfonti);
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->vfontbi);
|
||||
BLO_read_id_address(reader, id, &cu->bevobj);
|
||||
BLO_read_id_address(reader, id, &cu->taperobj);
|
||||
BLO_read_id_address(reader, id, &cu->textoncurve);
|
||||
BLO_read_id_address(reader, id, &cu->vfont);
|
||||
BLO_read_id_address(reader, id, &cu->vfontb);
|
||||
BLO_read_id_address(reader, id, &cu->vfonti);
|
||||
BLO_read_id_address(reader, id, &cu->vfontbi);
|
||||
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, cu->id.lib, &cu->key);
|
||||
BLO_read_id_address(reader, id, &cu->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, id, &cu->key);
|
||||
}
|
||||
|
||||
static void curve_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -137,9 +137,9 @@ static void curves_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
Curves *curves = (Curves *)id;
|
||||
for (int a = 0; a < curves->totcol; a++) {
|
||||
BLO_read_id_address(reader, curves->id.lib, &curves->mat[a]);
|
||||
BLO_read_id_address(reader, id, &curves->mat[a]);
|
||||
}
|
||||
BLO_read_id_address(reader, curves->id.lib, &curves->surface);
|
||||
BLO_read_id_address(reader, id, &curves->surface);
|
||||
}
|
||||
|
||||
static void curves_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -3176,6 +3176,13 @@ void CustomData_free_layers(CustomData *data, const eCustomDataType type, const
|
|||
}
|
||||
}
|
||||
|
||||
bool CustomData_has_layer_named(const CustomData *data,
|
||||
const eCustomDataType type,
|
||||
const char *name)
|
||||
{
|
||||
return CustomData_get_named_layer_index(data, type, name) != -1;
|
||||
}
|
||||
|
||||
bool CustomData_has_layer(const CustomData *data, const eCustomDataType type)
|
||||
{
|
||||
return (CustomData_get_layer_index(data, type) != -1);
|
||||
|
@ -5181,9 +5188,6 @@ void CustomData_blend_write(BlendWriter *writer,
|
|||
case CD_PAINT_MASK:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
case CD_SCULPT_FACE_SETS:
|
||||
BLO_write_raw(writer, sizeof(float) * count, static_cast<const float *>(layer.data));
|
||||
break;
|
||||
case CD_GRID_PAINT_MASK:
|
||||
write_grid_paint_mask(writer, count, static_cast<const GridPaintMask *>(layer.data));
|
||||
break;
|
||||
|
|
|
@ -950,7 +950,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
|
|||
return true;
|
||||
}
|
||||
if (r_map && cddata_type == CD_FAKE_SEAM) {
|
||||
if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, ".uv_seam")) {
|
||||
if (!CustomData_has_layer_named(&me_dst->edata, CD_PROP_BOOL, ".uv_seam")) {
|
||||
CustomData_add_layer_named(
|
||||
&me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->totedge, ".uv_seam");
|
||||
}
|
||||
|
@ -968,7 +968,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
|
|||
return true;
|
||||
}
|
||||
if (r_map && cddata_type == CD_FAKE_SHARP) {
|
||||
if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")) {
|
||||
if (!CustomData_has_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")) {
|
||||
CustomData_add_layer_named(
|
||||
&me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->totedge, "sharp_edge");
|
||||
}
|
||||
|
@ -1056,7 +1056,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
|
|||
return true;
|
||||
}
|
||||
if (r_map && cddata_type == CD_FAKE_SHARP) {
|
||||
if (!CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face")) {
|
||||
if (!CustomData_has_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face")) {
|
||||
CustomData_add_layer_named(
|
||||
&me_dst->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->totpoly, "sharp_face");
|
||||
}
|
||||
|
|
|
@ -2540,7 +2540,7 @@ void BKE_fmodifiers_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *fmo
|
|||
switch (fcm->type) {
|
||||
case FMODIFIER_TYPE_PYTHON: {
|
||||
FMod_Python *data = (FMod_Python *)fcm->data;
|
||||
BLO_read_id_address(reader, id->lib, &data->script);
|
||||
BLO_read_id_address(reader, id, &data->script);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2670,7 +2670,7 @@ void BKE_fcurve_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *fcurves
|
|||
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
|
||||
/* only relink if still used */
|
||||
if (tarIndex < dvar->num_targets) {
|
||||
BLO_read_id_address(reader, id->lib, &dtar->id);
|
||||
BLO_read_id_address(reader, id, &dtar->id);
|
||||
}
|
||||
else {
|
||||
dtar->id = NULL;
|
||||
|
|
|
@ -275,12 +275,12 @@ static void greasepencil_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
/* Layers */
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* Layer -> Parent References */
|
||||
BLO_read_id_address(reader, gpd->id.lib, &gpl->parent);
|
||||
BLO_read_id_address(reader, id, &gpl->parent);
|
||||
}
|
||||
|
||||
/* materials */
|
||||
for (int a = 0; a < gpd->totcol; a++) {
|
||||
BLO_read_id_address(reader, gpd->id.lib, &gpd->mat[a]);
|
||||
BLO_read_id_address(reader, id, &gpd->mat[a]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1495,7 +1495,7 @@ void IDP_BlendReadData_impl(BlendDataReader *reader, IDProperty **prop, const ch
|
|||
}
|
||||
}
|
||||
|
||||
void IDP_BlendReadLib(BlendLibReader *reader, Library *lib, IDProperty *prop)
|
||||
void IDP_BlendReadLib(BlendLibReader *reader, ID *self_id, IDProperty *prop)
|
||||
{
|
||||
if (!prop) {
|
||||
return;
|
||||
|
@ -1504,7 +1504,8 @@ void IDP_BlendReadLib(BlendLibReader *reader, Library *lib, IDProperty *prop)
|
|||
switch (prop->type) {
|
||||
case IDP_ID: /* PointerProperty */
|
||||
{
|
||||
void *newaddr = BLO_read_get_new_id_address(reader, lib, IDP_Id(prop));
|
||||
void *newaddr = BLO_read_get_new_id_address(
|
||||
reader, self_id, ID_IS_LINKED(self_id), IDP_Id(prop));
|
||||
if (IDP_Id(prop) && !newaddr && G.debug) {
|
||||
printf("Error while loading \"%s\". Data not found in file!\n", prop->name);
|
||||
}
|
||||
|
@ -1515,14 +1516,14 @@ void IDP_BlendReadLib(BlendLibReader *reader, Library *lib, IDProperty *prop)
|
|||
{
|
||||
IDProperty *idp_array = IDP_IDPArray(prop);
|
||||
for (int i = 0; i < prop->len; i++) {
|
||||
IDP_BlendReadLib(reader, lib, &(idp_array[i]));
|
||||
IDP_BlendReadLib(reader, self_id, &(idp_array[i]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDP_GROUP: /* PointerProperty */
|
||||
{
|
||||
LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) {
|
||||
IDP_BlendReadLib(reader, lib, loop);
|
||||
IDP_BlendReadLib(reader, self_id, loop);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ static void ipo_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
|
||||
LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
|
||||
if (icu->driver) {
|
||||
BLO_read_id_address(reader, ipo->id.lib, &icu->driver->ob);
|
||||
BLO_read_id_address(reader, id, &icu->driver->ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,8 +186,8 @@ static void shapekey_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
Key *key = (Key *)id;
|
||||
BLI_assert((key->id.tag & LIB_TAG_EXTERN) == 0);
|
||||
|
||||
BLO_read_id_address(reader, key->id.lib, &key->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, key->id.lib, &key->from);
|
||||
BLO_read_id_address(reader, id, &key->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, id, &key->from);
|
||||
}
|
||||
|
||||
static void shapekey_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -161,8 +161,8 @@ static void lattice_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void lattice_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
Lattice *lt = (Lattice *)id;
|
||||
BLO_read_id_address(reader, lt->id.lib, <->ipo); // XXX deprecated - old animation system
|
||||
BLO_read_id_address(reader, lt->id.lib, <->key);
|
||||
BLO_read_id_address(reader, id, <->ipo); // XXX deprecated - old animation system
|
||||
BLO_read_id_address(reader, id, <->key);
|
||||
}
|
||||
|
||||
static void lattice_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -2438,35 +2438,35 @@ void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_lay
|
|||
}
|
||||
|
||||
static void lib_link_layer_collection(BlendLibReader *reader,
|
||||
Library *lib,
|
||||
ID *self_id,
|
||||
LayerCollection *layer_collection,
|
||||
bool master)
|
||||
const bool master)
|
||||
{
|
||||
/* Master collection is not a real data-block. */
|
||||
if (!master) {
|
||||
BLO_read_id_address(reader, lib, &layer_collection->collection);
|
||||
BLO_read_id_address(reader, self_id, &layer_collection->collection);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (
|
||||
LayerCollection *, layer_collection_nested, &layer_collection->layer_collections) {
|
||||
lib_link_layer_collection(reader, lib, layer_collection_nested, false);
|
||||
lib_link_layer_collection(reader, self_id, layer_collection_nested, false);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_view_layer_blend_read_lib(BlendLibReader *reader, Library *lib, ViewLayer *view_layer)
|
||||
void BKE_view_layer_blend_read_lib(BlendLibReader *reader, ID *self_id, ViewLayer *view_layer)
|
||||
{
|
||||
LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
|
||||
BLO_read_id_address(reader, lib, &fmc->script);
|
||||
BLO_read_id_address(reader, self_id, &fmc->script);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) {
|
||||
BLO_read_id_address(reader, lib, &fls->linestyle);
|
||||
BLO_read_id_address(reader, lib, &fls->group);
|
||||
BLO_read_id_address(reader, self_id, &fls->linestyle);
|
||||
BLO_read_id_address(reader, self_id, &fls->group);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
|
||||
/* we only bump the use count for the collection objects */
|
||||
BLO_read_id_address(reader, lib, &base->object);
|
||||
BLO_read_id_address(reader, self_id, &base->object);
|
||||
|
||||
if (base->object == nullptr) {
|
||||
/* Free in case linked object got lost. */
|
||||
|
@ -2478,12 +2478,12 @@ void BKE_view_layer_blend_read_lib(BlendLibReader *reader, Library *lib, ViewLay
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
|
||||
lib_link_layer_collection(reader, lib, layer_collection, true);
|
||||
lib_link_layer_collection(reader, self_id, layer_collection, true);
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, lib, &view_layer->mat_override);
|
||||
BLO_read_id_address(reader, self_id, &view_layer->mat_override);
|
||||
|
||||
IDP_BlendReadLib(reader, lib, view_layer->id_properties);
|
||||
IDP_BlendReadLib(reader, self_id, view_layer->id_properties);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -173,7 +173,7 @@ static int lib_id_clear_library_data_users_update_cb(LibraryIDLinkCallbackData *
|
|||
/* Even though the ID itself remain the same after being made local, from depsgraph point of
|
||||
* view this is a different ID. Hence we need to tag all of its users for COW update. */
|
||||
DEG_id_tag_update_ex(
|
||||
cb_data->bmain, cb_data->id_owner, ID_RECALC_TAG_FOR_UNDO | ID_RECALC_COPY_ON_WRITE);
|
||||
cb_data->bmain, cb_data->owner_id, ID_RECALC_TAG_FOR_UNDO | ID_RECALC_COPY_ON_WRITE);
|
||||
return IDWALK_RET_STOP_ITER;
|
||||
}
|
||||
return IDWALK_RET_NOP;
|
||||
|
@ -396,7 +396,7 @@ void BKE_id_newptr_and_tag_clear(ID *id)
|
|||
static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
Main *bmain = cb_data->bmain;
|
||||
ID *id_self = cb_data->id_self;
|
||||
ID *self_id = cb_data->self_id;
|
||||
ID **id_pointer = cb_data->id_pointer;
|
||||
int const cb_flag = cb_data->cb_flag;
|
||||
const int flags = POINTER_AS_INT(cb_data->user_data);
|
||||
|
@ -412,7 +412,7 @@ static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
|
|||
* local directly), its embedded IDs should also have already been duplicated, and hence be
|
||||
* fully local here already. */
|
||||
if (*id_pointer != NULL && ID_IS_LINKED(*id_pointer)) {
|
||||
BLI_assert(*id_pointer != id_self);
|
||||
BLI_assert(*id_pointer != self_id);
|
||||
|
||||
BKE_lib_id_clear_library_data(bmain, *id_pointer, flags);
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ static int lib_id_expand_local_cb(LibraryIDLinkCallbackData *cb_data)
|
|||
* (through drivers)...
|
||||
* Just skip it, shape key can only be either indirectly linked, or fully local, period.
|
||||
* And let's curse one more time that stupid useless shape-key ID type! */
|
||||
if (*id_pointer && *id_pointer != id_self &&
|
||||
if (*id_pointer && *id_pointer != self_id &&
|
||||
BKE_idtype_idcode_is_linkable(GS((*id_pointer)->name)))
|
||||
{
|
||||
id_lib_extern(*id_pointer);
|
||||
|
@ -583,14 +583,14 @@ static int id_copy_libmanagement_cb(LibraryIDLinkCallbackData *cb_data)
|
|||
|
||||
/* Remap self-references to new copied ID. */
|
||||
if (id == data->id_src) {
|
||||
/* We cannot use id_self here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */
|
||||
/* We cannot use self_id here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */
|
||||
id = *id_pointer = data->id_dst;
|
||||
}
|
||||
|
||||
/* Increase used IDs refcount if needed and required. */
|
||||
if ((data->flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0 && (cb_flag & IDWALK_CB_USER)) {
|
||||
if ((data->flag & LIB_ID_CREATE_NO_MAIN) != 0) {
|
||||
BLI_assert(cb_data->id_self->tag & LIB_TAG_NO_MAIN);
|
||||
BLI_assert(cb_data->self_id->tag & LIB_TAG_NO_MAIN);
|
||||
id_us_plus_no_lib(id);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -373,7 +373,7 @@ bool BKE_lib_override_library_property_is_animated(const ID *id,
|
|||
|
||||
static int foreachid_is_hierarchy_leaf_fn(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
ID *id_owner = cb_data->id_owner;
|
||||
ID *id_owner = cb_data->owner_id;
|
||||
ID *id = *cb_data->id_pointer;
|
||||
bool *is_leaf = static_cast<bool *>(cb_data->user_data);
|
||||
|
||||
|
@ -3194,7 +3194,7 @@ static int lib_override_sort_libraries_func(LibraryIDLinkCallbackData *cb_data)
|
|||
if (cb_data->cb_flag & IDWALK_CB_LOOPBACK) {
|
||||
return IDWALK_RET_NOP;
|
||||
}
|
||||
ID *id_owner = cb_data->id_owner;
|
||||
ID *id_owner = cb_data->owner_id;
|
||||
ID *id = *cb_data->id_pointer;
|
||||
if (id != nullptr && ID_IS_LINKED(id) && id->lib != id_owner->lib) {
|
||||
const int owner_library_indirect_level = ID_IS_LINKED(id_owner) ? id_owner->lib->temp_index :
|
||||
|
|
|
@ -87,8 +87,8 @@ void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int
|
|||
const int callback_return = data->callback(
|
||||
&(struct LibraryIDLinkCallbackData){.user_data = data->user_data,
|
||||
.bmain = data->bmain,
|
||||
.id_owner = data->owner_id,
|
||||
.id_self = data->self_id,
|
||||
.owner_id = data->owner_id,
|
||||
.self_id = data->self_id,
|
||||
.id_pointer = id_pp,
|
||||
.cb_flag = cb_flag});
|
||||
if (flag & IDWALK_READONLY) {
|
||||
|
@ -126,7 +126,7 @@ int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData
|
|||
}
|
||||
|
||||
static bool library_foreach_ID_link(Main *bmain,
|
||||
ID *id_owner,
|
||||
ID *owner_id,
|
||||
ID *id,
|
||||
LibraryIDLinkCallback callback,
|
||||
void *user_data,
|
||||
|
@ -192,7 +192,7 @@ static void library_foreach_ID_data_cleanup(LibraryForeachIDData *data)
|
|||
|
||||
/** \return false in case iteration over ID pointers must be stopped, true otherwise. */
|
||||
static bool library_foreach_ID_link(Main *bmain,
|
||||
ID *id_owner,
|
||||
ID *owner_id,
|
||||
ID *id,
|
||||
LibraryIDLinkCallback callback,
|
||||
void *user_data,
|
||||
|
@ -259,7 +259,7 @@ static bool library_foreach_ID_link(Main *bmain,
|
|||
* knowledge of the owner ID then.
|
||||
* While not great, and that should be probably sanitized at some point, we cal live with it
|
||||
* for now. */
|
||||
data.owner_id = ((id->flag & LIB_EMBEDDED_DATA) != 0 && id_owner != NULL) ? id_owner :
|
||||
data.owner_id = ((id->flag & LIB_EMBEDDED_DATA) != 0 && owner_id != NULL) ? owner_id :
|
||||
data.self_id;
|
||||
|
||||
/* inherit_data is non-NULL when this function is called for some sub-data ID
|
||||
|
@ -374,13 +374,13 @@ void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t BKE_library_id_can_use_filter_id(const ID *id_owner, const bool include_ui)
|
||||
uint64_t BKE_library_id_can_use_filter_id(const ID *owner_id, const bool include_ui)
|
||||
{
|
||||
/* any type of ID can be used in custom props. */
|
||||
if (id_owner->properties) {
|
||||
if (owner_id->properties) {
|
||||
return FILTER_ID_ALL;
|
||||
}
|
||||
const short id_type_owner = GS(id_owner->name);
|
||||
const short id_type_owner = GS(owner_id->name);
|
||||
|
||||
/* IDProps of armature bones and nodes, and bNode->id can use virtually any type of ID. */
|
||||
if (ELEM(id_type_owner, ID_NT, ID_AR)) {
|
||||
|
@ -395,16 +395,16 @@ uint64_t BKE_library_id_can_use_filter_id(const ID *id_owner, const bool include
|
|||
/* Casting to non const.
|
||||
* TODO(jbakker): We should introduce a ntree_id_has_tree function as we are actually not
|
||||
* interested in the result. */
|
||||
if (ntreeFromID((ID *)id_owner)) {
|
||||
if (ntreeFromID((ID *)owner_id)) {
|
||||
return FILTER_ID_ALL;
|
||||
}
|
||||
|
||||
if (BKE_animdata_from_id(id_owner)) {
|
||||
if (BKE_animdata_from_id(owner_id)) {
|
||||
/* AnimationData can use virtually any kind of data-blocks, through drivers especially. */
|
||||
return FILTER_ID_ALL;
|
||||
}
|
||||
|
||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_owner)) {
|
||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
|
||||
/* LibOverride data 'hierarchy root' can virtually point back to any type of ID. */
|
||||
return FILTER_ID_ALL;
|
||||
}
|
||||
|
@ -496,14 +496,14 @@ uint64_t BKE_library_id_can_use_filter_id(const ID *id_owner, const bool include
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
|
||||
bool BKE_library_id_can_use_idtype(ID *owner_id, const short id_type_used)
|
||||
{
|
||||
/* any type of ID can be used in custom props. */
|
||||
if (id_owner->properties) {
|
||||
if (owner_id->properties) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const short id_type_owner = GS(id_owner->name);
|
||||
const short id_type_owner = GS(owner_id->name);
|
||||
/* Exception for ID_LI as they don't exist as a filter. */
|
||||
if (id_type_used == ID_LI) {
|
||||
return id_type_owner == ID_LI;
|
||||
|
@ -520,7 +520,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
|
|||
}
|
||||
|
||||
const uint64_t filter_id_type_used = BKE_idtype_idcode_to_idfilter(id_type_used);
|
||||
const uint64_t can_be_used = BKE_library_id_can_use_filter_id(id_owner, false);
|
||||
const uint64_t can_be_used = BKE_library_id_can_use_filter_id(owner_id, false);
|
||||
return (can_be_used & filter_id_type_used) != 0;
|
||||
}
|
||||
|
||||
|
@ -866,7 +866,7 @@ void BKE_lib_query_unused_ids_tag(Main *bmain,
|
|||
|
||||
static int foreach_libblock_used_linked_data_tag_clear_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
ID *self_id = cb_data->id_self;
|
||||
ID *self_id = cb_data->self_id;
|
||||
ID **id_p = cb_data->id_pointer;
|
||||
const int cb_flag = cb_data->cb_flag;
|
||||
bool *is_changed = cb_data->user_data;
|
||||
|
|
|
@ -177,8 +177,8 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
|
|||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
ID *id_owner = cb_data->id_owner;
|
||||
ID *id_self = cb_data->id_self;
|
||||
ID *id_owner = cb_data->owner_id;
|
||||
ID *id_self = cb_data->self_id;
|
||||
ID **id_p = cb_data->id_pointer;
|
||||
IDRemap *id_remap_data = cb_data->user_data;
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ static void light_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void light_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
Light *la = (Light *)id;
|
||||
BLO_read_id_address(reader, la->id.lib, &la->ipo); // XXX deprecated - old animation system
|
||||
BLO_read_id_address(reader, id, &la->ipo); // XXX deprecated - old animation system
|
||||
}
|
||||
|
||||
static void light_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -66,7 +66,7 @@ static void lightprobe_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void lightprobe_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
LightProbe *prb = (LightProbe *)id;
|
||||
BLO_read_id_address(reader, prb->id.lib, &prb->visibility_grp);
|
||||
BLO_read_id_address(reader, &prb->id, &prb->visibility_grp);
|
||||
}
|
||||
|
||||
IDTypeInfo IDType_ID_LP = {
|
||||
|
|
|
@ -682,7 +682,7 @@ static void linestyle_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
||||
LineStyleColorModifier_DistanceFromObject *cm =
|
||||
(LineStyleColorModifier_DistanceFromObject *)m;
|
||||
BLO_read_id_address(reader, linestyle->id.lib, &cm->target);
|
||||
BLO_read_id_address(reader, id, &cm->target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ static void linestyle_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
||||
LineStyleAlphaModifier_DistanceFromObject *am =
|
||||
(LineStyleAlphaModifier_DistanceFromObject *)m;
|
||||
BLO_read_id_address(reader, linestyle->id.lib, &am->target);
|
||||
BLO_read_id_address(reader, id, &am->target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -702,7 +702,7 @@ static void linestyle_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
case LS_MODIFIER_DISTANCE_FROM_OBJECT: {
|
||||
LineStyleThicknessModifier_DistanceFromObject *tm =
|
||||
(LineStyleThicknessModifier_DistanceFromObject *)m;
|
||||
BLO_read_id_address(reader, linestyle->id.lib, &tm->target);
|
||||
BLO_read_id_address(reader, id, &tm->target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -710,8 +710,8 @@ static void linestyle_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
for (int a = 0; a < MAX_MTEX; a++) {
|
||||
MTex *mtex = linestyle->mtex[a];
|
||||
if (mtex) {
|
||||
BLO_read_id_address(reader, linestyle->id.lib, &mtex->tex);
|
||||
BLO_read_id_address(reader, linestyle->id.lib, &mtex->object);
|
||||
BLO_read_id_address(reader, id, &mtex->tex);
|
||||
BLO_read_id_address(reader, id, &mtex->object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,22 +230,22 @@ void BKE_main_unlock(struct Main *bmain)
|
|||
static int main_relations_create_idlink_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
{
|
||||
MainIDRelations *bmain_relations = cb_data->user_data;
|
||||
ID *id_self = cb_data->id_self;
|
||||
ID *self_id = cb_data->self_id;
|
||||
ID **id_pointer = cb_data->id_pointer;
|
||||
const int cb_flag = cb_data->cb_flag;
|
||||
|
||||
if (*id_pointer) {
|
||||
MainIDRelationsEntry **entry_p;
|
||||
|
||||
/* Add `id_pointer` as child of `id_self`. */
|
||||
/* Add `id_pointer` as child of `self_id`. */
|
||||
{
|
||||
if (!BLI_ghash_ensure_p(
|
||||
bmain_relations->relations_from_pointers, id_self, (void ***)&entry_p)) {
|
||||
bmain_relations->relations_from_pointers, self_id, (void ***)&entry_p)) {
|
||||
*entry_p = MEM_callocN(sizeof(**entry_p), __func__);
|
||||
(*entry_p)->session_uuid = id_self->session_uuid;
|
||||
(*entry_p)->session_uuid = self_id->session_uuid;
|
||||
}
|
||||
else {
|
||||
BLI_assert((*entry_p)->session_uuid == id_self->session_uuid);
|
||||
BLI_assert((*entry_p)->session_uuid == self_id->session_uuid);
|
||||
}
|
||||
MainIDRelationsEntryItem *to_id_entry = BLI_mempool_alloc(bmain_relations->entry_items_pool);
|
||||
to_id_entry->next = (*entry_p)->to_ids;
|
||||
|
@ -256,7 +256,7 @@ static int main_relations_create_idlink_cb(LibraryIDLinkCallbackData *cb_data)
|
|||
(*entry_p)->to_ids = to_id_entry;
|
||||
}
|
||||
|
||||
/* Add `id_self` as parent of `id_pointer`. */
|
||||
/* Add `self_id` as parent of `id_pointer`. */
|
||||
if (*id_pointer != NULL) {
|
||||
if (!BLI_ghash_ensure_p(
|
||||
bmain_relations->relations_from_pointers, *id_pointer, (void ***)&entry_p)) {
|
||||
|
@ -269,8 +269,8 @@ static int main_relations_create_idlink_cb(LibraryIDLinkCallbackData *cb_data)
|
|||
MainIDRelationsEntryItem *from_id_entry = BLI_mempool_alloc(
|
||||
bmain_relations->entry_items_pool);
|
||||
from_id_entry->next = (*entry_p)->from_ids;
|
||||
from_id_entry->id_pointer.from = id_self;
|
||||
from_id_entry->session_uuid = id_self->session_uuid;
|
||||
from_id_entry->id_pointer.from = self_id;
|
||||
from_id_entry->session_uuid = self_id->session_uuid;
|
||||
from_id_entry->usage_flag = cb_flag;
|
||||
(*entry_p)->from_ids = from_id_entry;
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ static void mask_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
|
||||
static void lib_link_mask_parent(BlendLibReader *reader, Mask *mask, MaskParent *parent)
|
||||
{
|
||||
BLO_read_id_address(reader, mask->id.lib, &parent->id);
|
||||
BLO_read_id_address(reader, &mask->id, &parent->id);
|
||||
}
|
||||
|
||||
static void mask_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
|
|
|
@ -223,16 +223,16 @@ static void material_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void material_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
Material *ma = (Material *)id;
|
||||
BLO_read_id_address(reader, ma->id.lib, &ma->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, id, &ma->ipo); /* XXX deprecated - old animation system */
|
||||
|
||||
/* relink grease pencil settings */
|
||||
if (ma->gp_style != nullptr) {
|
||||
MaterialGPencilStyle *gp_style = ma->gp_style;
|
||||
if (gp_style->sima != nullptr) {
|
||||
BLO_read_id_address(reader, ma->id.lib, &gp_style->sima);
|
||||
BLO_read_id_address(reader, id, &gp_style->sima);
|
||||
}
|
||||
if (gp_style->ima != nullptr) {
|
||||
BLO_read_id_address(reader, ma->id.lib, &gp_style->ima);
|
||||
BLO_read_id_address(reader, id, &gp_style->ima);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,10 +141,10 @@ static void metaball_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
MetaBall *mb = (MetaBall *)id;
|
||||
for (int a = 0; a < mb->totcol; a++) {
|
||||
BLO_read_id_address(reader, mb->id.lib, &mb->mat[a]);
|
||||
BLO_read_id_address(reader, id, &mb->mat[a]);
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, mb->id.lib, &mb->ipo); // XXX deprecated - old animation system
|
||||
BLO_read_id_address(reader, id, &mb->ipo); // XXX deprecated - old animation system
|
||||
}
|
||||
|
||||
static void metaball_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -257,68 +257,10 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
|
|||
mesh->poly_offset_indices = nullptr;
|
||||
}
|
||||
else {
|
||||
Set<std::string> names_to_skip;
|
||||
if (!BLO_write_is_undo(writer)) {
|
||||
/* When converting to the old mesh format, don't save redundant attributes. */
|
||||
names_to_skip.add_multiple_new({"position",
|
||||
".edge_verts",
|
||||
".corner_vert",
|
||||
".corner_edge",
|
||||
".hide_vert",
|
||||
".hide_edge",
|
||||
".hide_poly",
|
||||
".uv_seam",
|
||||
".select_vert",
|
||||
".select_edge",
|
||||
".select_poly",
|
||||
"material_index",
|
||||
"sharp_face",
|
||||
"sharp_edge"});
|
||||
|
||||
mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts(
|
||||
mesh, temp_arrays_for_legacy_format, vert_layers);
|
||||
mesh->mloop = BKE_mesh_legacy_convert_corners_to_loops(
|
||||
mesh, temp_arrays_for_legacy_format, loop_layers);
|
||||
mesh->medge = BKE_mesh_legacy_convert_edges_to_medge(
|
||||
mesh, temp_arrays_for_legacy_format, edge_layers);
|
||||
|
||||
MutableSpan<MPoly> legacy_polys = BKE_mesh_legacy_convert_offsets_to_polys(
|
||||
mesh, temp_arrays_for_legacy_format, poly_layers);
|
||||
|
||||
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh, legacy_polys);
|
||||
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh, legacy_polys);
|
||||
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh, legacy_polys);
|
||||
BKE_mesh_legacy_sharp_faces_to_flags(mesh, legacy_polys);
|
||||
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
|
||||
BKE_mesh_legacy_edge_crease_from_layers(mesh);
|
||||
BKE_mesh_legacy_sharp_edges_to_flags(mesh);
|
||||
BKE_mesh_legacy_uv_seam_to_flags(mesh);
|
||||
BKE_mesh_legacy_attribute_strings_to_flags(mesh);
|
||||
mesh->active_color_attribute = nullptr;
|
||||
mesh->default_color_attribute = nullptr;
|
||||
BKE_mesh_legacy_convert_loose_edges_to_flag(mesh);
|
||||
mesh->poly_offset_indices = nullptr;
|
||||
|
||||
/* Set deprecated mesh data pointers for forward compatibility. */
|
||||
mesh->mpoly = legacy_polys.data();
|
||||
mesh->dvert = const_cast<MDeformVert *>(mesh->deform_verts().data());
|
||||
}
|
||||
|
||||
CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip);
|
||||
CustomData_blend_write_prepare(mesh->edata, edge_layers, names_to_skip);
|
||||
CustomData_blend_write_prepare(mesh->ldata, loop_layers, names_to_skip);
|
||||
CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip);
|
||||
|
||||
if (!BLO_write_is_undo(writer)) {
|
||||
/* #CustomData expects the layers to be sorted in increasing order based on type. */
|
||||
std::stable_sort(
|
||||
poly_layers.begin(),
|
||||
poly_layers.end(),
|
||||
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
|
||||
|
||||
BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers);
|
||||
BKE_mesh_legacy_face_set_from_generic(poly_layers);
|
||||
}
|
||||
CustomData_blend_write_prepare(mesh->vdata, vert_layers, {});
|
||||
CustomData_blend_write_prepare(mesh->edata, edge_layers, {});
|
||||
CustomData_blend_write_prepare(mesh->ldata, loop_layers, {});
|
||||
CustomData_blend_write_prepare(mesh->pdata, poly_layers, {});
|
||||
}
|
||||
|
||||
mesh->runtime = nullptr;
|
||||
|
@ -420,16 +362,16 @@ static void mesh_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
/* this check added for python created meshes */
|
||||
if (me->mat) {
|
||||
for (int i = 0; i < me->totcol; i++) {
|
||||
BLO_read_id_address(reader, me->id.lib, &me->mat[i]);
|
||||
BLO_read_id_address(reader, id, &me->mat[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
me->totcol = 0;
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, me->id.lib, &me->ipo); // XXX: deprecated: old anim sys
|
||||
BLO_read_id_address(reader, me->id.lib, &me->key);
|
||||
BLO_read_id_address(reader, me->id.lib, &me->texcomesh);
|
||||
BLO_read_id_address(reader, id, &me->ipo); // XXX: deprecated: old anim sys
|
||||
BLO_read_id_address(reader, id, &me->key);
|
||||
BLO_read_id_address(reader, id, &me->texcomesh);
|
||||
}
|
||||
|
||||
static void mesh_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -231,7 +231,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
|
|||
}
|
||||
|
||||
/* Create new edges. */
|
||||
if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) {
|
||||
if (!CustomData_has_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) {
|
||||
CustomData_add_layer_named(
|
||||
&mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_edge");
|
||||
}
|
||||
|
|
|
@ -1236,25 +1236,6 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh)
|
|||
/** \name Sharp Edge Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_sharp_faces_to_flags(Mesh *mesh, blender::MutableSpan<MPoly> legacy_polys)
|
||||
{
|
||||
using namespace blender;
|
||||
if (const bool *sharp_faces = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face")))
|
||||
{
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, !sharp_faces[i], ME_SMOOTH);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
for (const int i : legacy_polys.index_range()) {
|
||||
legacy_polys[i].flag_legacy |= ME_SMOOTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1289,28 +1270,6 @@ void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh)
|
|||
/** \name Face Set Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_face_set_from_generic(blender::MutableSpan<CustomDataLayer> poly_layers)
|
||||
{
|
||||
using namespace blender;
|
||||
bool changed = false;
|
||||
for (CustomDataLayer &layer : poly_layers) {
|
||||
if (StringRef(layer.name) == ".sculpt_face_set") {
|
||||
layer.type = CD_SCULPT_FACE_SETS;
|
||||
layer.name[0] = '\0';
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
/* #CustomData expects the layers to be sorted in increasing order based on type. */
|
||||
std::stable_sort(
|
||||
poly_layers.begin(),
|
||||
poly_layers.end(),
|
||||
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1349,41 +1308,6 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
|
|||
/** \name Bevel Weight Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
|
||||
if (const float *weights = static_cast<const float *>(
|
||||
CustomData_get_layer(&mesh->vdata, CD_BWEIGHT)))
|
||||
{
|
||||
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
|
||||
for (const int i : verts.index_range()) {
|
||||
verts[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
|
||||
for (const int i : verts.index_range()) {
|
||||
verts[i].bweight_legacy = 0;
|
||||
}
|
||||
}
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
if (const float *weights = static_cast<const float *>(
|
||||
CustomData_get_layer(&mesh->edata, CD_BWEIGHT)))
|
||||
{
|
||||
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].bweight_legacy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1416,26 +1340,6 @@ void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
|
|||
/** \name Edge Crease Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_edge_crease_from_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
if (const float *creases = static_cast<const float *>(
|
||||
CustomData_get_layer(&mesh->edata, CD_CREASE)))
|
||||
{
|
||||
mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].crease_legacy = std::clamp(creases[i], 0.0f, 1.0f) * 255.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh->cd_flag &= ~ME_CDFLAG_EDGE_CREASE;
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].crease_legacy = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1458,26 +1362,6 @@ void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh)
|
|||
/** \name Sharp Edge Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_sharp_edges_to_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
if (const bool *sharp_edges = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")))
|
||||
{
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, sharp_edges[i], ME_SHARP);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].flag_legacy &= ~ME_SHARP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1511,26 +1395,6 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh)
|
|||
/** \name UV Seam Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_uv_seam_to_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
if (const bool *uv_seams = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, ".uv_seam")))
|
||||
{
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, uv_seams[i], ME_SEAM);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].flag_legacy &= ~ME_SEAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1564,40 +1428,6 @@ void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh)
|
|||
/** \name Hide Attribute and Legacy Flag Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
|
||||
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(verts[i].flag_legacy, hide_vert[i], ME_HIDE);
|
||||
}
|
||||
});
|
||||
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
const VArray<bool> hide_edge = *attributes.lookup_or_default<bool>(
|
||||
".hide_edge", ATTR_DOMAIN_EDGE, false);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, hide_edge[i], ME_HIDE);
|
||||
}
|
||||
});
|
||||
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, hide_poly[i], ME_HIDE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1663,21 +1493,6 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
|
|||
/** \name Material Index Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
legacy_polys[i].mat_nr_legacy = material_indices[i];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1708,87 +1523,6 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
|
|||
/** \name Generic UV Map Conversion
|
||||
* \{ */
|
||||
|
||||
static const bool *layers_find_bool_named(const Span<CustomDataLayer> layers,
|
||||
const blender::StringRef name)
|
||||
{
|
||||
for (const CustomDataLayer &layer : layers) {
|
||||
if (layer.type == CD_PROP_BOOL) {
|
||||
if (layer.name == name) {
|
||||
return static_cast<const bool *>(layer.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_uvs_to_struct(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_mloopuv_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const int loops_num = mesh->totloop;
|
||||
Vector<CustomDataLayer, 16> new_layer_to_write;
|
||||
|
||||
/* Don't write the boolean UV map sublayers which will be written in the legacy #MLoopUV type. */
|
||||
Set<std::string> uv_sublayers_to_skip;
|
||||
char vert_name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
char edge_name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
char pin_name[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
for (const CustomDataLayer &layer : loop_layers_to_write) {
|
||||
if (layer.type == CD_PROP_FLOAT2) {
|
||||
uv_sublayers_to_skip.add_multiple_new(
|
||||
{BKE_uv_map_vert_select_name_get(layer.name, vert_name),
|
||||
BKE_uv_map_edge_select_name_get(layer.name, edge_name),
|
||||
BKE_uv_map_pin_name_get(layer.name, pin_name)});
|
||||
}
|
||||
}
|
||||
|
||||
for (const CustomDataLayer &layer : loop_layers_to_write) {
|
||||
if (layer.name[0] && uv_sublayers_to_skip.contains_as(layer.name)) {
|
||||
continue;
|
||||
}
|
||||
if (layer.type != CD_PROP_FLOAT2) {
|
||||
new_layer_to_write.append(layer);
|
||||
continue;
|
||||
}
|
||||
const Span<float2> coords{static_cast<const float2 *>(layer.data), loops_num};
|
||||
CustomDataLayer mloopuv_layer = layer;
|
||||
mloopuv_layer.type = CD_MLOOPUV;
|
||||
MutableSpan<MLoopUV> mloopuv = temp_mloopuv_for_convert.construct<Array<MLoopUV>>(loops_num);
|
||||
mloopuv_layer.data = mloopuv.data();
|
||||
|
||||
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
const bool *vert_selection = layers_find_bool_named(
|
||||
loop_layers_to_write, BKE_uv_map_vert_select_name_get(layer.name, buffer));
|
||||
const bool *edge_selection = layers_find_bool_named(
|
||||
loop_layers_to_write, BKE_uv_map_edge_select_name_get(layer.name, buffer));
|
||||
const bool *pin = layers_find_bool_named(loop_layers_to_write,
|
||||
BKE_uv_map_pin_name_get(layer.name, buffer));
|
||||
|
||||
threading::parallel_for(mloopuv.index_range(), 2048, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
copy_v2_v2(mloopuv[i].uv, coords[i]);
|
||||
SET_FLAG_FROM_TEST(mloopuv[i].flag, vert_selection && vert_selection[i], MLOOPUV_VERTSEL);
|
||||
SET_FLAG_FROM_TEST(mloopuv[i].flag, edge_selection && edge_selection[i], MLOOPUV_EDGESEL);
|
||||
SET_FLAG_FROM_TEST(mloopuv[i].flag, pin && pin[i], MLOOPUV_PINNED);
|
||||
}
|
||||
});
|
||||
new_layer_to_write.append(mloopuv_layer);
|
||||
}
|
||||
|
||||
/* #CustomData expects the layers to be sorted in increasing order based on type. */
|
||||
std::stable_sort(
|
||||
new_layer_to_write.begin(),
|
||||
new_layer_to_write.end(),
|
||||
[](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; });
|
||||
|
||||
loop_layers_to_write = new_layer_to_write;
|
||||
mesh->ldata.totlayer = new_layer_to_write.size();
|
||||
mesh->ldata.maxlayer = mesh->ldata.totlayer;
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -1918,40 +1652,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
|
|||
/** \name Selection Attribute and Legacy Flag Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh,
|
||||
blender::MutableSpan<MPoly> legacy_polys)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
|
||||
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(verts[i].flag_legacy, select_vert[i], SELECT);
|
||||
}
|
||||
});
|
||||
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
const VArray<bool> select_edge = *attributes.lookup_or_default<bool>(
|
||||
".select_edge", ATTR_DOMAIN_EDGE, false);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, select_edge[i], SELECT);
|
||||
}
|
||||
});
|
||||
|
||||
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, select_poly[i], ME_FACE_SEL);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
|
@ -2013,67 +1713,16 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Loose Edges
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
|
||||
const LooseEdgeCache &loose_edges = mesh->loose_edges();
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
|
||||
if (loose_edges.count == 0) {
|
||||
for (const int64_t i : range) {
|
||||
edges[i].flag_legacy &= ~ME_LOOSEEDGE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const int64_t i : range) {
|
||||
SET_FLAG_FROM_TEST(edges[i].flag_legacy, loose_edges.is_loose_bits[i], ME_LOOSEEDGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Vertex and Position Conversion
|
||||
* \{ */
|
||||
|
||||
MVert *BKE_mesh_legacy_convert_positions_to_verts(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &vert_layers_to_write)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
const Span<float3> positions = mesh->vert_positions();
|
||||
|
||||
CustomDataLayer mvert_layer{};
|
||||
mvert_layer.type = CD_MVERT;
|
||||
MutableSpan<MVert> verts = temp_arrays_for_convert.construct<Array<MVert>>(mesh->totvert);
|
||||
mvert_layer.data = verts.data();
|
||||
|
||||
threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
copy_v3_v3(verts[i].co_legacy, positions[i]);
|
||||
}
|
||||
});
|
||||
|
||||
vert_layers_to_write.append(mvert_layer);
|
||||
return verts.data();
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const MVert *mvert = static_cast<const MVert *>(CustomData_get_layer(&mesh->vdata, CD_MVERT));
|
||||
if (!mvert || CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) {
|
||||
if (!mvert || CustomData_has_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2098,37 +1747,12 @@ void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh)
|
|||
/** \name MEdge and int2 conversion
|
||||
* \{ */
|
||||
|
||||
MEdge *BKE_mesh_legacy_convert_edges_to_medge(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &edge_layers_to_write)
|
||||
{
|
||||
using namespace blender;
|
||||
const Span<int2> edges = mesh->edges();
|
||||
|
||||
CustomDataLayer medge_layer{};
|
||||
medge_layer.type = CD_MEDGE;
|
||||
MutableSpan<MEdge> legacy_edges = temp_arrays_for_convert.construct<Array<MEdge>>(mesh->totedge);
|
||||
medge_layer.data = legacy_edges.data();
|
||||
|
||||
threading::parallel_for(edges.index_range(), 2048, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
legacy_edges[i] = {};
|
||||
legacy_edges[i].v1 = edges[i][0];
|
||||
legacy_edges[i].v2 = edges[i][1];
|
||||
}
|
||||
});
|
||||
|
||||
edge_layers_to_write.append(medge_layer);
|
||||
return legacy_edges.data();
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const MEdge *medge = static_cast<const MEdge *>(CustomData_get_layer(&mesh->edata, CD_MEDGE));
|
||||
if (!medge || CustomData_get_layer_named(&mesh->edata, CD_PROP_INT32_2D, ".edge_verts")) {
|
||||
if (!medge || CustomData_has_layer_named(&mesh->edata, CD_PROP_INT32_2D, ".edge_verts")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2217,95 +1841,17 @@ void BKE_mesh_legacy_attribute_flags_to_strings(Mesh *mesh)
|
|||
default_from_indices(mesh->ldata);
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
CustomData *vdata = &mesh->vdata;
|
||||
CustomData *ldata = &mesh->ldata;
|
||||
|
||||
CustomData_clear_layer_flag(
|
||||
vdata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
|
||||
CustomData_clear_layer_flag(
|
||||
ldata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
|
||||
CustomData_clear_layer_flag(ldata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
|
||||
CustomData_clear_layer_flag(vdata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
|
||||
|
||||
if (const char *name = mesh->active_color_attribute) {
|
||||
int i;
|
||||
if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_active_index(vdata, CD_PROP_BYTE_COLOR, i);
|
||||
vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
|
||||
}
|
||||
else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_active_index(vdata, CD_PROP_COLOR, i);
|
||||
vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
|
||||
}
|
||||
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_active_index(ldata, CD_PROP_BYTE_COLOR, i);
|
||||
ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
|
||||
}
|
||||
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_active_index(ldata, CD_PROP_COLOR, i);
|
||||
ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
|
||||
}
|
||||
}
|
||||
if (const char *name = mesh->default_color_attribute) {
|
||||
int i;
|
||||
if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_render_index(vdata, CD_PROP_BYTE_COLOR, i);
|
||||
vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
|
||||
}
|
||||
else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_render_index(vdata, CD_PROP_COLOR, i);
|
||||
vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
|
||||
}
|
||||
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_render_index(ldata, CD_PROP_BYTE_COLOR, i);
|
||||
ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
|
||||
}
|
||||
else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) {
|
||||
CustomData_set_layer_render_index(ldata, CD_PROP_COLOR, i);
|
||||
ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Face Corner Conversion
|
||||
* \{ */
|
||||
|
||||
MLoop *BKE_mesh_legacy_convert_corners_to_loops(
|
||||
Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &loop_layers_to_write)
|
||||
{
|
||||
using namespace blender;
|
||||
const Span<int> corner_verts = mesh->corner_verts();
|
||||
const Span<int> corner_edges = mesh->corner_edges();
|
||||
|
||||
CustomDataLayer mloop_layer{};
|
||||
mloop_layer.type = CD_MLOOP;
|
||||
MutableSpan<MLoop> loops = temp_arrays_for_convert.construct<Array<MLoop>>(mesh->totloop);
|
||||
mloop_layer.data = loops.data();
|
||||
|
||||
threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
loops[i].v = corner_verts[i];
|
||||
loops[i].e = corner_edges[i];
|
||||
}
|
||||
});
|
||||
|
||||
loop_layers_to_write.append(mloop_layer);
|
||||
return loops.data();
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
if (CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert") &&
|
||||
CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge"))
|
||||
if (CustomData_has_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert") &&
|
||||
CustomData_has_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2335,30 +1881,6 @@ void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh)
|
|||
/** \name Poly Offset Conversion
|
||||
* \{ */
|
||||
|
||||
blender::MutableSpan<MPoly> BKE_mesh_legacy_convert_offsets_to_polys(
|
||||
const Mesh *mesh,
|
||||
blender::ResourceScope &temp_arrays_for_convert,
|
||||
blender::Vector<CustomDataLayer, 16> &poly_layers_to_write)
|
||||
{
|
||||
using namespace blender;
|
||||
const OffsetIndices polys = mesh->polys();
|
||||
|
||||
MutableSpan<MPoly> polys_legacy = temp_arrays_for_convert.construct<Array<MPoly>>(mesh->totpoly);
|
||||
threading::parallel_for(polys_legacy.index_range(), 2048, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
polys_legacy[i].loopstart = polys[i].start();
|
||||
polys_legacy[i].totloop = polys[i].size();
|
||||
}
|
||||
});
|
||||
|
||||
CustomDataLayer layer{};
|
||||
layer.type = CD_MPOLY;
|
||||
layer.data = polys_legacy.data();
|
||||
poly_layers_to_write.append(layer);
|
||||
|
||||
return polys_legacy;
|
||||
}
|
||||
|
||||
static bool poly_loops_orders_match(const Span<MPoly> polys)
|
||||
{
|
||||
for (const int i : polys.index_range().drop_back(1)) {
|
||||
|
|
|
@ -71,10 +71,6 @@
|
|||
|
||||
#include "tracking_private.h"
|
||||
|
||||
/* Convert camera object to legacy format where the camera tracks are stored in the MovieTracking
|
||||
* structure when saving .blend file. */
|
||||
#define USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE 1
|
||||
|
||||
static void free_buffers(MovieClip *clip);
|
||||
|
||||
static void movie_clip_init_data(ID *id)
|
||||
|
@ -200,39 +196,6 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad
|
|||
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
|
||||
#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE
|
||||
const bool is_undo = BLO_write_is_undo(writer);
|
||||
|
||||
/* When using legacy format for camera object assign the list of camera tracks to the
|
||||
* MovieTracking object. Do it in-place as it simplifies the code a bit, and it is not
|
||||
* supposed to cause threading issues as no other code is meant to access the legacy fields. */
|
||||
if (!is_undo) {
|
||||
MovieTrackingObject *active_tracking_object = BKE_tracking_object_get_active(tracking);
|
||||
MovieTrackingObject *tracking_camera_object = BKE_tracking_object_get_camera(tracking);
|
||||
BLI_assert(active_tracking_object != NULL);
|
||||
BLI_assert(tracking_camera_object != NULL);
|
||||
|
||||
tracking->tracks_legacy = tracking_camera_object->tracks;
|
||||
tracking->plane_tracks_legacy = tracking_camera_object->plane_tracks;
|
||||
|
||||
/* The active track in the tracking structure used to be shared across all tracking objects. */
|
||||
tracking->act_track_legacy = active_tracking_object->active_track;
|
||||
tracking->act_plane_track_legacy = active_tracking_object->active_plane_track;
|
||||
|
||||
tracking->reconstruction_legacy = tracking_camera_object->reconstruction;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Assign the pixel-space principal point for forward compatibility. */
|
||||
/* TODO(sergey): Remove with the next major version update when forward compatibility is allowed
|
||||
* to be broken. */
|
||||
if (!is_undo && clip->lastsize[0] != 0 && clip->lastsize[1] != 0) {
|
||||
tracking_principal_point_normalized_to_pixel(tracking->camera.principal_point,
|
||||
clip->lastsize[0],
|
||||
clip->lastsize[1],
|
||||
tracking->camera.principal_legacy);
|
||||
}
|
||||
|
||||
BLO_write_id_struct(writer, MovieClip, id_address, &clip->id);
|
||||
BKE_id_blend_write(writer, &clip->id);
|
||||
|
||||
|
@ -241,39 +204,11 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
|
||||
#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE
|
||||
/* When saving cameras object in the legacy format clear the list of tracks. This is because
|
||||
* the tracking object code is generic and assumes object owns the tracks in the list. For the
|
||||
* camera tracks that is not the case in the legacy format. */
|
||||
if (!is_undo && (object->flag & TRACKING_OBJECT_CAMERA)) {
|
||||
MovieTrackingObject legacy_object = *object;
|
||||
BLI_listbase_clear(&legacy_object.tracks);
|
||||
BLI_listbase_clear(&legacy_object.plane_tracks);
|
||||
legacy_object.active_track = NULL;
|
||||
legacy_object.active_plane_track = NULL;
|
||||
memset(&legacy_object.reconstruction, 0, sizeof(legacy_object.reconstruction));
|
||||
BLO_write_struct_at_address(writer, MovieTrackingObject, object, &legacy_object);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
BLO_write_struct(writer, MovieTrackingObject, object);
|
||||
}
|
||||
|
||||
BLO_write_struct(writer, MovieTrackingObject, object);
|
||||
write_movieTracks(writer, &object->tracks);
|
||||
write_moviePlaneTracks(writer, &object->plane_tracks);
|
||||
write_movieReconstruction(writer, &object->reconstruction);
|
||||
}
|
||||
|
||||
#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE
|
||||
if (!is_undo) {
|
||||
BLI_listbase_clear(&tracking->tracks_legacy);
|
||||
BLI_listbase_clear(&tracking->plane_tracks_legacy);
|
||||
tracking->act_track_legacy = NULL;
|
||||
tracking->act_plane_track_legacy = NULL;
|
||||
memset(&tracking->reconstruction_legacy, 0, sizeof(tracking->reconstruction_legacy));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void direct_link_movieReconstruction(BlendDataReader *reader,
|
||||
|
@ -350,7 +285,7 @@ static void movieclip_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void lib_link_movieTracks(BlendLibReader *reader, MovieClip *clip, ListBase *tracksbase)
|
||||
{
|
||||
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
|
||||
BLO_read_id_address(reader, clip->id.lib, &track->gpd);
|
||||
BLO_read_id_address(reader, &clip->id, &track->gpd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +294,7 @@ static void lib_link_moviePlaneTracks(BlendLibReader *reader,
|
|||
ListBase *tracksbase)
|
||||
{
|
||||
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, tracksbase) {
|
||||
BLO_read_id_address(reader, clip->id.lib, &plane_track->image);
|
||||
BLO_read_id_address(reader, &clip->id, &plane_track->image);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,7 +303,7 @@ static void movieclip_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
MovieClip *clip = (MovieClip *)id;
|
||||
MovieTracking *tracking = &clip->tracking;
|
||||
|
||||
BLO_read_id_address(reader, clip->id.lib, &clip->gpd);
|
||||
BLO_read_id_address(reader, id, &clip->gpd);
|
||||
|
||||
LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
|
||||
lib_link_movieTracks(reader, clip, &object->tracks);
|
||||
|
|
|
@ -2387,7 +2387,7 @@ static void blend_lib_read_nla_strips(BlendLibReader *reader, ID *id, ListBase *
|
|||
BKE_fcurve_blend_read_lib(reader, id, &strip->fcurves);
|
||||
|
||||
/* reassign the counted-reference to action */
|
||||
BLO_read_id_address(reader, id->lib, &strip->act);
|
||||
BLO_read_id_address(reader, id, &strip->act);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -879,9 +879,9 @@ static void ntree_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
ntreeBlendReadData(reader, nullptr, ntree);
|
||||
}
|
||||
|
||||
static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSocket *sock)
|
||||
static void lib_link_node_socket(BlendLibReader *reader, ID *self_id, bNodeSocket *sock)
|
||||
{
|
||||
IDP_BlendReadLib(reader, lib, sock->prop);
|
||||
IDP_BlendReadLib(reader, self_id, sock->prop);
|
||||
|
||||
/* This can happen for all socket types when a file is saved in an older version of Blender than
|
||||
* it was originally created in (#86298). Some socket types still require a default value. The
|
||||
|
@ -893,26 +893,27 @@ static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSock
|
|||
switch (eNodeSocketDatatype(sock->type)) {
|
||||
case SOCK_OBJECT: {
|
||||
BLO_read_id_address(
|
||||
reader, lib, &sock->default_value_typed<bNodeSocketValueObject>()->value);
|
||||
reader, self_id, &sock->default_value_typed<bNodeSocketValueObject>()->value);
|
||||
break;
|
||||
}
|
||||
case SOCK_IMAGE: {
|
||||
BLO_read_id_address(reader, lib, &sock->default_value_typed<bNodeSocketValueImage>()->value);
|
||||
BLO_read_id_address(
|
||||
reader, self_id, &sock->default_value_typed<bNodeSocketValueImage>()->value);
|
||||
break;
|
||||
}
|
||||
case SOCK_COLLECTION: {
|
||||
BLO_read_id_address(
|
||||
reader, lib, &sock->default_value_typed<bNodeSocketValueCollection>()->value);
|
||||
reader, self_id, &sock->default_value_typed<bNodeSocketValueCollection>()->value);
|
||||
break;
|
||||
}
|
||||
case SOCK_TEXTURE: {
|
||||
BLO_read_id_address(
|
||||
reader, lib, &sock->default_value_typed<bNodeSocketValueTexture>()->value);
|
||||
reader, self_id, &sock->default_value_typed<bNodeSocketValueTexture>()->value);
|
||||
break;
|
||||
}
|
||||
case SOCK_MATERIAL: {
|
||||
BLO_read_id_address(
|
||||
reader, lib, &sock->default_value_typed<bNodeSocketValueMaterial>()->value);
|
||||
reader, self_id, &sock->default_value_typed<bNodeSocketValueMaterial>()->value);
|
||||
break;
|
||||
}
|
||||
case SOCK_FLOAT:
|
||||
|
@ -929,32 +930,30 @@ static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSock
|
|||
}
|
||||
}
|
||||
|
||||
static void lib_link_node_sockets(BlendLibReader *reader, Library *lib, ListBase *sockets)
|
||||
static void lib_link_node_sockets(BlendLibReader *reader, ID *self_id, ListBase *sockets)
|
||||
{
|
||||
LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
|
||||
lib_link_node_socket(reader, lib, sock);
|
||||
lib_link_node_socket(reader, self_id, sock);
|
||||
}
|
||||
}
|
||||
|
||||
void ntreeBlendReadLib(BlendLibReader *reader, bNodeTree *ntree)
|
||||
{
|
||||
Library *lib = ntree->id.lib;
|
||||
|
||||
BLO_read_id_address(reader, lib, &ntree->gpd);
|
||||
BLO_read_id_address(reader, &ntree->id, &ntree->gpd);
|
||||
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
|
||||
* of library blocks that implement this. */
|
||||
IDP_BlendReadLib(reader, lib, node->prop);
|
||||
IDP_BlendReadLib(reader, &ntree->id, node->prop);
|
||||
|
||||
BLO_read_id_address(reader, lib, &node->id);
|
||||
BLO_read_id_address(reader, &ntree->id, &node->id);
|
||||
|
||||
lib_link_node_sockets(reader, lib, &node->inputs);
|
||||
lib_link_node_sockets(reader, lib, &node->outputs);
|
||||
lib_link_node_sockets(reader, &ntree->id, &node->inputs);
|
||||
lib_link_node_sockets(reader, &ntree->id, &node->outputs);
|
||||
}
|
||||
|
||||
lib_link_node_sockets(reader, lib, &ntree->inputs);
|
||||
lib_link_node_sockets(reader, lib, &ntree->outputs);
|
||||
lib_link_node_sockets(reader, &ntree->id, &ntree->inputs);
|
||||
lib_link_node_sockets(reader, &ntree->id, &ntree->outputs);
|
||||
|
||||
/* Set `node->typeinfo` pointers. This is done in lib linking, after the
|
||||
* first versioning that can change types still without functions that
|
||||
|
|
|
@ -845,11 +845,11 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void lib_link_nlastrips(BlendLibReader *reader, ID *id, ListBase *striplist)
|
||||
{
|
||||
LISTBASE_FOREACH (bActionStrip *, strip, striplist) {
|
||||
BLO_read_id_address(reader, id->lib, &strip->object);
|
||||
BLO_read_id_address(reader, id->lib, &strip->act);
|
||||
BLO_read_id_address(reader, id->lib, &strip->ipo);
|
||||
BLO_read_id_address(reader, id, &strip->object);
|
||||
BLO_read_id_address(reader, id, &strip->act);
|
||||
BLO_read_id_address(reader, id, &strip->ipo);
|
||||
LISTBASE_FOREACH (bActionModifier *, amod, &strip->modifiers) {
|
||||
BLO_read_id_address(reader, id->lib, &amod->ob);
|
||||
BLO_read_id_address(reader, id, &amod->ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ static void lib_link_nlastrips(BlendLibReader *reader, ID *id, ListBase *stripli
|
|||
static void lib_link_constraint_channels(BlendLibReader *reader, ID *id, ListBase *chanbase)
|
||||
{
|
||||
LISTBASE_FOREACH (bConstraintChannel *, chan, chanbase) {
|
||||
BLO_read_id_address(reader, id->lib, &chan->ipo);
|
||||
BLO_read_id_address(reader, id, &chan->ipo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -870,23 +870,24 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
BlendFileReadReport *reports = BLO_read_lib_reports(reader);
|
||||
|
||||
/* XXX deprecated - old animation system <<< */
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->ipo);
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->action);
|
||||
BLO_read_id_address(reader, id, &ob->ipo);
|
||||
BLO_read_id_address(reader, id, &ob->action);
|
||||
/* >>> XXX deprecated - old animation system */
|
||||
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->parent);
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->track);
|
||||
BLO_read_id_address(reader, id, &ob->parent);
|
||||
BLO_read_id_address(reader, id, &ob->track);
|
||||
|
||||
/* XXX deprecated - old pose library, deprecated in Blender 3.5. */
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->poselib);
|
||||
BLO_read_id_address(reader, id, &ob->poselib);
|
||||
|
||||
/* 2.8x drops support for non-empty dupli instances. */
|
||||
if (ob->type == OB_EMPTY) {
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->instance_collection);
|
||||
BLO_read_id_address(reader, id, &ob->instance_collection);
|
||||
}
|
||||
else {
|
||||
if (ob->instance_collection != nullptr) {
|
||||
ID *new_id = BLO_read_get_new_id_address(reader, ob->id.lib, &ob->instance_collection->id);
|
||||
ID *new_id = BLO_read_get_new_id_address(
|
||||
reader, id, ID_IS_LINKED(id), &ob->instance_collection->id);
|
||||
BLO_reportf_wrap(reports,
|
||||
RPT_INFO,
|
||||
TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
|
||||
|
@ -898,7 +899,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
ob->transflag &= ~OB_DUPLICOLLECTION;
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->proxy);
|
||||
BLO_read_id_address(reader, id, &ob->proxy);
|
||||
if (ob->proxy) {
|
||||
/* paranoia check, actually a proxy_from pointer should never be written... */
|
||||
if (!ID_IS_LINKED(ob->proxy)) {
|
||||
|
@ -923,10 +924,10 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
ob->proxy->proxy_from = ob;
|
||||
}
|
||||
}
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->proxy_group);
|
||||
BLO_read_id_address(reader, id, &ob->proxy_group);
|
||||
|
||||
void *poin = ob->data;
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->data);
|
||||
BLO_read_id_address(reader, id, &ob->data);
|
||||
|
||||
if (ob->data == nullptr && poin != nullptr) {
|
||||
ob->type = OB_EMPTY;
|
||||
|
@ -959,7 +960,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
reports->count.missing_obdata++;
|
||||
}
|
||||
for (int a = 0; a < ob->totcol; a++) {
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->mat[a]);
|
||||
BLO_read_id_address(reader, id, &ob->mat[a]);
|
||||
}
|
||||
|
||||
/* When the object is local and the data is library its possible
|
||||
|
@ -968,7 +969,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
BKE_object_materials_test(bmain, ob, (ID *)ob->data);
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->gpd);
|
||||
BLO_read_id_address(reader, id, &ob->gpd);
|
||||
|
||||
/* if id.us==0 a new base will be created later on */
|
||||
|
||||
|
@ -983,7 +984,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
|
||||
LISTBASE_FOREACH (PartEff *, paf, &ob->effect) {
|
||||
if (paf->type == EFF_PARTICLE) {
|
||||
BLO_read_id_address(reader, ob->id.lib, &paf->group);
|
||||
BLO_read_id_address(reader, id, &paf->group);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,7 +994,7 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
|
||||
if (fluidmd && fluidmd->fss) {
|
||||
/* XXX: deprecated - old animation system. */
|
||||
BLO_read_id_address(reader, ob->id.lib, &fluidmd->fss->ipo);
|
||||
BLO_read_id_address(reader, id, &fluidmd->fss->ipo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1019,9 +1020,9 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
|
||||
if (ob->soft) {
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->soft->collision_group);
|
||||
BLO_read_id_address(reader, id, &ob->soft->collision_group);
|
||||
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->soft->effector_weights->group);
|
||||
BLO_read_id_address(reader, id, &ob->soft->effector_weights->group);
|
||||
}
|
||||
|
||||
BKE_particle_system_blend_read_lib(reader, ob, &ob->id, &ob->particlesystem);
|
||||
|
@ -1030,8 +1031,8 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
BKE_shaderfx_blend_read_lib(reader, ob);
|
||||
|
||||
if (ob->rigidbody_constraint) {
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob1);
|
||||
BLO_read_id_address(reader, ob->id.lib, &ob->rigidbody_constraint->ob2);
|
||||
BLO_read_id_address(reader, id, &ob->rigidbody_constraint->ob1);
|
||||
BLO_read_id_address(reader, id, &ob->rigidbody_constraint->ob2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5648,7 +5649,7 @@ void BKE_object_modifiers_lib_link_common(void *userData,
|
|||
{
|
||||
BlendLibReader *reader = (BlendLibReader *)userData;
|
||||
|
||||
BLO_read_id_address(reader, ob->id.lib, idpoin);
|
||||
BLO_read_id_address(reader, &ob->id, idpoin);
|
||||
if (*idpoin != nullptr && (cb_flag & IDWALK_CB_USER) != 0) {
|
||||
id_us_plus_no_lib(*idpoin);
|
||||
}
|
||||
|
|
|
@ -1246,13 +1246,13 @@ void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Pain
|
|||
void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
|
||||
{
|
||||
if (p) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &p->brush);
|
||||
BLO_read_id_address(reader, &sce->id, &p->brush);
|
||||
for (int i = 0; i < p->tool_slots_len; i++) {
|
||||
if (p->tool_slots[i].brush != nullptr) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &p->tool_slots[i].brush);
|
||||
BLO_read_id_address(reader, &sce->id, &p->tool_slots[i].brush);
|
||||
}
|
||||
}
|
||||
BLO_read_id_address(reader, sce->id.lib, &p->palette);
|
||||
BLO_read_id_address(reader, &sce->id, &p->palette);
|
||||
p->paint_cursor = nullptr;
|
||||
|
||||
BKE_paint_runtime_init(sce->toolsettings, p);
|
||||
|
|
|
@ -365,10 +365,10 @@ static void particle_settings_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
void BKE_particle_partdeflect_blend_read_lib(BlendLibReader *reader, ID *id, PartDeflect *pd)
|
||||
{
|
||||
if (pd && pd->tex) {
|
||||
BLO_read_id_address(reader, id->lib, &pd->tex);
|
||||
BLO_read_id_address(reader, id, &pd->tex);
|
||||
}
|
||||
if (pd && pd->f_source) {
|
||||
BLO_read_id_address(reader, id->lib, &pd->f_source);
|
||||
BLO_read_id_address(reader, id, &pd->f_source);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -377,19 +377,19 @@ static void particle_settings_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
ParticleSettings *part = (ParticleSettings *)id;
|
||||
|
||||
/* XXX: deprecated - old animation system. */
|
||||
BLO_read_id_address(reader, part->id.lib, &part->ipo);
|
||||
BLO_read_id_address(reader, id, &part->ipo);
|
||||
|
||||
BLO_read_id_address(reader, part->id.lib, &part->instance_object);
|
||||
BLO_read_id_address(reader, part->id.lib, &part->instance_collection);
|
||||
BLO_read_id_address(reader, part->id.lib, &part->force_group);
|
||||
BLO_read_id_address(reader, part->id.lib, &part->bb_ob);
|
||||
BLO_read_id_address(reader, part->id.lib, &part->collision_group);
|
||||
BLO_read_id_address(reader, id, &part->instance_object);
|
||||
BLO_read_id_address(reader, id, &part->instance_collection);
|
||||
BLO_read_id_address(reader, id, &part->force_group);
|
||||
BLO_read_id_address(reader, id, &part->bb_ob);
|
||||
BLO_read_id_address(reader, id, &part->collision_group);
|
||||
|
||||
BKE_particle_partdeflect_blend_read_lib(reader, &part->id, part->pd);
|
||||
BKE_particle_partdeflect_blend_read_lib(reader, &part->id, part->pd2);
|
||||
BKE_particle_partdeflect_blend_read_lib(reader, id, part->pd);
|
||||
BKE_particle_partdeflect_blend_read_lib(reader, id, part->pd2);
|
||||
|
||||
if (part->effector_weights) {
|
||||
BLO_read_id_address(reader, part->id.lib, &part->effector_weights->group);
|
||||
BLO_read_id_address(reader, id, &part->effector_weights->group);
|
||||
}
|
||||
else {
|
||||
part->effector_weights = BKE_effector_add_weights(part->force_group);
|
||||
|
@ -397,7 +397,7 @@ static void particle_settings_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
|
||||
if (part->instance_weights.first && part->instance_collection) {
|
||||
LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) {
|
||||
BLO_read_id_address(reader, part->id.lib, &dw->ob);
|
||||
BLO_read_id_address(reader, id, &dw->ob);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -411,12 +411,12 @@ static void particle_settings_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
case eBoidRuleType_Goal:
|
||||
case eBoidRuleType_Avoid: {
|
||||
BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid *)rule;
|
||||
BLO_read_id_address(reader, part->id.lib, &brga->ob);
|
||||
BLO_read_id_address(reader, id, &brga->ob);
|
||||
break;
|
||||
}
|
||||
case eBoidRuleType_FollowLeader: {
|
||||
BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader *)rule;
|
||||
BLO_read_id_address(reader, part->id.lib, &brfl->ob);
|
||||
BLO_read_id_address(reader, id, &brfl->ob);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -427,8 +427,8 @@ static void particle_settings_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
for (int a = 0; a < MAX_MTEX; a++) {
|
||||
MTex *mtex = part->mtex[a];
|
||||
if (mtex) {
|
||||
BLO_read_id_address(reader, part->id.lib, &mtex->tex);
|
||||
BLO_read_id_address(reader, part->id.lib, &mtex->object);
|
||||
BLO_read_id_address(reader, id, &mtex->tex);
|
||||
BLO_read_id_address(reader, id, &mtex->object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5474,21 +5474,21 @@ void BKE_particle_system_blend_read_lib(BlendLibReader *reader,
|
|||
{
|
||||
LISTBASE_FOREACH_MUTABLE (ParticleSystem *, psys, particles) {
|
||||
|
||||
BLO_read_id_address(reader, id->lib, &psys->part);
|
||||
BLO_read_id_address(reader, id, &psys->part);
|
||||
if (psys->part) {
|
||||
LISTBASE_FOREACH (ParticleTarget *, pt, &psys->targets) {
|
||||
BLO_read_id_address(reader, id->lib, &pt->ob);
|
||||
BLO_read_id_address(reader, id, &pt->ob);
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, id->lib, &psys->parent);
|
||||
BLO_read_id_address(reader, id->lib, &psys->target_ob);
|
||||
BLO_read_id_address(reader, id, &psys->parent);
|
||||
BLO_read_id_address(reader, id, &psys->target_ob);
|
||||
|
||||
if (psys->clmd) {
|
||||
/* XXX(@ideasman42): from reading existing code this seems correct but intended usage
|
||||
* of point-cache with cloth should be added in #ParticleSystem. */
|
||||
psys->clmd->point_cache = psys->pointcache;
|
||||
psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = nullptr;
|
||||
BLO_read_id_address(reader, id->lib, &psys->clmd->coll_parms->group);
|
||||
BLO_read_id_address(reader, id, &psys->clmd->coll_parms->group);
|
||||
psys->clmd->modifier.error = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ static void pointcloud_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
PointCloud *pointcloud = (PointCloud *)id;
|
||||
for (int a = 0; a < pointcloud->totcol; a++) {
|
||||
BLO_read_id_address(reader, pointcloud->id.lib, &pointcloud->mat[a]);
|
||||
BLO_read_id_address(reader, id, &pointcloud->mat[a]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -487,6 +487,7 @@ enum eSceneForeachUndoPreserveProcess {
|
|||
};
|
||||
|
||||
static void scene_foreach_toolsettings_id_pointer_process(
|
||||
Scene *scene,
|
||||
ID **id_p,
|
||||
const eSceneForeachUndoPreserveProcess action,
|
||||
BlendLibReader *reader,
|
||||
|
@ -498,9 +499,9 @@ static void scene_foreach_toolsettings_id_pointer_process(
|
|||
ID *id_old = *id_old_p;
|
||||
/* Old data has not been remapped to new values of the pointers, if we want to keep the old
|
||||
* pointer here we need its new address. */
|
||||
ID *id_old_new = id_old != nullptr ?
|
||||
BLO_read_get_new_id_address(reader, id_old->lib, id_old) :
|
||||
nullptr;
|
||||
ID *id_old_new = id_old != nullptr ? BLO_read_get_new_id_address(
|
||||
reader, &scene->id, ID_IS_LINKED(scene), id_old) :
|
||||
nullptr;
|
||||
if (id_old_new != nullptr) {
|
||||
BLI_assert(ELEM(id_old, id_old_new, id_old_new->orig_id));
|
||||
*id_old_p = id_old_new;
|
||||
|
@ -526,11 +527,11 @@ static void scene_foreach_toolsettings_id_pointer_process(
|
|||
* `scene_foreach_paint`) are also used by `scene_undo_preserve`, where `LibraryForeachIDData
|
||||
* *data` is nullptr. */
|
||||
#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER( \
|
||||
__data, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \
|
||||
__data, __scene, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \
|
||||
{ \
|
||||
if (__do_undo_restore) { \
|
||||
scene_foreach_toolsettings_id_pointer_process( \
|
||||
(ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \
|
||||
__scene, (ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \
|
||||
} \
|
||||
else { \
|
||||
BLI_assert((__data) != nullptr); \
|
||||
|
@ -553,12 +554,14 @@ static void scene_foreach_toolsettings_id_pointer_process(
|
|||
(void)0
|
||||
|
||||
static void scene_foreach_paint(LibraryForeachIDData *data,
|
||||
Scene *scene,
|
||||
Paint *paint,
|
||||
const bool do_undo_restore,
|
||||
BlendLibReader *reader,
|
||||
Paint *paint_old)
|
||||
{
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
paint->brush,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_RESTORE,
|
||||
|
@ -577,6 +580,7 @@ static void scene_foreach_paint(LibraryForeachIDData *data,
|
|||
Brush *brush_tmp = nullptr;
|
||||
Brush **brush_p = i < paint->tool_slots_len ? &paint->tool_slots[i].brush : &brush_tmp;
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
*brush_p,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_RESTORE,
|
||||
|
@ -585,6 +589,7 @@ static void scene_foreach_paint(LibraryForeachIDData *data,
|
|||
IDWALK_CB_USER);
|
||||
}
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
paint->palette,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_RESTORE,
|
||||
|
@ -594,12 +599,14 @@ static void scene_foreach_paint(LibraryForeachIDData *data,
|
|||
}
|
||||
|
||||
static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
||||
Scene *scene,
|
||||
ToolSettings *toolsett,
|
||||
const bool do_undo_restore,
|
||||
BlendLibReader *reader,
|
||||
ToolSettings *toolsett_old)
|
||||
{
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->particle.scene,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_NO_RESTORE,
|
||||
|
@ -607,6 +614,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
toolsett_old->particle.scene,
|
||||
IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->particle.object,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_NO_RESTORE,
|
||||
|
@ -614,6 +622,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
toolsett_old->particle.object,
|
||||
IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->particle.shape_object,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_NO_RESTORE,
|
||||
|
@ -621,9 +630,14 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
toolsett_old->particle.shape_object,
|
||||
IDWALK_CB_NOP);
|
||||
|
||||
scene_foreach_paint(
|
||||
data, &toolsett->imapaint.paint, do_undo_restore, reader, &toolsett_old->imapaint.paint);
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->imapaint.paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
&toolsett_old->imapaint.paint);
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->imapaint.stencil,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_RESTORE,
|
||||
|
@ -631,6 +645,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
toolsett_old->imapaint.stencil,
|
||||
IDWALK_CB_USER);
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->imapaint.clone,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_RESTORE,
|
||||
|
@ -638,6 +653,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
toolsett_old->imapaint.clone,
|
||||
IDWALK_CB_USER);
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->imapaint.canvas,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_RESTORE,
|
||||
|
@ -650,6 +666,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->vpaint->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -660,6 +677,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->wpaint->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -670,11 +688,13 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->sculpt->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
&toolsett_old->sculpt->paint));
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->sculpt->gravity_object,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_NO_RESTORE,
|
||||
|
@ -687,6 +707,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->uvsculpt->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -697,6 +718,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->gp_paint->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -707,6 +729,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->gp_vertexpaint->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -717,6 +740,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->gp_sculptpaint->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -727,6 +751,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->gp_weightpaint->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -737,6 +762,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data,
|
||||
scene,
|
||||
&toolsett->curves_sculpt->paint,
|
||||
do_undo_restore,
|
||||
reader,
|
||||
|
@ -744,6 +770,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
}
|
||||
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
|
||||
scene,
|
||||
toolsett->gp_sculpt.guide.reference_object,
|
||||
do_undo_restore,
|
||||
SCENE_FOREACH_UNDO_NO_RESTORE,
|
||||
|
@ -876,7 +903,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
|
|||
ToolSettings *toolsett = scene->toolsettings;
|
||||
if (toolsett) {
|
||||
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
|
||||
data, scene_foreach_toolsettings(data, toolsett, false, nullptr, toolsett));
|
||||
data, scene_foreach_toolsettings(data, scene, toolsett, false, nullptr, toolsett));
|
||||
}
|
||||
|
||||
if (scene->rigidbody_world) {
|
||||
|
@ -1487,10 +1514,10 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
|
||||
BKE_keyingsets_blend_read_lib(reader, &sce->id, &sce->keyingsets);
|
||||
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->camera);
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->world);
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->set);
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->gpd);
|
||||
BLO_read_id_address(reader, id, &sce->camera);
|
||||
BLO_read_id_address(reader, id, &sce->world);
|
||||
BLO_read_id_address(reader, id, &sce->set);
|
||||
BLO_read_id_address(reader, id, &sce->gpd);
|
||||
|
||||
BKE_paint_blend_read_lib(reader, sce, &sce->toolsettings->imapaint.paint);
|
||||
if (sce->toolsettings->sculpt) {
|
||||
|
@ -1522,27 +1549,27 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
|
||||
if (sce->toolsettings->sculpt) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->sculpt->gravity_object);
|
||||
BLO_read_id_address(reader, id, &sce->toolsettings->sculpt->gravity_object);
|
||||
}
|
||||
|
||||
if (sce->toolsettings->imapaint.stencil) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.stencil);
|
||||
BLO_read_id_address(reader, id, &sce->toolsettings->imapaint.stencil);
|
||||
}
|
||||
|
||||
if (sce->toolsettings->imapaint.clone) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.clone);
|
||||
BLO_read_id_address(reader, id, &sce->toolsettings->imapaint.clone);
|
||||
}
|
||||
|
||||
if (sce->toolsettings->imapaint.canvas) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->imapaint.canvas);
|
||||
BLO_read_id_address(reader, id, &sce->toolsettings->imapaint.canvas);
|
||||
}
|
||||
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->particle.shape_object);
|
||||
BLO_read_id_address(reader, id, &sce->toolsettings->particle.shape_object);
|
||||
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->toolsettings->gp_sculpt.guide.reference_object);
|
||||
BLO_read_id_address(reader, id, &sce->toolsettings->gp_sculpt.guide.reference_object);
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &base_legacy->object);
|
||||
BLO_read_id_address(reader, id, &base_legacy->object);
|
||||
|
||||
if (base_legacy->object == nullptr) {
|
||||
BLO_reportf_wrap(BLO_read_lib_reports(reader),
|
||||
|
@ -1562,10 +1589,10 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
|
||||
IDP_BlendReadLib(reader, sce->id.lib, marker->prop);
|
||||
IDP_BlendReadLib(reader, id, marker->prop);
|
||||
|
||||
if (marker->camera) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &marker->camera);
|
||||
BLO_read_id_address(reader, id, &marker->camera);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1573,13 +1600,13 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
if (sce->rigidbody_world) {
|
||||
RigidBodyWorld *rbw = sce->rigidbody_world;
|
||||
if (rbw->group) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &rbw->group);
|
||||
BLO_read_id_address(reader, id, &rbw->group);
|
||||
}
|
||||
if (rbw->constraints) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &rbw->constraints);
|
||||
BLO_read_id_address(reader, id, &rbw->constraints);
|
||||
}
|
||||
if (rbw->effector_weights) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &rbw->effector_weights->group);
|
||||
BLO_read_id_address(reader, id, &rbw->effector_weights->group);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1588,30 +1615,30 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH (SceneRenderLayer *, srl, &sce->r.layers) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &srl->mat_override);
|
||||
BLO_read_id_address(reader, id, &srl->mat_override);
|
||||
LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &srl->freestyleConfig.modules) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &fmc->script);
|
||||
BLO_read_id_address(reader, id, &fmc->script);
|
||||
}
|
||||
LISTBASE_FOREACH (FreestyleLineSet *, fls, &srl->freestyleConfig.linesets) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &fls->linestyle);
|
||||
BLO_read_id_address(reader, sce->id.lib, &fls->group);
|
||||
BLO_read_id_address(reader, id, &fls->linestyle);
|
||||
BLO_read_id_address(reader, id, &fls->group);
|
||||
}
|
||||
}
|
||||
/* Motion Tracking */
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->clip);
|
||||
BLO_read_id_address(reader, id, &sce->clip);
|
||||
|
||||
#ifdef USE_COLLECTION_COMPAT_28
|
||||
if (sce->collection) {
|
||||
BKE_collection_compat_blend_read_lib(reader, sce->id.lib, sce->collection);
|
||||
BKE_collection_compat_blend_read_lib(reader, id, sce->collection);
|
||||
}
|
||||
#endif
|
||||
|
||||
LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
|
||||
BKE_view_layer_blend_read_lib(reader, sce->id.lib, view_layer);
|
||||
BKE_view_layer_blend_read_lib(reader, id, view_layer);
|
||||
}
|
||||
|
||||
if (sce->r.bake.cage_object) {
|
||||
BLO_read_id_address(reader, sce->id.lib, &sce->r.bake.cage_object);
|
||||
BLO_read_id_address(reader, id, &sce->r.bake.cage_object);
|
||||
}
|
||||
|
||||
#ifdef USE_SETSCENE_CHECK
|
||||
|
@ -1714,7 +1741,7 @@ static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
|
|||
* palettes), and counteract the swap of the whole ToolSettings structs below for the others
|
||||
* (like object ones). */
|
||||
scene_foreach_toolsettings(
|
||||
nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings);
|
||||
nullptr, scene_new, scene_new->toolsettings, true, reader, scene_old->toolsettings);
|
||||
std::swap(*scene_old->toolsettings, *scene_new->toolsettings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -368,7 +368,7 @@ static void screen_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
bScreen *screen = (bScreen *)id;
|
||||
/* deprecated, but needed for versioning (will be NULL'ed then) */
|
||||
BLO_read_id_address(reader, screen->id.lib, &screen->scene);
|
||||
BLO_read_id_address(reader, id, &screen->scene);
|
||||
|
||||
screen->animtimer = NULL; /* saved in rare cases */
|
||||
screen->tool_tip = NULL;
|
||||
|
@ -1483,7 +1483,7 @@ bool BKE_screen_area_map_blend_read_data(BlendDataReader *reader, ScrAreaMap *ar
|
|||
|
||||
void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrArea *area)
|
||||
{
|
||||
BLO_read_id_address(reader, parent_id->lib, &area->full);
|
||||
BLO_read_id_address(reader, parent_id, &area->full);
|
||||
|
||||
memset(&area->runtime, 0x0, sizeof(area->runtime));
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ static void sound_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
bSound *sound = (bSound *)id;
|
||||
/* XXX: deprecated - old animation system. */
|
||||
BLO_read_id_address(reader, sound->id.lib, &sound->ipo);
|
||||
BLO_read_id_address(reader, id, &sound->ipo);
|
||||
}
|
||||
|
||||
static void sound_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
@ -819,6 +819,11 @@ void BKE_sound_set_scene_sound_pitch(void *handle, float pitch, char animated)
|
|||
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PITCH, sound_cfra, &pitch, animated);
|
||||
}
|
||||
|
||||
void BKE_sound_set_scene_sound_pitch_at_frame(void *handle, int frame, float pitch, char animated)
|
||||
{
|
||||
AUD_SequenceEntry_setAnimationData(handle, AUD_AP_PITCH, frame, &pitch, animated);
|
||||
}
|
||||
|
||||
void BKE_sound_set_scene_sound_pitch_constant_range(void *handle,
|
||||
int frame_start,
|
||||
int frame_end,
|
||||
|
@ -1379,6 +1384,12 @@ void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle),
|
|||
char UNUSED(animated))
|
||||
{
|
||||
}
|
||||
void BKE_sound_set_scene_sound_pitch_at_frame(void *UNUSED(handle),
|
||||
int UNUSED(frame),
|
||||
float UNUSED(pitch),
|
||||
char UNUSED(animated))
|
||||
{
|
||||
}
|
||||
void BKE_sound_set_scene_sound_pitch_constant_range(void *UNUSED(handle),
|
||||
int UNUSED(frame_start),
|
||||
int UNUSED(frame_end),
|
||||
|
|
|
@ -67,7 +67,7 @@ static void speaker_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void speaker_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
Speaker *spk = (Speaker *)id;
|
||||
BLO_read_id_address(reader, spk->id.lib, &spk->sound);
|
||||
BLO_read_id_address(reader, id, &spk->sound);
|
||||
}
|
||||
|
||||
static void speaker_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -194,8 +194,8 @@ static void texture_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void texture_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
Tex *tex = (Tex *)id;
|
||||
BLO_read_id_address(reader, tex->id.lib, &tex->ima);
|
||||
BLO_read_id_address(reader, tex->id.lib, &tex->ipo); /* XXX deprecated - old animation system */
|
||||
BLO_read_id_address(reader, id, &tex->ima);
|
||||
BLO_read_id_address(reader, id, &tex->ipo); /* XXX deprecated - old animation system */
|
||||
}
|
||||
|
||||
static void texture_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -103,13 +103,13 @@ void BKE_viewer_path_blend_read_data(struct BlendDataReader *reader, ViewerPath
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_viewer_path_blend_read_lib(BlendLibReader *reader, Library *lib, ViewerPath *viewer_path)
|
||||
void BKE_viewer_path_blend_read_lib(BlendLibReader *reader, ID *self_id, ViewerPath *viewer_path)
|
||||
{
|
||||
LISTBASE_FOREACH (ViewerPathElem *, elem, &viewer_path->path) {
|
||||
switch (ViewerPathElemType(elem->type)) {
|
||||
case VIEWER_PATH_ELEM_TYPE_ID: {
|
||||
auto *typed_elem = reinterpret_cast<IDViewerPathElem *>(elem);
|
||||
BLO_read_id_address(reader, lib, &typed_elem->id);
|
||||
BLO_read_id_address(reader, self_id, &typed_elem->id);
|
||||
break;
|
||||
}
|
||||
case VIEWER_PATH_ELEM_TYPE_MODIFIER:
|
||||
|
|
|
@ -631,7 +631,7 @@ static void volume_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
BKE_volume_init_grids(volume);
|
||||
|
||||
for (int a = 0; a < volume->totcol; a++) {
|
||||
BLO_read_id_address(reader, volume->id.lib, &volume->mat[a]);
|
||||
BLO_read_id_address(reader, id, &volume->mat[a]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
workspace->pin_scene = nullptr;
|
||||
}
|
||||
else {
|
||||
BLO_read_id_address(reader, nullptr, &workspace->pin_scene);
|
||||
BLO_read_id_address(reader, id, &workspace->pin_scene);
|
||||
}
|
||||
|
||||
/* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */
|
||||
|
@ -155,7 +155,7 @@ static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) {
|
||||
BLO_read_id_address(reader, id->lib, &layout->screen);
|
||||
BLO_read_id_address(reader, id, &layout->screen);
|
||||
|
||||
if (layout->screen) {
|
||||
if (ID_IS_LINKED(id)) {
|
||||
|
@ -173,7 +173,7 @@ static void workspace_blend_read_lib(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
}
|
||||
|
||||
BKE_viewer_path_blend_read_lib(reader, id->lib, &workspace->viewer_path);
|
||||
BKE_viewer_path_blend_read_lib(reader, id, &workspace->viewer_path);
|
||||
}
|
||||
|
||||
static void workspace_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -178,7 +178,7 @@ static void world_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
static void world_blend_read_lib(BlendLibReader *reader, ID *id)
|
||||
{
|
||||
World *wrld = (World *)id;
|
||||
BLO_read_id_address(reader, wrld->id.lib, &wrld->ipo); /* XXX deprecated, old animation system */
|
||||
BLO_read_id_address(reader, id, &wrld->ipo); /* XXX deprecated, old animation system */
|
||||
}
|
||||
|
||||
static void world_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
|
|
|
@ -41,6 +41,9 @@ bool BLI_path_name_at_index(const char *__restrict path,
|
|||
*/
|
||||
bool BLI_path_is_unc(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
|
||||
|
||||
bool BLI_path_is_win32_drive(const char *path);
|
||||
bool BLI_path_is_win32_drive_with_slash(const char *path);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -153,22 +156,27 @@ void BLI_path_to_display_name(char *display_name, int display_name_maxncpy, cons
|
|||
* such as `//../parent` or `../parent`.
|
||||
*
|
||||
* \param path: The path to a file or directory which can be absolute or relative.
|
||||
* \return the length of `path`.
|
||||
*/
|
||||
void BLI_path_normalize(char *path) ATTR_NONNULL(1);
|
||||
int BLI_path_normalize(char *path) ATTR_NONNULL(1);
|
||||
|
||||
/**
|
||||
* A version of #BLI_path_normalize without special handling of `//` blend file relative prefix.
|
||||
*
|
||||
* \note On UNIX `//path` is a valid path which gets normalized to `/path`.
|
||||
*
|
||||
* \return the length of `path`.
|
||||
*/
|
||||
void BLI_path_normalize_native(char *path) ATTR_NONNULL(1);
|
||||
int BLI_path_normalize_native(char *path) ATTR_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Cleanup file-path ensuring a trailing slash.
|
||||
*
|
||||
* \note Same as #BLI_path_normalize but adds a trailing slash.
|
||||
*
|
||||
* \return the length of `dir`.
|
||||
*/
|
||||
void BLI_path_normalize_dir(char *dir, size_t dir_maxncpy) ATTR_NONNULL(1);
|
||||
int BLI_path_normalize_dir(char *dir, size_t dir_maxncpy) ATTR_NONNULL(1);
|
||||
|
||||
#if defined(WIN32)
|
||||
void BLI_path_normalize_unc_16(wchar_t *path_16);
|
||||
|
@ -177,6 +185,28 @@ void BLI_path_normalize_unc(char *path, int path_maxncpy);
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Path Canonicalize
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Convert `path` to a canonical representation.
|
||||
* This is intended for system paths (passed in as command-line arguments of via scripts)
|
||||
* which are valid in that they resolve to a file/directory and but could be `CWD` relative or
|
||||
* contain redundant slashes that cause absolute/relative conversion to fail.
|
||||
* (specifically the "//" prefix used by Blender).
|
||||
*
|
||||
* Perform the following operations:
|
||||
*
|
||||
* - Make absolute (relative to the current working directory).
|
||||
* - Convert slash direction (WIN32 only, as other systems may use back-slashes in filenames).
|
||||
* - Normalize redundant slashes.
|
||||
* - Strip trailing slashes.
|
||||
*/
|
||||
int BLI_path_canonicalize_native(char *path, int path_maxncpy);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Path FileName Manipulation
|
||||
* \{ */
|
||||
|
@ -219,7 +249,14 @@ const char *BLI_path_slash_find(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUS
|
|||
const char *BLI_path_slash_rfind(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
|
||||
/**
|
||||
* Appends a slash to path if there isn't one there already.
|
||||
* Returns the new length of the path.
|
||||
* \param path_len: The length of `path`.
|
||||
* \return the new length of the path.
|
||||
*/
|
||||
int BLI_path_slash_ensure_ex(char *path, size_t path_maxncpy, const size_t path_len)
|
||||
ATTR_NONNULL(1);
|
||||
/**
|
||||
* Appends a slash to path if there isn't one there already.
|
||||
* \return the new length of the path.
|
||||
*/
|
||||
int BLI_path_slash_ensure(char *path, size_t path_maxncpy) ATTR_NONNULL(1);
|
||||
/**
|
||||
|
|
|
@ -43,6 +43,7 @@ static int BLI_path_unc_prefix_len(const char *path);
|
|||
|
||||
#ifdef WIN32
|
||||
static bool BLI_path_is_abs_win32(const char *path);
|
||||
static int BLI_path_win32_prefix_len(const char *path);
|
||||
#endif /* WIN32 */
|
||||
|
||||
/**
|
||||
|
@ -135,7 +136,11 @@ void BLI_path_sequence_encode(char *path,
|
|||
BLI_snprintf(path, path_maxncpy, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
|
||||
}
|
||||
|
||||
static void path_normalize_impl(char *path, bool check_blend_relative_prefix)
|
||||
/**
|
||||
* Implementation for #BLI_path_normalize & #BLI_path_normalize_native.
|
||||
* \return The path length.
|
||||
*/
|
||||
static int path_normalize_impl(char *path, bool check_blend_relative_prefix)
|
||||
{
|
||||
const char *path_orig = path;
|
||||
int path_len = strlen(path);
|
||||
|
@ -173,7 +178,7 @@ static void path_normalize_impl(char *path, bool check_blend_relative_prefix)
|
|||
path += path_unc_len;
|
||||
path_len -= path_unc_len;
|
||||
}
|
||||
else if (isalpha(path[0]) && (path[1] == ':')) {
|
||||
else if (BLI_path_is_win32_drive(path)) { /* Check for `C:` (2 characters only). */
|
||||
path += 2;
|
||||
path_len -= 2;
|
||||
}
|
||||
|
@ -355,27 +360,52 @@ static void path_normalize_impl(char *path, bool check_blend_relative_prefix)
|
|||
BLI_assert(strlen(path) == path_len);
|
||||
|
||||
#undef IS_PARENT_DIR
|
||||
|
||||
return (path - path_orig) + path_len;
|
||||
}
|
||||
|
||||
void BLI_path_normalize(char *path)
|
||||
int BLI_path_normalize(char *path)
|
||||
{
|
||||
path_normalize_impl(path, true);
|
||||
return path_normalize_impl(path, true);
|
||||
}
|
||||
|
||||
void BLI_path_normalize_native(char *path)
|
||||
int BLI_path_normalize_native(char *path)
|
||||
{
|
||||
path_normalize_impl(path, false);
|
||||
return path_normalize_impl(path, false);
|
||||
}
|
||||
|
||||
void BLI_path_normalize_dir(char *dir, size_t dir_maxncpy)
|
||||
int BLI_path_normalize_dir(char *dir, size_t dir_maxncpy)
|
||||
{
|
||||
/* Would just create an unexpected "/" path, just early exit entirely. */
|
||||
if (dir[0] == '\0') {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLI_path_normalize(dir);
|
||||
BLI_path_slash_ensure(dir, dir_maxncpy);
|
||||
int dir_len = BLI_path_normalize(dir);
|
||||
return BLI_path_slash_ensure_ex(dir, dir_maxncpy, dir_len);
|
||||
}
|
||||
|
||||
int BLI_path_canonicalize_native(char *path, int path_maxncpy)
|
||||
{
|
||||
BLI_path_abs_from_cwd(path, path_maxncpy);
|
||||
/* As these are system level paths, only convert slashes
|
||||
* if the alternate direction is accepted as a slash. */
|
||||
if (BLI_path_slash_is_native_compat(ALTSEP)) {
|
||||
BLI_path_slash_native(path);
|
||||
}
|
||||
int path_len = BLI_path_normalize_native(path);
|
||||
/* Strip trailing slash but don't strip `/` away to nothing. */
|
||||
if (path_len > 1 && path[path_len - 1] == SEP) {
|
||||
#ifdef WIN32
|
||||
/* Don't strip `C:\` -> `C:` as this is no longer a valid directory. */
|
||||
if (BLI_path_win32_prefix_len(path) + 1 < path_len)
|
||||
#endif
|
||||
{
|
||||
path_len -= 1;
|
||||
path[path_len] = '\0';
|
||||
}
|
||||
}
|
||||
return path_len;
|
||||
}
|
||||
|
||||
bool BLI_path_make_safe_filename_ex(char *fname, bool allow_tokens)
|
||||
|
@ -523,6 +553,26 @@ static int BLI_path_unc_prefix_len(const char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
static int BLI_path_win32_prefix_len(const char *path)
|
||||
{
|
||||
if (BLI_path_is_win32_drive(path)) {
|
||||
return 2;
|
||||
}
|
||||
return BLI_path_unc_prefix_len(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool BLI_path_is_win32_drive(const char *path)
|
||||
{
|
||||
return isalpha(path[0]) && (path[1] == ':');
|
||||
}
|
||||
|
||||
bool BLI_path_is_win32_drive_with_slash(const char *path)
|
||||
{
|
||||
return isalpha(path[0]) && (path[1] == ':') && ELEM(path[2], '\\', '/');
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
/**
|
||||
|
@ -535,7 +585,7 @@ static int BLI_path_unc_prefix_len(const char *path)
|
|||
*/
|
||||
static bool BLI_path_is_abs_win32(const char *path)
|
||||
{
|
||||
return (path[1] == ':' && ELEM(path[2], '\\', '/')) || BLI_path_is_unc(path);
|
||||
return BLI_path_is_win32_drive_with_slash(path) || BLI_path_is_unc(path);
|
||||
}
|
||||
|
||||
static wchar_t *next_slash(wchar_t *path)
|
||||
|
@ -1082,7 +1132,7 @@ bool BLI_path_abs(char path[FILE_MAX], const char *basepath)
|
|||
* Add a `/` prefix and lowercase the drive-letter, remove the `:`.
|
||||
* `C:\foo.JPG` -> `/c/foo.JPG` */
|
||||
|
||||
if (isalpha(tmp[0]) && (tmp[1] == ':') && ELEM(tmp[2], '\\', '/')) {
|
||||
if (BLI_path_is_win32_drive_with_slash(tmp)) {
|
||||
tmp[1] = tolower(tmp[0]); /* Replace `:` with drive-letter. */
|
||||
tmp[0] = '/';
|
||||
/* `\` the slash will be converted later. */
|
||||
|
@ -1602,35 +1652,20 @@ const char *BLI_path_extension(const char *filepath)
|
|||
|
||||
size_t BLI_path_append(char *__restrict dst, const size_t dst_maxncpy, const char *__restrict file)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(dst, dst_maxncpy);
|
||||
|
||||
size_t dirlen = BLI_strnlen(dst, dst_maxncpy);
|
||||
/* Inline #BLI_path_slash_ensure. */
|
||||
if ((dirlen > 0) && !BLI_path_slash_is_native_compat(dst[dirlen - 1])) {
|
||||
dst[dirlen++] = SEP;
|
||||
dst[dirlen] = '\0';
|
||||
/* Slash ensure uses #BLI_string_debug_size */
|
||||
int dst_len = BLI_path_slash_ensure(dst, dst_maxncpy);
|
||||
if (dst_len + 1 < dst_maxncpy) {
|
||||
dst_len += BLI_strncpy_rlen(dst + dst_len, file, dst_maxncpy - dst_len);
|
||||
}
|
||||
|
||||
if (dirlen >= dst_maxncpy) {
|
||||
return dirlen; /* Fills the path. */
|
||||
}
|
||||
|
||||
return dirlen + BLI_strncpy_rlen(dst + dirlen, file, dst_maxncpy - dirlen);
|
||||
return dst_len;
|
||||
}
|
||||
|
||||
size_t BLI_path_append_dir(char *__restrict dst,
|
||||
const size_t dst_maxncpy,
|
||||
const char *__restrict dir)
|
||||
{
|
||||
size_t dirlen = BLI_path_append(dst, dst_maxncpy, dir);
|
||||
if (dirlen + 1 < dst_maxncpy) {
|
||||
/* Inline #BLI_path_slash_ensure. */
|
||||
if ((dirlen > 0) && !BLI_path_slash_is_native_compat(dst[dirlen - 1])) {
|
||||
dst[dirlen++] = SEP;
|
||||
dst[dirlen] = '\0';
|
||||
}
|
||||
}
|
||||
return dirlen;
|
||||
size_t dst_len = BLI_path_append(dst, dst_maxncpy, dir);
|
||||
return BLI_path_slash_ensure_ex(dst, dst_maxncpy, dst_len);
|
||||
}
|
||||
|
||||
size_t BLI_path_join_array(char *__restrict dst,
|
||||
|
@ -1885,21 +1920,24 @@ const char *BLI_path_slash_rfind(const char *path)
|
|||
return (lfslash > lbslash) ? lfslash : lbslash;
|
||||
}
|
||||
|
||||
int BLI_path_slash_ensure(char *path, size_t path_maxncpy)
|
||||
int BLI_path_slash_ensure_ex(char *path, size_t path_maxncpy, size_t path_len)
|
||||
{
|
||||
BLI_string_debug_size_after_nil(path, path_maxncpy);
|
||||
|
||||
int len = strlen(path);
|
||||
BLI_assert(len < path_maxncpy);
|
||||
if (len == 0 || !BLI_path_slash_is_native_compat(path[len - 1])) {
|
||||
BLI_assert(strlen(path) == path_len);
|
||||
BLI_assert(path_len < path_maxncpy);
|
||||
if (path_len == 0 || !BLI_path_slash_is_native_compat(path[path_len - 1])) {
|
||||
/* Avoid unlikely buffer overflow. */
|
||||
if (len + 1 < path_maxncpy) {
|
||||
path[len] = SEP;
|
||||
path[len + 1] = '\0';
|
||||
return len + 1;
|
||||
if (path_len + 1 < path_maxncpy) {
|
||||
path[path_len++] = SEP;
|
||||
path[path_len] = '\0';
|
||||
}
|
||||
}
|
||||
return len;
|
||||
return path_len;
|
||||
}
|
||||
|
||||
int BLI_path_slash_ensure(char *path, size_t path_maxncpy)
|
||||
{
|
||||
return BLI_path_slash_ensure_ex(path, path_maxncpy, strlen(path));
|
||||
}
|
||||
|
||||
void BLI_path_slash_rstrip(char *path)
|
||||
|
@ -1947,6 +1985,10 @@ int BLI_path_cmp_normalized(const char *p1, const char *p2)
|
|||
BLI_path_slash_native(norm_p1);
|
||||
BLI_path_slash_native(norm_p2);
|
||||
|
||||
/* One of the paths ending with a slash does not make them different, strip both. */
|
||||
BLI_path_slash_rstrip(norm_p1);
|
||||
BLI_path_slash_rstrip(norm_p2);
|
||||
|
||||
BLI_path_normalize(norm_p1);
|
||||
BLI_path_normalize(norm_p2);
|
||||
|
||||
|
|
|
@ -48,11 +48,12 @@ static char *str_replace_char_strdup(const char *str, char src, char dst)
|
|||
if (SEP == '\\') { \
|
||||
str_replace_char_with_relative_exception(path, '/', '\\'); \
|
||||
} \
|
||||
BLI_path_normalize(path); \
|
||||
const int path_len_test = BLI_path_normalize(path); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(path, '\\', '/'); \
|
||||
} \
|
||||
EXPECT_STREQ(path, output_expect); \
|
||||
EXPECT_EQ(path_len_test, strlen(path)); \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
|
@ -155,6 +156,26 @@ TEST(path_util, Normalize_UnbalancedRelativeTrailing)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tests for: #BLI_path_cmp_normalized
|
||||
*
|
||||
* \note #BLI_path_normalize tests handle most of the corner cases.
|
||||
* \{ */
|
||||
|
||||
TEST(path_util, CompareNormalized)
|
||||
{
|
||||
/* Trailing slash should not matter. */
|
||||
EXPECT_EQ(BLI_path_cmp_normalized("/tmp/", "/tmp"), 0);
|
||||
/* Slash direction should not matter. */
|
||||
EXPECT_EQ(BLI_path_cmp_normalized("c:\\tmp\\", "c:/tmp/"), 0);
|
||||
/* Empty paths should be supported. */
|
||||
EXPECT_EQ(BLI_path_cmp_normalized("", ""), 0);
|
||||
|
||||
EXPECT_NE(BLI_path_cmp_normalized("A", "B"), 0);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tests for: #BLI_path_parent_dir
|
||||
* \{ */
|
||||
|
@ -560,6 +581,47 @@ TEST(path_util, JoinRelativePrefix)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tests for: #BLI_path_append
|
||||
* \{ */
|
||||
|
||||
/* For systems with `/` path separator (non WIN32). */
|
||||
#define APPEND(str_expect, size, path, filename) \
|
||||
{ \
|
||||
const char *expect = str_expect; \
|
||||
char result[(size) + 1024] = path; \
|
||||
char filename_native[] = filename; \
|
||||
/* Check we don't write past the last byte. */ \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(filename_native, '/', '\\'); \
|
||||
BLI_str_replace_char(result, '/', '\\'); \
|
||||
} \
|
||||
BLI_path_append(result, size, filename_native); \
|
||||
if (SEP == '\\') { \
|
||||
BLI_str_replace_char(result, '\\', '/'); \
|
||||
} \
|
||||
EXPECT_STREQ(result, expect); \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
TEST(path_util, AppendFile)
|
||||
{
|
||||
APPEND("a/b", 100, "a", "b");
|
||||
APPEND("a/b", 100, "a/", "b");
|
||||
}
|
||||
|
||||
TEST(path_util, AppendFile_Truncate)
|
||||
{
|
||||
APPEND("/A", 3, "/", "ABC");
|
||||
APPEND("/", 2, "/", "test");
|
||||
APPEND("X", 2, "X", "ABC");
|
||||
APPEND("X/", 3, "X/", "ABC");
|
||||
}
|
||||
|
||||
#undef APPEND
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Tests for: #BLI_path_frame
|
||||
* \{ */
|
||||
|
|
|
@ -271,10 +271,20 @@ struct BlendFileReadReport *BLO_read_data_reports(BlendDataReader *reader);
|
|||
* However, now only pointers to ID data blocks are updated.
|
||||
* \{ */
|
||||
|
||||
ID *BLO_read_get_new_id_address(BlendLibReader *reader, struct Library *lib, struct ID *id);
|
||||
/** Search for the new address of given `id`, during liblinking part of blendfile reading process.
|
||||
*
|
||||
* \param self_id the ID owner of the given `id` pointer. Note that it may be an embedded ID.
|
||||
* \param do_linked_only If `true`, only return found pointer if it is a linked ID. Used to
|
||||
* preventlinked data to point to local IDs.
|
||||
* \return the new address of the given ID pointer, or null if not found. */
|
||||
ID *BLO_read_get_new_id_address(BlendLibReader *reader,
|
||||
struct ID *self_id,
|
||||
const bool do_linked_only,
|
||||
struct ID *id) ATTR_NONNULL(2);
|
||||
|
||||
#define BLO_read_id_address(reader, lib, id_ptr_p) \
|
||||
*((void **)id_ptr_p) = (void *)BLO_read_get_new_id_address((reader), (lib), (ID *)*(id_ptr_p))
|
||||
#define BLO_read_id_address(reader, self_id, id_ptr_p) \
|
||||
*((void **)id_ptr_p) = (void *)BLO_read_get_new_id_address( \
|
||||
(reader), (self_id), (self_id) && ID_IS_LINKED(self_id), (ID *)*(id_ptr_p))
|
||||
|
||||
/* Misc. */
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, const void *addr, bool inc
|
|||
}
|
||||
|
||||
/* for libdata, NewAddress.nr has ID code, no increment */
|
||||
static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *lib)
|
||||
static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const bool is_linked_only)
|
||||
{
|
||||
if (addr == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -295,7 +295,7 @@ static void *oldnewmap_liblookup(OldNewMap *onm, const void *addr, const void *l
|
|||
if (id == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!lib || id->lib) {
|
||||
if (!is_linked_only || ID_IS_LINKED(id)) {
|
||||
return id;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -1386,14 +1386,20 @@ static void *newpackedadr(FileData *fd, const void *adr)
|
|||
}
|
||||
|
||||
/* only lib data */
|
||||
static void *newlibadr(FileData *fd, const void *lib, const void *adr)
|
||||
static void *newlibadr(FileData *fd,
|
||||
ID * /* self_id */,
|
||||
const bool is_linked_only,
|
||||
const void *adr)
|
||||
{
|
||||
return oldnewmap_liblookup(fd->libmap, adr, lib);
|
||||
return oldnewmap_liblookup(fd->libmap, adr, is_linked_only);
|
||||
}
|
||||
|
||||
void *blo_do_versions_newlibadr(FileData *fd, const void *lib, const void *adr)
|
||||
void *blo_do_versions_newlibadr(FileData *fd,
|
||||
ID *self_id,
|
||||
const bool is_linked_only,
|
||||
const void *adr)
|
||||
{
|
||||
return newlibadr(fd, lib, adr);
|
||||
return newlibadr(fd, self_id, is_linked_only, adr);
|
||||
}
|
||||
|
||||
/* increases user number */
|
||||
|
@ -1860,7 +1866,7 @@ static void lib_link_id(BlendLibReader *reader, ID *id)
|
|||
{
|
||||
/* NOTE: WM IDProperties are never written to file, hence they should always be nullptr here. */
|
||||
BLI_assert((GS(id->name) != ID_WM) || id->properties == nullptr);
|
||||
IDP_BlendReadLib(reader, id->lib, id->properties);
|
||||
IDP_BlendReadLib(reader, id, id->properties);
|
||||
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt != nullptr) {
|
||||
|
@ -1868,9 +1874,9 @@ static void lib_link_id(BlendLibReader *reader, ID *id)
|
|||
}
|
||||
|
||||
if (id->override_library) {
|
||||
BLO_read_id_address(reader, id->lib, &id->override_library->reference);
|
||||
BLO_read_id_address(reader, id->lib, &id->override_library->storage);
|
||||
BLO_read_id_address(reader, id->lib, &id->override_library->hierarchy_root);
|
||||
BLO_read_id_address(reader, id, &id->override_library->reference);
|
||||
BLO_read_id_address(reader, id, &id->override_library->storage);
|
||||
BLO_read_id_address(reader, id, &id->override_library->hierarchy_root);
|
||||
}
|
||||
|
||||
lib_link_id_embedded_id(reader, id);
|
||||
|
@ -3444,8 +3450,8 @@ static void link_global(FileData *fd, BlendFileData *bfd)
|
|||
{
|
||||
bfd->cur_view_layer = static_cast<ViewLayer *>(
|
||||
blo_read_get_new_globaldata_address(fd, bfd->cur_view_layer));
|
||||
bfd->curscreen = static_cast<bScreen *>(newlibadr(fd, nullptr, bfd->curscreen));
|
||||
bfd->curscene = static_cast<Scene *>(newlibadr(fd, nullptr, bfd->curscene));
|
||||
bfd->curscreen = static_cast<bScreen *>(newlibadr(fd, nullptr, false, bfd->curscreen));
|
||||
bfd->curscene = static_cast<Scene *>(newlibadr(fd, nullptr, false, bfd->curscene));
|
||||
/* this happens in files older than 2.35 */
|
||||
if (bfd->curscene == nullptr) {
|
||||
if (bfd->curscreen) {
|
||||
|
@ -4999,9 +5005,12 @@ void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_a
|
|||
return newpackedadr(reader->fd, old_address);
|
||||
}
|
||||
|
||||
ID *BLO_read_get_new_id_address(BlendLibReader *reader, Library *lib, ID *id)
|
||||
ID *BLO_read_get_new_id_address(BlendLibReader *reader,
|
||||
ID *self_id,
|
||||
const bool is_linked_only,
|
||||
ID *id)
|
||||
{
|
||||
return static_cast<ID *>(newlibadr(reader->fd, lib, id));
|
||||
return static_cast<ID *>(newlibadr(reader->fd, self_id, is_linked_only, id));
|
||||
}
|
||||
|
||||
int BLO_read_fileversion_get(BlendDataReader *reader)
|
||||
|
|
|
@ -201,8 +201,10 @@ void blo_do_versions_oldnewmap_insert(struct OldNewMap *onm,
|
|||
/**
|
||||
* Only library data.
|
||||
*/
|
||||
void *blo_do_versions_newlibadr(struct FileData *fd, const void *lib, const void *adr);
|
||||
void *blo_do_versions_newlibadr_us(struct FileData *fd, const void *lib, const void *adr);
|
||||
void *blo_do_versions_newlibadr(struct FileData *fd,
|
||||
ID *self_id,
|
||||
const bool is_linked_only,
|
||||
const void *adr);
|
||||
|
||||
/**
|
||||
* \note this version patch is intended for versions < 2.52.2,
|
||||
|
|
|
@ -668,7 +668,7 @@ static bool seq_set_pitch_cb(Sequence *seq, void *UNUSED(user_data))
|
|||
}
|
||||
|
||||
/* NOLINTNEXTLINE: readability-function-size */
|
||||
void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
||||
void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
{
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted */
|
||||
|
||||
|
@ -727,10 +727,10 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
|||
/* move to cameras */
|
||||
if (sce->r.mode & R_PANORAMA) {
|
||||
for (base = sce->base.first; base; base = base->next) {
|
||||
ob = blo_do_versions_newlibadr(fd, lib, base->object);
|
||||
ob = blo_do_versions_newlibadr(fd, &sce->id, ID_IS_LINKED(sce), base->object);
|
||||
|
||||
if (ob->type == OB_CAMERA && !ob->id.lib) {
|
||||
cam = blo_do_versions_newlibadr(fd, lib, ob->data);
|
||||
cam = blo_do_versions_newlibadr(fd, &ob->id, ID_IS_LINKED(ob), ob->data);
|
||||
cam->flag |= CAM_PANORAMA;
|
||||
}
|
||||
}
|
||||
|
@ -996,7 +996,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
|||
* to the evaluated #Mesh, so here we ensure that the basis
|
||||
* shape key is always set in the mesh coordinates. */
|
||||
for (me = bmain->meshes.first; me; me = me->id.next) {
|
||||
if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) {
|
||||
if ((key = blo_do_versions_newlibadr(fd, &me->id, ID_IS_LINKED(me), me->key)) &&
|
||||
key->refkey) {
|
||||
data = key->refkey->data;
|
||||
tot = MIN2(me->totvert, key->refkey->totelem);
|
||||
MVert *verts = (MVert *)CustomData_get_layer_for_write(&me->vdata, CD_MVERT, me->totvert);
|
||||
|
@ -1007,7 +1008,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
|||
}
|
||||
|
||||
for (lt = bmain->lattices.first; lt; lt = lt->id.next) {
|
||||
if ((key = blo_do_versions_newlibadr(fd, lib, lt->key)) && key->refkey) {
|
||||
if ((key = blo_do_versions_newlibadr(fd, <->id, ID_IS_LINKED(lt), lt->key)) &&
|
||||
key->refkey) {
|
||||
data = key->refkey->data;
|
||||
tot = MIN2(lt->pntsu * lt->pntsv * lt->pntsw, key->refkey->totelem);
|
||||
|
||||
|
@ -1018,7 +1020,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
|||
}
|
||||
|
||||
for (cu = bmain->curves.first; cu; cu = cu->id.next) {
|
||||
if ((key = blo_do_versions_newlibadr(fd, lib, cu->key)) && key->refkey) {
|
||||
if ((key = blo_do_versions_newlibadr(fd, &cu->id, ID_IS_LINKED(cu), cu->key)) &&
|
||||
key->refkey) {
|
||||
data = key->refkey->data;
|
||||
|
||||
for (nu = cu->nurb.first; nu; nu = nu->next) {
|
||||
|
@ -1294,7 +1297,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
|||
* performing initialization where appropriate
|
||||
*/
|
||||
if (ob->pose && ob->data) {
|
||||
bArmature *arm = blo_do_versions_newlibadr(fd, lib, ob->data);
|
||||
bArmature *arm = blo_do_versions_newlibadr(fd, &ob->id, ID_IS_LINKED(ob), ob->data);
|
||||
if (arm) { /* XXX: why does this fail in some cases? */
|
||||
bAnimVizSettings *avs = &ob->pose->avs;
|
||||
|
||||
|
@ -1628,12 +1631,14 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
|||
/* parent type to modifier */
|
||||
for (ob = bmain->objects.first; ob; ob = ob->id.next) {
|
||||
if (ob->parent) {
|
||||
Object *parent = (Object *)blo_do_versions_newlibadr(fd, lib, ob->parent);
|
||||
Object *parent = (Object *)blo_do_versions_newlibadr(
|
||||
fd, &ob->id, ID_IS_LINKED(ob), ob->parent);
|
||||
if (parent) { /* parent may not be in group */
|
||||
enum { PARCURVE = 1 };
|
||||
if (parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
|
||||
ArmatureModifierData *amd;
|
||||
bArmature *arm = (bArmature *)blo_do_versions_newlibadr(fd, lib, parent->data);
|
||||
bArmature *arm = (bArmature *)blo_do_versions_newlibadr(
|
||||
fd, &parent->id, ID_IS_LINKED(parent), parent->data);
|
||||
|
||||
amd = (ArmatureModifierData *)BKE_modifier_new(eModifierType_Armature);
|
||||
amd->object = ob->parent;
|
||||
|
|
|
@ -1813,7 +1813,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
|
||||
for (tex = bmain->textures.first; tex; tex = tex->id.next) {
|
||||
if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
|
||||
Image *image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
|
||||
Image *image = blo_do_versions_newlibadr(fd, &tex->id, ID_IS_LINKED(tex), tex->ima);
|
||||
|
||||
if (image && (image->flag & IMA_DO_PREMUL) == 0) {
|
||||
enum { IMA_IGNORE_ALPHA = (1 << 12) };
|
||||
|
@ -1827,7 +1827,8 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
bNode *node;
|
||||
for (node = ntree->nodes.first; node; node = node->next) {
|
||||
if (node->type == CMP_NODE_IMAGE) {
|
||||
Image *image = blo_do_versions_newlibadr(fd, ntree->id.lib, node->id);
|
||||
Image *image = blo_do_versions_newlibadr(
|
||||
fd, &ntree->id, ID_IS_LINKED(ntree), node->id);
|
||||
|
||||
if (image) {
|
||||
if ((image->flag & IMA_DO_PREMUL) == 0 && image->alpha_mode == IMA_ALPHA_STRAIGHT) {
|
||||
|
|
|
@ -171,13 +171,6 @@ static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip)
|
|||
|
||||
BLI_assert(tracking_camera_object != nullptr);
|
||||
|
||||
|
||||
/* NOTE: The regular .blend file saving converts the new format to the legacy format, but the
|
||||
* auto-save one does not do this. Likely, the regular saving clears the new storage before
|
||||
* write, so it can be used to make a decision here.
|
||||
*
|
||||
* The idea is basically to not override the new storage if it exists. This is only supposed to
|
||||
* happen for auto-save files. */
|
||||
|
||||
if (BLI_listbase_is_empty(&tracking_camera_object->tracks)) {
|
||||
tracking_camera_object->tracks = tracking.tracks_legacy;
|
||||
active_tracking_object->active_track = tracking.act_track_legacy;
|
||||
|
@ -211,15 +204,12 @@ static void version_movieclips_legacy_camera_object(Main *bmain)
|
|||
|
||||
void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
// if (!MAIN_VERSION_ATLEAST(bmain, 400, 0)) {
|
||||
/* This is done here because we will continue to write with the old format until 4.0, so we need
|
||||
* to convert even "current" files. Keep the check commented out for now so the versioning isn't
|
||||
* turned off right after the 4.0 bump. */
|
||||
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
|
||||
version_mesh_legacy_to_struct_of_array_format(*mesh);
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 400, 1)) {
|
||||
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
|
||||
version_mesh_legacy_to_struct_of_array_format(*mesh);
|
||||
}
|
||||
version_movieclips_legacy_camera_object(bmain);
|
||||
}
|
||||
version_movieclips_legacy_camera_object(bmain);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Creating IDs in versioning code is forbidden. Until a better system (more generic) is implemented, a specific call needs to be added after all versioning is done, see e.g. the call to
BKE_lib_override_library_main_proxy_convert
insetup_app_data()