Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--build_files/cmake/config/blender_release.cmake2
-rw-r--r--intern/cycles/device/cuda/device_cuda_impl.cpp23
-rw-r--r--intern/cycles/kernel/CMakeLists.txt4
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl4
-rw-r--r--intern/cycles/kernel/svm/svm_sky.h4
-rw-r--r--intern/cycles/render/nodes.cpp2
-rw-r--r--intern/mantaflow/extern/manta_fluid_API.h68
-rw-r--r--intern/mantaflow/intern/manta_fluid_API.cpp136
-rw-r--r--intern/mantaflow/intern/strings/smoke_script.h6
-rw-r--r--intern/sky/source/sky_nishita.cpp103
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py4
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py34
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_toolbar.py10
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py2
-rw-r--r--source/blender/blenkernel/BKE_action.h3
-rw-r--r--source/blender/blenkernel/BKE_animsys.h34
-rw-r--r--source/blender/blenkernel/BKE_collection.h3
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h7
-rw-r--r--source/blender/blenkernel/BKE_fcurve_driver.h3
-rw-r--r--source/blender/blenkernel/intern/action.c12
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c163
-rw-r--r--source/blender/blenkernel/intern/collection.c83
-rw-r--r--source/blender/blenkernel/intern/constraint.c9
-rw-r--r--source/blender/blenkernel/intern/fcurve.c13
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c14
-rw-r--r--source/blender/blenkernel/intern/fluid.c229
-rw-r--r--source/blender/blenkernel/intern/lib_id_delete.c9
-rw-r--r--source/blender/blenkernel/intern/lib_override.c14
-rw-r--r--source/blender/blenkernel/intern/object.c17
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c7
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/blenkernel/nla_private.h10
-rw-r--r--source/blender/blenlib/BLI_allocator.hh4
-rw-r--r--source/blender/blenlib/BLI_array.hh51
-rw-r--r--source/blender/blenlib/BLI_color.hh16
-rw-r--r--source/blender/blenlib/BLI_disjoint_set.hh27
-rw-r--r--source/blender/blenlib/BLI_dot_export.hh4
-rw-r--r--source/blender/blenlib/BLI_float3.hh8
-rw-r--r--source/blender/blenlib/BLI_float4x4.hh6
-rw-r--r--source/blender/blenlib/BLI_hash.hh62
-rw-r--r--source/blender/blenlib/BLI_hash_tables.hh101
-rw-r--r--source/blender/blenlib/BLI_index_mask.hh30
-rw-r--r--source/blender/blenlib/BLI_index_range.hh64
-rw-r--r--source/blender/blenlib/BLI_linear_allocator.hh29
-rw-r--r--source/blender/blenlib/BLI_listbase_wrapper.hh6
-rw-r--r--source/blender/blenlib/BLI_map.hh113
-rw-r--r--source/blender/blenlib/BLI_map_slots.hh20
-rw-r--r--source/blender/blenlib/BLI_memory_utils.hh76
-rw-r--r--source/blender/blenlib/BLI_probing_strategies.hh58
-rw-r--r--source/blender/blenlib/BLI_rand.hh2
-rw-r--r--source/blender/blenlib/BLI_resource_collector.hh2
-rw-r--r--source/blender/blenlib/BLI_set.hh82
-rw-r--r--source/blender/blenlib/BLI_set_slots.hh26
-rw-r--r--source/blender/blenlib/BLI_span.hh104
-rw-r--r--source/blender/blenlib/BLI_stack.hh26
-rw-r--r--source/blender/blenlib/BLI_string_ref.hh53
-rw-r--r--source/blender/blenlib/BLI_vector.hh133
-rw-r--r--source/blender/blenlib/BLI_vector_set.hh101
-rw-r--r--source/blender/blenlib/BLI_vector_set_slots.hh24
-rw-r--r--source/blender/blenlib/intern/BLI_index_range.cc22
-rw-r--r--source/blender/blenlib/intern/dot_export.cc4
-rw-r--r--source/blender/blenlib/intern/rand.cc19
-rw-r--r--source/blender/blenloader/intern/versioning_290.c8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cache.h2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_registry.cc6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.cc2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_id.h2
-rw-r--r--source/blender/draw/DRW_engine.h4
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/select/select_engine.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c2
-rw-r--r--source/blender/draw/intern/draw_manager.c94
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c36
-rw-r--r--source/blender/editors/animation/anim_filter.c1
-rw-r--r--source/blender/editors/animation/keyframing.c92
-rw-r--r--source/blender/editors/animation/keyingsets.c5
-rw-r--r--source/blender/editors/armature/pose_lib.c13
-rw-r--r--source/blender/editors/armature/pose_transform.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c65
-rw-r--r--source/blender/editors/include/ED_anim_api.h2
-rw-r--r--source/blender/editors/include/ED_keyframing.h7
-rw-r--r--source/blender/editors/interface/interface.c6
-rw-r--r--source/blender/editors/interface/interface_anim.c8
-rw-r--r--source/blender/editors/interface/interface_handlers.c6
-rw-r--r--source/blender/editors/interface/interface_intern.h3
-rw-r--r--source/blender/editors/interface/interface_layout.c28
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c124
-rw-r--r--source/blender/editors/object/object_add.c2
-rw-r--r--source/blender/editors/object/object_modifier.c6
-rw-r--r--source/blender/editors/space_action/action_edit.c8
-rw-r--r--source/blender/editors/space_graph/graph_edit.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c2
-rw-r--r--source/blender/editors/transform/transform_convert_armature.c21
-rw-r--r--source/blender/editors/transform/transform_convert_object.c21
-rw-r--r--source/blender/functions/FN_array_spans.hh22
-rw-r--r--source/blender/functions/FN_attributes_ref.hh57
-rw-r--r--source/blender/functions/FN_cpp_type.hh92
-rw-r--r--source/blender/functions/FN_generic_vector_array.hh46
-rw-r--r--source/blender/functions/FN_multi_function.hh10
-rw-r--r--source/blender/functions/FN_multi_function_builder.hh18
-rw-r--r--source/blender/functions/FN_multi_function_data_type.hh4
-rw-r--r--source/blender/functions/FN_multi_function_network.hh70
-rw-r--r--source/blender/functions/FN_multi_function_params.hh58
-rw-r--r--source/blender/functions/FN_multi_function_signature.hh16
-rw-r--r--source/blender/functions/FN_spans.hh40
-rw-r--r--source/blender/functions/intern/attributes_ref.cc6
-rw-r--r--source/blender/functions/intern/multi_function_builder.cc10
-rw-r--r--source/blender/functions/intern/multi_function_network.cc20
-rw-r--r--source/blender/functions/intern/multi_function_network_evaluation.cc20
-rw-r--r--source/blender/functions/intern/multi_function_network_optimization.cc46
-rw-r--r--source/blender/gpu/intern/gpu_draw_smoke.c12
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c16
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c12
-rw-r--r--source/blender/makesrna/intern/rna_render.c25
-rw-r--r--source/blender/nodes/NOD_derived_node_tree.hh44
-rw-r--r--source/blender/nodes/NOD_node_tree_multi_function.hh6
-rw-r--r--source/blender/nodes/NOD_node_tree_ref.hh26
-rw-r--r--source/blender/nodes/intern/derived_node_tree.cc18
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_map_range.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.cc2
-rw-r--r--source/blender/python/BPY_extern.h3
-rw-r--r--source/blender/python/intern/bpy_driver.c44
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c22
-rw-r--r--source/blender/render/extern/include/RE_engine.h1
-rw-r--r--source/blender/render/intern/source/external_engine.c16
-rw-r--r--source/blender/render/intern/source/pipeline.c4
-rw-r--r--source/blender/simulation/intern/particle_allocator.cc14
-rw-r--r--source/blender/simulation/intern/particle_allocator.hh21
-rw-r--r--source/blender/simulation/intern/particle_function.cc14
-rw-r--r--source/blender/simulation/intern/particle_function.hh8
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.cc19
-rw-r--r--source/blender/simulation/intern/simulation_solver.cc219
-rw-r--r--source/blender/simulation/intern/simulation_solver.hh53
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c4
-rw-r--r--tests/gtests/blenlib/BLI_array_test.cc44
-rw-r--r--tests/gtests/blenlib/BLI_disjoint_set_test.cc2
-rw-r--r--tests/gtests/blenlib/BLI_index_mask_test.cc2
-rw-r--r--tests/gtests/blenlib/BLI_index_range_test.cc86
-rw-r--r--tests/gtests/blenlib/BLI_linear_allocator_test.cc12
-rw-r--r--tests/gtests/blenlib/BLI_map_test.cc84
-rw-r--r--tests/gtests/blenlib/BLI_set_test.cc54
-rw-r--r--tests/gtests/blenlib/BLI_span_test.cc64
-rw-r--r--tests/gtests/blenlib/BLI_stack_cxx_test.cc32
-rw-r--r--tests/gtests/blenlib/BLI_string_ref_test.cc32
-rw-r--r--tests/gtests/blenlib/BLI_vector_set_test.cc56
-rw-r--r--tests/gtests/blenlib/BLI_vector_test.cc168
-rw-r--r--tests/gtests/functions/FN_array_spans_test.cc2
-rw-r--r--tests/gtests/functions/FN_attributes_ref_test.cc2
-rw-r--r--tests/gtests/functions/FN_cpp_type_test.cc2
-rw-r--r--tests/gtests/functions/FN_multi_function_network_test.cc10
-rw-r--r--tests/gtests/functions/FN_multi_function_test.cc10
162 files changed, 2675 insertions, 2061 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 49b974596f7..cc0e5a2491f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -367,7 +367,7 @@ option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
-set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 CACHE STRING "CUDA architectures to build binaries for")
+set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 compute_75 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake
index 5fce64ce719..e6fc73a75ed 100644
--- a/build_files/cmake/config/blender_release.cmake
+++ b/build_files/cmake/config/blender_release.cmake
@@ -53,7 +53,7 @@ set(WITH_USD ON CACHE BOOL "" FORCE)
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
-set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75 CACHE STRING "" FORCE)
+set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75;compute_75 CACHE STRING "" FORCE)
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
# platform dependent options
diff --git a/intern/cycles/device/cuda/device_cuda_impl.cpp b/intern/cycles/device/cuda/device_cuda_impl.cpp
index 0be2c322dfa..3a2eb8df95b 100644
--- a/intern/cycles/device/cuda/device_cuda_impl.cpp
+++ b/intern/cycles/device/cuda/device_cuda_impl.cpp
@@ -383,11 +383,24 @@ string CUDADevice::compile_kernel(const DeviceRequestedFeatures &requested_featu
}
}
- const string ptx = path_get(string_printf("lib/%s_compute_%d%d.ptx", name, major, minor));
- VLOG(1) << "Testing for pre-compiled kernel " << ptx << ".";
- if (path_exists(ptx)) {
- VLOG(1) << "Using precompiled kernel.";
- return ptx;
+ /* The driver can JIT-compile PTX generated for older generations, so find the closest one. */
+ int ptx_major = major, ptx_minor = minor;
+ while (ptx_major >= 3) {
+ const string ptx = path_get(
+ string_printf("lib/%s_compute_%d%d.ptx", name, ptx_major, ptx_minor));
+ VLOG(1) << "Testing for pre-compiled kernel " << ptx << ".";
+ if (path_exists(ptx)) {
+ VLOG(1) << "Using precompiled kernel.";
+ return ptx;
+ }
+
+ if (ptx_minor > 0) {
+ ptx_minor--;
+ }
+ else {
+ ptx_major--;
+ ptx_minor = 9;
+ }
}
}
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 7cc0d32d521..5533eeb006d 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -539,7 +539,7 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
${SRC_UTIL_HEADERS}
COMMAND ${CUBIN_CC_ENV}
"$<TARGET_FILE:cycles_cubin_cc>"
- -target 30
+ -target 52
-ptx
-i ${CMAKE_CURRENT_SOURCE_DIR}/${input}
${cuda_flags}
@@ -563,7 +563,7 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
COMMAND
${CUDA_NVCC_EXECUTABLE}
--ptx
- -arch=sm_30
+ -arch=sm_52
${cuda_flags}
${input}
WORKING_DIRECTORY
diff --git a/intern/cycles/kernel/shaders/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index acb198a9852..a12e7a9dc17 100644
--- a/intern/cycles/kernel/shaders/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -204,8 +204,8 @@ color sky_radiance_nishita(vector dir, float nishita_data[10], string filename)
mul;
}
}
- /* convert to RGB and adjust strength */
- return xyz_to_rgb(xyz[0], xyz[1], xyz[2]) * 120000.0;
+ /* convert to RGB */
+ return xyz_to_rgb(xyz[0], xyz[1], xyz[2]);
}
shader node_sky_texture(
diff --git a/intern/cycles/kernel/svm/svm_sky.h b/intern/cycles/kernel/svm/svm_sky.h
index be2c8ccdacf..f824184c1d4 100644
--- a/intern/cycles/kernel/svm/svm_sky.h
+++ b/intern/cycles/kernel/svm/svm_sky.h
@@ -205,8 +205,8 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals *kg,
}
}
- /* convert to rgb and adjust strength */
- return xyz_to_rgb(kg, xyz) * 120000.0f;
+ /* convert to RGB */
+ return xyz_to_rgb(kg, xyz);
}
ccl_device void svm_node_tex_sky(
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 1a29663ec5e..d5f65fb54db 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -798,7 +798,7 @@ NODE_DEFINE(SkyTextureNode)
SOCKET_BOOLEAN(sun_disc, "Sun Disc", true);
SOCKET_FLOAT(sun_size, "Sun Size", 0.009512f);
SOCKET_FLOAT(sun_intensity, "Sun Intensity", 1.0f);
- SOCKET_FLOAT(sun_elevation, "Sun Elevation", M_PI_2_F);
+ SOCKET_FLOAT(sun_elevation, "Sun Elevation", 15.0f * M_PI_F / 180.0f);
SOCKET_FLOAT(sun_rotation, "Sun Rotation", 0.0f);
SOCKET_FLOAT(altitude, "Altitude", 1.0f);
SOCKET_FLOAT(air_density, "Air", 1.0f);
diff --git a/intern/mantaflow/extern/manta_fluid_API.h b/intern/mantaflow/extern/manta_fluid_API.h
index 1dbfc6bdd9c..3da1d8f53f0 100644
--- a/intern/mantaflow/extern/manta_fluid_API.h
+++ b/intern/mantaflow/extern/manta_fluid_API.h
@@ -111,46 +111,16 @@ float *manta_get_phioutstatic_in(struct MANTA *fluid);
/* Smoke functions */
void manta_smoke_export_script(struct MANTA *smoke, struct FluidModifierData *fmd);
-void manta_smoke_export(struct MANTA *smoke,
- float *dt,
- float *dx,
- float **dens,
- float **react,
- float **flame,
- float **fuel,
- float **heat,
- float **vx,
- float **vy,
- float **vz,
- float **r,
- float **g,
- float **b,
- int **flags,
- float **shadow);
-void manta_smoke_turbulence_export(struct MANTA *smoke,
- float **dens,
- float **react,
- float **flame,
- float **fuel,
- float **r,
- float **g,
- float **b,
- float **tcu,
- float **tcv,
- float **tcw,
- float **tcu2,
- float **tcv2,
- float **tcw2);
void manta_smoke_get_rgba(struct MANTA *smoke, float *data, int sequential);
-void manta_smoke_turbulence_get_rgba(struct MANTA *smoke, float *data, int sequential);
+void manta_noise_get_rgba(struct MANTA *smoke, float *data, int sequential);
void manta_smoke_get_rgba_fixed_color(struct MANTA *smoke,
float color[3],
float *data,
int sequential);
-void manta_smoke_turbulence_get_rgba_fixed_color(struct MANTA *smoke,
- float color[3],
- float *data,
- int sequential);
+void manta_noise_get_rgba_fixed_color(struct MANTA *smoke,
+ float color[3],
+ float *data,
+ int sequential);
void manta_smoke_ensure_heat(struct MANTA *smoke, struct FluidModifierData *fmd);
void manta_smoke_ensure_fire(struct MANTA *smoke, struct FluidModifierData *fmd);
void manta_smoke_ensure_colors(struct MANTA *smoke, struct FluidModifierData *fmd);
@@ -177,17 +147,23 @@ float *manta_smoke_get_emission_in(struct MANTA *smoke);
int manta_smoke_has_heat(struct MANTA *smoke);
int manta_smoke_has_fuel(struct MANTA *smoke);
int manta_smoke_has_colors(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_density(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_fuel(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_react(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_color_r(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_color_g(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_color_b(struct MANTA *smoke);
-float *manta_smoke_turbulence_get_flame(struct MANTA *smoke);
-int manta_smoke_turbulence_has_fuel(struct MANTA *smoke);
-int manta_smoke_turbulence_has_colors(struct MANTA *smoke);
-void manta_smoke_turbulence_get_res(struct MANTA *smoke, int *res);
-int manta_smoke_turbulence_get_cells(struct MANTA *smoke);
+float *manta_noise_get_density(struct MANTA *smoke);
+float *manta_noise_get_fuel(struct MANTA *smoke);
+float *manta_noise_get_react(struct MANTA *smoke);
+float *manta_noise_get_color_r(struct MANTA *smoke);
+float *manta_noise_get_color_g(struct MANTA *smoke);
+float *manta_noise_get_color_b(struct MANTA *smoke);
+float *manta_noise_get_texture_u(struct MANTA *smoke);
+float *manta_noise_get_texture_v(struct MANTA *smoke);
+float *manta_noise_get_texture_w(struct MANTA *smoke);
+float *manta_noise_get_texture_u2(struct MANTA *smoke);
+float *manta_noise_get_texture_v2(struct MANTA *smoke);
+float *manta_noise_get_texture_w2(struct MANTA *smoke);
+float *manta_noise_get_flame(struct MANTA *smoke);
+int manta_noise_has_fuel(struct MANTA *smoke);
+int manta_noise_has_colors(struct MANTA *smoke);
+void manta_noise_get_res(struct MANTA *smoke, int *res);
+int manta_noise_get_cells(struct MANTA *smoke);
/* Liquid functions */
void manta_liquid_export_script(struct MANTA *smoke, struct FluidModifierData *fmd);
diff --git a/intern/mantaflow/intern/manta_fluid_API.cpp b/intern/mantaflow/intern/manta_fluid_API.cpp
index 1db3da63ecc..60546bc1183 100644
--- a/intern/mantaflow/intern/manta_fluid_API.cpp
+++ b/intern/mantaflow/intern/manta_fluid_API.cpp
@@ -368,89 +368,6 @@ void manta_smoke_export_script(MANTA *smoke, FluidModifierData *fmd)
smoke->exportSmokeScript(fmd);
}
-void manta_smoke_export(MANTA *smoke,
- float *dt,
- float *dx,
- float **dens,
- float **react,
- float **flame,
- float **fuel,
- float **heat,
- float **vx,
- float **vy,
- float **vz,
- float **r,
- float **g,
- float **b,
- int **flags,
- float **shadow)
-{
- if (dens)
- *dens = smoke->getDensity();
- if (fuel)
- *fuel = smoke->getFuel();
- if (react)
- *react = smoke->getReact();
- if (flame)
- *flame = smoke->getFlame();
- if (heat)
- *heat = smoke->getHeat();
- *vx = smoke->getVelocityX();
- *vy = smoke->getVelocityY();
- *vz = smoke->getVelocityZ();
- if (r)
- *r = smoke->getColorR();
- if (g)
- *g = smoke->getColorG();
- if (b)
- *b = smoke->getColorB();
- *flags = smoke->getFlags();
- if (shadow)
- *shadow = smoke->getShadow();
- *dt = 1; // dummy value, not needed for smoke
- *dx = 1; // dummy value, not needed for smoke
-}
-
-void manta_smoke_turbulence_export(MANTA *smoke,
- float **dens,
- float **react,
- float **flame,
- float **fuel,
- float **r,
- float **g,
- float **b,
- float **tcu,
- float **tcv,
- float **tcw,
- float **tcu2,
- float **tcv2,
- float **tcw2)
-{
- if (!smoke && !(smoke->usingNoise()))
- return;
-
- *dens = smoke->getDensityHigh();
- if (fuel)
- *fuel = smoke->getFuelHigh();
- if (react)
- *react = smoke->getReactHigh();
- if (flame)
- *flame = smoke->getFlameHigh();
- if (r)
- *r = smoke->getColorRHigh();
- if (g)
- *g = smoke->getColorGHigh();
- if (b)
- *b = smoke->getColorBHigh();
- *tcu = smoke->getTextureU();
- *tcv = smoke->getTextureV();
- *tcw = smoke->getTextureW();
-
- *tcu2 = smoke->getTextureU2();
- *tcv2 = smoke->getTextureV2();
- *tcw2 = smoke->getTextureW2();
-}
-
static void get_rgba(
float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential)
{
@@ -484,7 +401,7 @@ void manta_smoke_get_rgba(MANTA *smoke, float *data, int sequential)
sequential);
}
-void manta_smoke_turbulence_get_rgba(MANTA *smoke, float *data, int sequential)
+void manta_noise_get_rgba(MANTA *smoke, float *data, int sequential)
{
get_rgba(smoke->getColorRHigh(),
smoke->getColorGHigh(),
@@ -519,10 +436,7 @@ void manta_smoke_get_rgba_fixed_color(MANTA *smoke, float color[3], float *data,
get_rgba_fixed_color(color, smoke->getTotalCells(), data, sequential);
}
-void manta_smoke_turbulence_get_rgba_fixed_color(MANTA *smoke,
- float color[3],
- float *data,
- int sequential)
+void manta_noise_get_rgba_fixed_color(MANTA *smoke, float color[3], float *data, int sequential)
{
get_rgba_fixed_color(color, smoke->getTotalCellsHigh(), data, sequential);
}
@@ -647,45 +561,69 @@ int manta_smoke_has_colors(MANTA *smoke)
return (smoke->getColorR() && smoke->getColorG() && smoke->getColorB()) ? 1 : 0;
}
-float *manta_smoke_turbulence_get_density(MANTA *smoke)
+float *manta_noise_get_density(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getDensityHigh() : nullptr;
}
-float *manta_smoke_turbulence_get_fuel(MANTA *smoke)
+float *manta_noise_get_fuel(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getFuelHigh() : nullptr;
}
-float *manta_smoke_turbulence_get_react(MANTA *smoke)
+float *manta_noise_get_react(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getReactHigh() : nullptr;
}
-float *manta_smoke_turbulence_get_color_r(MANTA *smoke)
+float *manta_noise_get_color_r(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getColorRHigh() : nullptr;
}
-float *manta_smoke_turbulence_get_color_g(MANTA *smoke)
+float *manta_noise_get_color_g(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getColorGHigh() : nullptr;
}
-float *manta_smoke_turbulence_get_color_b(MANTA *smoke)
+float *manta_noise_get_color_b(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getColorBHigh() : nullptr;
}
-float *manta_smoke_turbulence_get_flame(MANTA *smoke)
+float *manta_noise_get_flame(MANTA *smoke)
{
return (smoke && smoke->usingNoise()) ? smoke->getFlameHigh() : nullptr;
}
+float *manta_noise_get_texture_u(MANTA *smoke)
+{
+ return (smoke && smoke->usingNoise()) ? smoke->getTextureU() : nullptr;
+}
+float *manta_noise_get_texture_v(MANTA *smoke)
+{
+ return (smoke && smoke->usingNoise()) ? smoke->getTextureV() : nullptr;
+}
+float *manta_noise_get_texture_w(MANTA *smoke)
+{
+ return (smoke && smoke->usingNoise()) ? smoke->getTextureW() : nullptr;
+}
+float *manta_noise_get_texture_u2(MANTA *smoke)
+{
+ return (smoke && smoke->usingNoise()) ? smoke->getTextureU2() : nullptr;
+}
+float *manta_noise_get_texture_v2(MANTA *smoke)
+{
+ return (smoke && smoke->usingNoise()) ? smoke->getTextureV2() : nullptr;
+}
+float *manta_noise_get_texture_w2(MANTA *smoke)
+{
+ return (smoke && smoke->usingNoise()) ? smoke->getTextureW2() : nullptr;
+}
-int manta_smoke_turbulence_has_fuel(MANTA *smoke)
+int manta_noise_has_fuel(MANTA *smoke)
{
return (smoke->getFuelHigh()) ? 1 : 0;
}
-int manta_smoke_turbulence_has_colors(MANTA *smoke)
+int manta_noise_has_colors(MANTA *smoke)
{
return (smoke->getColorRHigh() && smoke->getColorGHigh() && smoke->getColorBHigh()) ? 1 : 0;
}
-void manta_smoke_turbulence_get_res(MANTA *smoke, int *res)
+void manta_noise_get_res(MANTA *smoke, int *res)
{
if (smoke && smoke->usingNoise()) {
res[0] = smoke->getResXHigh();
@@ -693,7 +631,7 @@ void manta_smoke_turbulence_get_res(MANTA *smoke, int *res)
res[2] = smoke->getResZHigh();
}
}
-int manta_smoke_turbulence_get_cells(MANTA *smoke)
+int manta_noise_get_cells(MANTA *smoke)
{
int total_cells_high = smoke->getResXHigh() * smoke->getResYHigh() * smoke->getResZHigh();
return (smoke && smoke->usingNoise()) ? total_cells_high : 0;
diff --git a/intern/mantaflow/intern/strings/smoke_script.h b/intern/mantaflow/intern/strings/smoke_script.h
index 612d01b85ef..332aa2342ee 100644
--- a/intern/mantaflow/intern/strings/smoke_script.h
+++ b/intern/mantaflow/intern/strings/smoke_script.h
@@ -100,6 +100,9 @@ color_r_in_s$ID$ = None\n\
color_g_in_s$ID$ = None\n\
color_b_in_s$ID$ = None\n\
\n\
+# Set some initial values\n\
+shadow_s$ID$.setConst(-1)\n\
+\n\
# Keep track of important objects in dict to load them later on\n\
smoke_data_dict_final_s$ID$ = { 'density' : density_s$ID$, 'shadow' : shadow_s$ID$ }\n\
smoke_data_dict_resume_s$ID$ = { 'densityIn' : densityIn_s$ID$, 'emission' : emission_s$ID$ }\n";
@@ -490,6 +493,9 @@ def step_noise_$ID$():\n\
advectSemiLagrange(flags=flags_s$ID$, vel=vel_s$ID$, grid=uvGrid1_s$ID$, order=2)\n\
updateUvWeight(resetTime=sn$ID$.timestep*10.0 , index=1, numUvs=uvs_s$ID$, uv=uvGrid1_s$ID$, offset=uvs_offset_s$ID$)\n\
\n\
+ if not domainClosed_s$ID$ or using_outflow_s$ID$:\n\
+ resetOutflow(flags=flags_sn$ID$, real=density_sn$ID$)\n\
+ \n\
mantaMsg('Energy')\n\
computeEnergy(flags=flags_s$ID$, vel=vel_s$ID$, energy=energy_s$ID$)\n\
\n\
diff --git a/intern/sky/source/sky_nishita.cpp b/intern/sky/source/sky_nishita.cpp
index eae95dc73fe..f36bfcc3d7b 100644
--- a/intern/sky/source/sky_nishita.cpp
+++ b/intern/sky/source/sky_nishita.cpp
@@ -18,20 +18,21 @@
#include "sky_model.h"
/* Constants */
-static const float rayleigh_scale = 8000.0f; // Rayleigh scale height (m)
-static const float mie_scale = 1200.0f; // Mie scale height (m)
-static const float mie_coeff = 2e-5f; // Mie scattering coefficient
-static const float mie_G = 0.76f; // aerosols anisotropy
-static const float sqr_G = mie_G * mie_G; // squared aerosols anisotropy
-static const float earth_radius = 6360000.0f; // radius of Earth (m)
-static const float atmosphere_radius = 6420000.0f; // radius of atmosphere (m)
-static const int steps = 32; // segments per primary ray
-static const int steps_light = 16; // segments per sun connection ray
-static const int num_wavelengths = 21; // number of wavelengths
-static const int max_luminous_efficacy = 683; // maximum luminous efficacy
-static const float step_lambda = (num_wavelengths - 1) *
- 1e-9f; // step between each sampled wavelength
-/* irradiance at top of atmosphere */
+static const float rayleigh_scale = 8e3f; // Rayleigh scale height (m)
+static const float mie_scale = 1.2e3f; // Mie scale height (m)
+static const float mie_coeff = 2e-5f; // Mie scattering coefficient (m^-1)
+static const float mie_G = 0.76f; // aerosols anisotropy
+static const float sqr_G = mie_G * mie_G; // squared aerosols anisotropy
+static const float earth_radius = 6360e3f; // radius of Earth (m)
+static const float atmosphere_radius = 6420e3f; // radius of atmosphere (m)
+static const int steps = 32; // segments of primary ray
+static const int steps_light = 16; // segments of sun connection ray
+static const int num_wavelengths = 21; // number of wavelengths
+static const int min_wavelength = 380; // lowest sampled wavelength (nm)
+static const int max_wavelength = 780; // highest sampled wavelength (nm)
+// step between each sampled wavelength (nm)
+static const float step_lambda = (max_wavelength - min_wavelength) / (num_wavelengths - 1);
+/* Sun irradiance on top of the atmosphere (W*m^-2*nm^-1) */
static const float irradiance[] = {
1.45756829855592995315f, 1.56596305559738380175f, 1.65148449067670455293f,
1.71496242737209314555f, 1.75797983805020541226f, 1.78256407885924539336f,
@@ -40,7 +41,7 @@ static const float irradiance[] = {
1.61993437242451854274f, 1.57083597368892080581f, 1.51932335059305478886f,
1.46628494965214395407f, 1.41245852740172450623f, 1.35844961970384092709f,
1.30474913844739281998f, 1.25174963272610817455f, 1.19975998755420620867f};
-/* Rayleigh scattering coefficient */
+/* Rayleigh scattering coefficient (m^-1) */
static const float rayleigh_coeff[] = {
0.00005424820087636473f, 0.00004418549866505454f, 0.00003635151910165377f,
0.00003017929012024763f, 0.00002526320226989157f, 0.00002130859310621843f,
@@ -49,7 +50,7 @@ static const float rayleigh_coeff[] = {
0.00000765513700977967f, 0.00000674217203751443f, 0.00000596134125832052f,
0.00000529034598065810f, 0.00000471115687557433f, 0.00000420910481110487f,
0.00000377218381260133f, 0.00000339051255477280f, 0.00000305591531679811f};
-/* Ozone absorption coefficient */
+/* Ozone absorption coefficient (m^-1) */
static const float ozone_coeff[] = {
0.00000000325126849861f, 0.00000000585395365047f, 0.00000001977191155085f,
0.00000007309568762914f, 0.00000020084561514287f, 0.00000040383958096161f,
@@ -94,11 +95,10 @@ static float3 spec_to_xyz(float *spectrum)
xyz.y += cmf_xyz[i][1] * spectrum[i];
xyz.z += cmf_xyz[i][2] * spectrum[i];
}
- return xyz * step_lambda * max_luminous_efficacy;
+ return xyz * step_lambda;
}
/* Atmosphere volume models */
-
static float density_rayleigh(float height)
{
return expf(-height / rayleigh_scale);
@@ -135,11 +135,13 @@ static bool surface_intersection(float3 pos, float3 dir)
{
if (dir.z >= 0)
return false;
- float t = dot(dir, -pos) / len_squared(dir);
- float D = pos.x * pos.x - 2.0f * (-pos.x) * dir.x * t + dir.x * t * dir.x * t + pos.y * pos.y -
- 2.0f * (-pos.y) * dir.y * t + (dir.y * t) * (dir.y * t) + pos.z * pos.z -
- 2.0f * (-pos.z) * dir.z * t + dir.z * t * dir.z * t;
- return (D <= sqr(earth_radius));
+ float b = -2.0f * dot(dir, -pos);
+ float c = len_squared(pos) - sqr(earth_radius);
+ float t = b * b - 4.0f * c;
+ if (t >= 0.0f)
+ return true;
+ else
+ return false;
}
static float3 atmosphere_intersection(float3 pos, float3 dir)
@@ -152,41 +154,40 @@ static float3 atmosphere_intersection(float3 pos, float3 dir)
static float3 ray_optical_depth(float3 ray_origin, float3 ray_dir)
{
- /* This code computes the optical depth along a ray through the atmosphere. */
+ /* this code computes the optical depth along a ray through the atmosphere */
float3 ray_end = atmosphere_intersection(ray_origin, ray_dir);
float ray_length = distance(ray_origin, ray_end);
- /* To compute the optical depth, we step along the ray in segments and
- * accumulate the optical depth along each segment. */
+ /* to compute the optical depth, we step along the ray in segments and
+ * accumulate the optical depth along each segment */
float segment_length = ray_length / steps_light;
float3 segment = segment_length * ray_dir;
- /* Instead of tracking the transmission spectrum across all wavelengths directly,
+ /* instead of tracking the transmission spectrum across all wavelengths directly,
* we use the fact that the density always has the same spectrum for each type of
* scattering, so we split the density into a constant spectrum and a factor and
- * only track the factors. */
+ * only track the factors */
float3 optical_depth = make_float3(0.0f, 0.0f, 0.0f);
- /* The density of each segment is evaluated at its middle. */
+ /* the density of each segment is evaluated at its middle */
float3 P = ray_origin + 0.5f * segment;
for (int i = 0; i < steps_light; i++) {
- /* Compute height above sea level. */
+ /* height above sea level */
float height = len(P) - earth_radius;
- /* Accumulate optical depth of this segment (density is assumed to be constant along it). */
+ /* accumulate optical depth of this segment (density is assumed to be constant along it) */
float3 density = make_float3(
density_rayleigh(height), density_mie(height), density_ozone(height));
optical_depth += density;
- /* Advance along ray. */
+ /* advance along ray */
P += segment;
}
return optical_depth * segment_length;
}
-/* Single Scattering implementation */
static void single_scattering(float3 ray_dir,
float3 sun_dir,
float3 ray_origin,
@@ -195,45 +196,45 @@ static void single_scattering(float3 ray_dir,
float ozone_density,
float *r_spectrum)
{
- /* This code computes single-inscattering along a ray through the atmosphere. */
+ /* this code computes single-inscattering along a ray through the atmosphere */
float3 ray_end = atmosphere_intersection(ray_origin, ray_dir);
float ray_length = distance(ray_origin, ray_end);
- /* To compute the inscattering, we step along the ray in segments and accumulate
- * the inscattering as well as the optical depth along each segment. */
+ /* to compute the inscattering, we step along the ray in segments and accumulate
+ * the inscattering as well as the optical depth along each segment */
float segment_length = ray_length / steps;
float3 segment = segment_length * ray_dir;
- /* Instead of tracking the transmission spectrum across all wavelengths directly,
+ /* instead of tracking the transmission spectrum across all wavelengths directly,
* we use the fact that the density always has the same spectrum for each type of
* scattering, so we split the density into a constant spectrum and a factor and
- * only track the factors. */
+ * only track the factors */
float3 optical_depth = make_float3(0.0f, 0.0f, 0.0f);
- /* Zero out light accumulation. */
+ /* zero out light accumulation */
for (int wl = 0; wl < num_wavelengths; wl++) {
r_spectrum[wl] = 0.0f;
}
- /* Compute phase function for scattering and the density scale factor. */
+ /* phase function for scattering and the density scale factor */
float mu = dot(ray_dir, sun_dir);
float3 phase_function = make_float3(phase_rayleigh(mu), phase_mie(mu), 0.0f);
float3 density_scale = make_float3(air_density, dust_density, ozone_density);
- /* The density and in-scattering of each segment is evaluated at its middle. */
+ /* the density and in-scattering of each segment is evaluated at its middle */
float3 P = ray_origin + 0.5f * segment;
for (int i = 0; i < steps; i++) {
- /* Compute height above sea level. */
+ /* height above sea level */
float height = len(P) - earth_radius;
- /* Evaluate and accumulate optical depth along the ray. */
+ /* evaluate and accumulate optical depth along the ray */
float3 density = density_scale * make_float3(density_rayleigh(height),
density_mie(height),
density_ozone(height));
optical_depth += segment_length * density;
- /* If the earth isn't in the way, evaluate inscattering from the sun. */
+ /* if the Earth isn't in the way, evaluate inscattering from the sun */
if (!surface_intersection(P, sun_dir)) {
float3 light_optical_depth = density_scale * ray_optical_depth(P, sun_dir);
float3 total_optical_depth = optical_depth + light_optical_depth;
@@ -247,7 +248,7 @@ static void single_scattering(float3 ray_dir,
float3 scattering_density = density * make_float3(rayleigh_coeff[wl], mie_coeff, 0.0f);
- /* The total inscattered radiance from one segment is:
+ /* the total inscattered radiance from one segment is:
* Tr(A<->B) * Tr(B<->C) * sigma_s * phase * L * segment_length
*
* These terms are:
@@ -258,19 +259,18 @@ static void single_scattering(float3 ray_dir,
* length of the segment
*
* The code here is just that, with a bit of additional optimization to not store full
- * spectra for the optical depth.
+ * spectra for the optical depth
*/
r_spectrum[wl] += attenuation * reduce_add(phase_function * scattering_density) *
irradiance[wl] * segment_length;
}
}
- /* Advance along ray. */
+ /* advance along ray */
P += segment;
}
}
-/* calculate texture array */
void SKY_nishita_skymodel_precompute_texture(float *pixels,
int stride,
int start_y,
@@ -305,6 +305,7 @@ void SKY_nishita_skymodel_precompute_texture(float *pixels,
single_scattering(dir, sun_dir, cam_pos, air_density, dust_density, ozone_density, spectrum);
float3 xyz = spec_to_xyz(spectrum);
+ /* store pixels */
int pos_x = x * stride;
pixel_row[pos_x] = xyz.x;
pixel_row[pos_x + 1] = xyz.y;
@@ -318,7 +319,7 @@ void SKY_nishita_skymodel_precompute_texture(float *pixels,
}
}
-/* Sun disc */
+/*********** Sun ***********/
static void sun_radiation(float3 cam_dir,
float altitude,
float air_density,
@@ -329,9 +330,9 @@ static void sun_radiation(float3 cam_dir,
float3 cam_pos = make_float3(0, 0, earth_radius + altitude);
float3 optical_depth = ray_optical_depth(cam_pos, cam_dir);
- /* Compute final spectrum. */
+ /* compute final spectrum */
for (int i = 0; i < num_wavelengths; i++) {
- /* Combine spectra and the optical depth into transmittance. */
+ /* combine spectra and the optical depth into transmittance */
float transmittance = rayleigh_coeff[i] * optical_depth.x * air_density +
1.11f * mie_coeff * optical_depth.y * dust_density;
r_spectrum[i] = irradiance[i] * expf(-transmittance) / solid_angle;
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index f37edd05fd2..257ef420ef9 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -97,9 +97,7 @@ class FILEBROWSER_PT_filter(Panel):
params = space.params
is_lib_browser = params.use_library_browsing
- row = layout.row(align=True)
- row.prop(params, "use_filter", text="", toggle=False)
- row.label(text="Filter")
+ layout.prop(params, "use_filter", text="Filter", toggle=False)
col = layout.column()
col.active = params.use_filter
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index 080e66b59e7..50316f50474 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -271,19 +271,24 @@ class ToolSelectPanelHelper:
yield item, i
i += 1
- # Special internal function, gives use items that contain keymaps.
@staticmethod
- def _tools_flatten_with_keymap(tools):
+ def _tools_flatten_with_dynamic(tools, *, context):
+ """
+ Expands dynamic items, indices aren't aligned with other flatten functions.
+ The context may be None, use as signal to return all items.
+ """
for item_parent in tools:
if item_parent is None:
- continue
+ yield None
for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
- # skip None or generator function
- if item is None or _item_is_fn(item):
- continue
- if item.keymap is not None:
+ if item is None:
+ yield None
+ elif _item_is_fn(item):
+ yield from ToolSelectPanelHelper._tools_flatten_with_dynamic(item(context), context=context)
+ else:
yield item
+
@classmethod
def _tool_get_active(cls, context, space_type, mode, with_icon=False):
"""
@@ -484,8 +489,12 @@ class ToolSelectPanelHelper:
else:
context_descr = context_mode.replace("_", " ").title()
- for item in cls._tools_flatten_with_keymap(tools):
+ for item in cls._tools_flatten_with_dynamic(tools, context=None):
+ if item is None:
+ continue
keymap_data = item.keymap
+ if keymap_data is None:
+ continue
if callable(keymap_data[0]):
cls._km_action_simple(kc_default, kc_default, context_descr, item.label, keymap_data)
@@ -498,8 +507,13 @@ class ToolSelectPanelHelper:
for context_mode_test, tools in cls.tools_all():
if context_mode_test == context_mode:
- for item in cls._tools_flatten_with_keymap(tools):
- km_name = item.keymap[0]
+ for item in cls._tools_flatten(tools):
+ if item is None:
+ continue
+ keymap_data = item.keymap
+ if keymap_data is None:
+ continue
+ km_name = keymap_data[0]
# print((km.name, cls.bl_space_type, 'WINDOW', []))
if km_name in visited:
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index b7852eb92e0..ce48b92c419 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -2496,15 +2496,17 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
_defs_sculpt.cloth_filter,
lambda context: (
(_defs_sculpt.color_filter,)
- if bpy.context.preferences.view.show_developer_ui and \
- bpy.context.preferences.experimental.use_sculpt_vertex_colors
+ if context is None or (
+ context.preferences.view.show_developer_ui and
+ context.preferences.experimental.use_sculpt_vertex_colors)
else ()
),
None,
lambda context: (
(_defs_sculpt.mask_by_color,)
- if bpy.context.preferences.view.show_developer_ui and \
- bpy.context.preferences.experimental.use_sculpt_vertex_colors
+ if context is None or (
+ context.preferences.view.show_developer_ui and
+ context.preferences.experimental.use_sculpt_vertex_colors)
else ()
),
None,
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 077b53559aa..007b8c933ce 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -6169,7 +6169,7 @@ class VIEW3D_PT_overlay_motion_tracking(Panel):
def draw_header(self, context):
view = context.space_data
- self.layout.prop(view, "show_reconstruction", text="")
+ self.layout.prop(view, "show_reconstruction", text=self.bl_label)
def draw(self, context):
layout = self.layout
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 104582be932..43071c2966d 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -32,6 +32,7 @@ extern "C" {
#endif
/* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */
+struct AnimationEvalContext;
struct FCurve;
struct Main;
struct Object;
@@ -202,7 +203,7 @@ void what_does_obaction(struct Object *ob,
struct bPose *pose,
struct bAction *act,
char groupname[],
- float cframe);
+ const struct AnimationEvalContext *anim_eval_context);
/* for proxy */
void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto,
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 4a2ad28f90f..ddfe6b61cfb 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -48,6 +48,23 @@ struct bAction;
struct bActionGroup;
struct bContext;
+/* Container for data required to do FCurve and Driver evaluation. */
+typedef struct AnimationEvalContext {
+ /* For drivers, so that they have access to the dependency graph and the current view layer. See
+ * T77086. */
+ struct Depsgraph *depsgraph;
+
+ /* FCurves and Drivers can be evaluated at a different time than the current scene time, for
+ * example when evaluating NLA strips. This means that, even though the current time is stored in
+ * the dependency graph, we need an explicit evaluation time. */
+ float eval_time;
+} AnimationEvalContext;
+
+AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
+ float eval_time);
+AnimationEvalContext BKE_animsys_eval_context_construct_at(
+ const AnimationEvalContext *anim_eval_context, float eval_time);
+
/* ************************************* */
/* KeyingSets API */
@@ -172,11 +189,12 @@ void BKE_fcurves_id_cb(struct ID *id, ID_FCurve_Edit_Callback func, void *user_d
typedef struct NlaKeyframingContext NlaKeyframingContext;
-struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
- struct PointerRNA *ptr,
- struct AnimData *adt,
- float ctime,
- const bool flush_to_original);
+struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
+ struct ListBase *cache,
+ struct PointerRNA *ptr,
+ struct AnimData *adt,
+ const struct AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original);
bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
struct PointerRNA *prop_ptr,
struct PropertyRNA *prop,
@@ -209,7 +227,7 @@ bool BKE_animsys_write_rna_setting(struct PathResolvedRNA *anim_rna, const float
/* Evaluation loop for evaluating animation data */
void BKE_animsys_evaluate_animdata(struct ID *id,
struct AnimData *adt,
- float ctime,
+ const struct AnimationEvalContext *anim_eval_context,
eAnimData_Recalc recalc,
const bool flush_to_original);
@@ -229,14 +247,14 @@ void BKE_animsys_evaluate_all_animation(struct Main *main,
/* Evaluate Action (F-Curve Bag) */
void animsys_evaluate_action(struct PointerRNA *ptr,
struct bAction *act,
- float ctime,
+ const struct AnimationEvalContext *anim_eval_context,
const bool flush_to_original);
/* Evaluate Action Group */
void animsys_evaluate_action_group(struct PointerRNA *ptr,
struct bAction *act,
struct bActionGroup *agrp,
- float ctime);
+ const struct AnimationEvalContext *anim_eval_context);
/* ************************************* */
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index db2fe651c91..25bc2006ee3 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -153,7 +153,8 @@ bool BKE_collection_move(struct Main *bmain,
bool relative_after,
struct Collection *collection);
-bool BKE_collection_find_cycle(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_cycle_find(struct Collection *new_ancestor, struct Collection *collection);
+bool BKE_collection_cycles_fix(struct Main *bmain, struct Collection *collection);
bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index ddd0cc286ab..b846e2e5b7b 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -36,6 +36,7 @@ struct FCurve;
struct FModifier;
struct AnimData;
+struct AnimationEvalContext;
struct BezTriple;
struct LibraryForeachIDData;
struct PathResolvedRNA;
@@ -281,10 +282,12 @@ float evaluate_fcurve_only_curve(struct FCurve *fcu, float evaltime);
float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna,
struct FCurve *fcu,
struct ChannelDriver *driver_orig,
- float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
bool BKE_fcurve_is_empty(struct FCurve *fcu);
/* evaluate fcurve and store value */
-float calculate_fcurve(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, float evaltime);
+float calculate_fcurve(struct PathResolvedRNA *anim_rna,
+ struct FCurve *fcu,
+ const struct AnimationEvalContext *anim_eval_context);
/* ************* F-Curve Samples API ******************** */
diff --git a/source/blender/blenkernel/BKE_fcurve_driver.h b/source/blender/blenkernel/BKE_fcurve_driver.h
index 563ed408ed7..6803485f843 100644
--- a/source/blender/blenkernel/BKE_fcurve_driver.h
+++ b/source/blender/blenkernel/BKE_fcurve_driver.h
@@ -30,6 +30,7 @@
extern "C" {
#endif
+struct AnimationEvalContext;
struct ChannelDriver;
struct DriverTarget;
struct DriverVar;
@@ -97,7 +98,7 @@ void BKE_driver_invalidate_expression(struct ChannelDriver *driver,
float evaluate_driver(struct PathResolvedRNA *anim_rna,
struct ChannelDriver *driver,
struct ChannelDriver *driver_orig,
- const float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index b35d2183408..0ee2fcb1963 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -1612,8 +1612,12 @@ void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
/* For the calculation of the effects of an Action at the given frame on an object
* This is currently only used for the Action Constraint
*/
-void what_does_obaction(
- Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe)
+void what_does_obaction(Object *ob,
+ Object *workob,
+ bPose *pose,
+ bAction *act,
+ char groupname[],
+ const AnimationEvalContext *anim_eval_context)
{
bActionGroup *agrp = BKE_action_group_find_name(act, groupname);
@@ -1669,7 +1673,7 @@ void what_does_obaction(
RNA_id_pointer_create(&workob->id, &id_ptr);
/* execute action for this group only */
- animsys_evaluate_action_group(&id_ptr, act, agrp, cframe);
+ animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context);
}
else {
AnimData adt = {NULL};
@@ -1680,6 +1684,6 @@ void what_does_obaction(
adt.action = act;
/* execute effects of Action on to workob (or it's PoseChannels) */
- BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM, false);
+ BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false);
}
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 09d6ba4ff44..ea5a4bd99d1 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -538,7 +538,7 @@ static void animsys_write_orig_anim_rna(PointerRNA *ptr,
*/
static void animsys_evaluate_fcurves(PointerRNA *ptr,
ListBase *list,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
bool flush_to_original)
{
/* Calculate then execute each curve. */
@@ -557,7 +557,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
}
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
BKE_animsys_write_rna_setting(&anim_rna, curval);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
@@ -569,8 +569,26 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
/* ***************************************** */
/* Driver Evaluation */
+AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph,
+ float eval_time)
+{
+ AnimationEvalContext ctx = {
+ .depsgraph = depsgraph,
+ .eval_time = eval_time,
+ };
+ return ctx;
+}
+
+AnimationEvalContext BKE_animsys_eval_context_construct_at(
+ const AnimationEvalContext *anim_eval_context, float eval_time)
+{
+ return BKE_animsys_eval_context_construct(anim_eval_context->depsgraph, eval_time);
+}
+
/* Evaluate Drivers */
-static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime)
+static void animsys_evaluate_drivers(PointerRNA *ptr,
+ AnimData *adt,
+ const AnimationEvalContext *anim_eval_context)
{
FCurve *fcu;
@@ -591,7 +609,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
* before adding new to only be done when drivers only changed. */
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
}
@@ -647,7 +665,10 @@ static void action_idcode_patch_check(ID *id, bAction *act)
/* ----------------------------------------- */
/* Evaluate Action Group */
-void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *agrp, float ctime)
+void animsys_evaluate_action_group(PointerRNA *ptr,
+ bAction *act,
+ bActionGroup *agrp,
+ const AnimationEvalContext *anim_eval_context)
{
FCurve *fcu;
@@ -669,7 +690,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) {
PathResolvedRNA anim_rna;
if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
BKE_animsys_write_rna_setting(&anim_rna, curval);
}
}
@@ -679,7 +700,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
/* Evaluate Action (F-Curve Bag) */
static void animsys_evaluate_action_ex(PointerRNA *ptr,
bAction *act,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
/* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */
@@ -690,15 +711,15 @@ static void animsys_evaluate_action_ex(PointerRNA *ptr,
action_idcode_patch_check(ptr->owner_id, act);
/* calculate then execute each curve */
- animsys_evaluate_fcurves(ptr, &act->curves, ctime, flush_to_original);
+ animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original);
}
void animsys_evaluate_action(PointerRNA *ptr,
bAction *act,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
- animsys_evaluate_action_ex(ptr, act, ctime, flush_to_original);
+ animsys_evaluate_action_ex(ptr, act, anim_eval_context, flush_to_original);
}
/* ***************************************** */
@@ -726,7 +747,9 @@ static float nlastrip_get_influence(NlaStrip *strip, float cframe)
}
/* evaluate the evaluation time and influence for the strip, storing the results in the strip */
-static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool flush_to_original)
+static void nlastrip_evaluate_controls(NlaStrip *strip,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
/* now strip's evaluate F-Curves for these settings (if applicable) */
if (strip->fcurves.first) {
@@ -736,7 +759,7 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
/* execute these settings as per normal */
- animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, ctime, flush_to_original);
+ animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, anim_eval_context, flush_to_original);
}
/* analytically generate values for influence and time (if applicable)
@@ -744,17 +767,18 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
* in case the override has been turned off.
*/
if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) {
- strip->influence = nlastrip_get_influence(strip, ctime);
+ strip->influence = nlastrip_get_influence(strip, anim_eval_context->eval_time);
}
/* Bypass evaluation time computation if time mapping is disabled. */
if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
- strip->strip_time = ctime;
+ strip->strip_time = anim_eval_context->eval_time;
return;
}
if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) {
- strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
+ strip->strip_time = nlastrip_get_frame(
+ strip, anim_eval_context->eval_time, NLATIME_CONVERT_EVAL);
}
/* if user can control the evaluation time (using F-Curves), consider the option which allows
@@ -768,12 +792,16 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool
}
/* gets the strip active at the current time for a list of strips for evaluation purposes */
-NlaEvalStrip *nlastrips_ctime_get_strip(
- ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original)
+NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
+ ListBase *strips,
+ short index,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
NlaStrip *strip, *estrip = NULL;
NlaEvalStrip *nes;
short side = 0;
+ float ctime = anim_eval_context->eval_time;
/* loop over strips, checking if they fall within the range */
for (strip = strips->first; strip; strip = strip->next) {
@@ -852,7 +880,9 @@ NlaEvalStrip *nlastrips_ctime_get_strip(
*/
/* TODO: this sounds a bit hacky having a few isolated F-Curves
* stuck on some data it operates on... */
- nlastrip_evaluate_controls(estrip, ctime, flush_to_original);
+ AnimationEvalContext clamped_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, ctime);
+ nlastrip_evaluate_controls(estrip, &clamped_eval_context, flush_to_original);
if (estrip->influence <= 0.0f) {
return NULL;
}
@@ -874,8 +904,12 @@ NlaEvalStrip *nlastrips_ctime_get_strip(
}
/* evaluate controls for the relevant extents of the bordering strips... */
- nlastrip_evaluate_controls(estrip->prev, estrip->start, flush_to_original);
- nlastrip_evaluate_controls(estrip->next, estrip->end, flush_to_original);
+ AnimationEvalContext start_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, estrip->start);
+ AnimationEvalContext end_eval_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, estrip->end);
+ nlastrip_evaluate_controls(estrip->prev, &start_eval_context, flush_to_original);
+ nlastrip_evaluate_controls(estrip->next, &end_eval_context, flush_to_original);
break;
}
@@ -1795,6 +1829,7 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
ListBase tmp_modifiers = {NULL, NULL};
@@ -1836,13 +1871,15 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
tmp_nes.strip = s1;
nlaeval_snapshot_init(&snapshot1, channels, snapshot);
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context, flush_to_original);
/* second strip */
tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
tmp_nes.strip = s2;
nlaeval_snapshot_init(&snapshot2, channels, snapshot);
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context, flush_to_original);
/* accumulate temp-buffer and full-buffer, using the 'real' strip */
nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time);
@@ -1857,6 +1894,7 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
ListBase tmp_modifiers = {NULL, NULL};
@@ -1877,13 +1915,16 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr,
/* find the child-strip to evaluate */
evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start;
- tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime, flush_to_original);
+ AnimationEvalContext child_context = BKE_animsys_eval_context_construct_at(anim_eval_context,
+ evaltime);
+ tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, &child_context, flush_to_original);
/* directly evaluate child strip into accumulation buffer...
* - there's no need to use a temporary buffer (as it causes issues [T40082])
*/
if (tmp_nes) {
- nlastrip_evaluate(ptr, channels, &tmp_modifiers, tmp_nes, snapshot, flush_to_original);
+ nlastrip_evaluate(
+ ptr, channels, &tmp_modifiers, tmp_nes, snapshot, &child_context, flush_to_original);
/* free temp eval-strip */
MEM_freeN(tmp_nes);
@@ -1899,6 +1940,7 @@ void nlastrip_evaluate(PointerRNA *ptr,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
NlaStrip *strip = nes->strip;
@@ -1921,10 +1963,12 @@ void nlastrip_evaluate(PointerRNA *ptr,
nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot);
break;
case NLASTRIP_TYPE_TRANSITION: /* transition */
- nlastrip_evaluate_transition(ptr, channels, modifiers, nes, snapshot, flush_to_original);
+ nlastrip_evaluate_transition(
+ ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
break;
case NLASTRIP_TYPE_META: /* meta */
- nlastrip_evaluate_meta(ptr, channels, modifiers, nes, snapshot, flush_to_original);
+ nlastrip_evaluate_meta(
+ ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original);
break;
default: /* do nothing */
@@ -2072,7 +2116,7 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
static bool animsys_evaluate_nla(NlaEvalData *echannels,
PointerRNA *ptr,
AnimData *adt,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original,
NlaKeyframingContext *r_context)
{
@@ -2120,7 +2164,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
}
/* otherwise, get strip to evaluate for this channel */
- nes = nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime, flush_to_original);
+ nes = nlastrips_ctime_get_strip(
+ &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original);
if (nes) {
nes->track = nlt;
}
@@ -2186,7 +2231,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* add this to our list of evaluation strips */
if (r_context == NULL) {
- nlastrips_ctime_get_strip(&estrips, &dummy_trackslist, -1, ctime, flush_to_original);
+ nlastrips_ctime_get_strip(
+ &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
}
/* If computing the context for keyframing, store data there instead of the list. */
else {
@@ -2196,7 +2242,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
NLASTRIP_EXTEND_HOLD;
r_context->eval_strip = nes = nlastrips_ctime_get_strip(
- NULL, &dummy_trackslist, -1, ctime, flush_to_original);
+ NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original);
/* These setting combinations require no data from strips below, so exit immediately. */
if ((nes == NULL) ||
@@ -2221,7 +2267,13 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
/* 2. for each strip, evaluate then accumulate on top of existing channels,
* but don't set values yet. */
for (nes = estrips.first; nes; nes = nes->next) {
- nlastrip_evaluate(ptr, echannels, NULL, nes, &echannels->eval_snapshot, flush_to_original);
+ nlastrip_evaluate(ptr,
+ echannels,
+ NULL,
+ nes,
+ &echannels->eval_snapshot,
+ anim_eval_context,
+ flush_to_original);
}
/* 3. free temporary evaluation data that's not used elsewhere */
@@ -2235,7 +2287,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels,
*/
static void animsys_calculate_nla(PointerRNA *ptr,
AnimData *adt,
- float ctime,
+ const AnimationEvalContext *anim_eval_context,
const bool flush_to_original)
{
NlaEvalData echannels;
@@ -2243,7 +2295,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
nlaeval_init(&echannels);
/* evaluate the NLA stack, obtaining a set of values to flush */
- if (animsys_evaluate_nla(&echannels, ptr, adt, ctime, flush_to_original, NULL)) {
+ if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) {
/* reset any channels touched by currently inactive actions to default value */
animsys_evaluate_nla_domain(ptr, &echannels, adt);
@@ -2257,7 +2309,7 @@ static void animsys_calculate_nla(PointerRNA *ptr,
CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case");
}
- animsys_evaluate_action(ptr, adt->action, ctime, flush_to_original);
+ animsys_evaluate_action(ptr, adt->action, anim_eval_context, flush_to_original);
}
/* free temp data */
@@ -2275,11 +2327,12 @@ static void animsys_calculate_nla(PointerRNA *ptr,
* \param ptr: RNA pointer to the Object with the animation.
* \return Keyframing context, or NULL if not necessary.
*/
-NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache,
- struct PointerRNA *ptr,
- struct AnimData *adt,
- float ctime,
- const bool flush_to_original)
+NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
+ struct ListBase *cache,
+ struct PointerRNA *ptr,
+ struct AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original)
{
/* No remapping needed if NLA is off or no action. */
if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) ||
@@ -2302,7 +2355,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *ca
ctx->adt = adt;
nlaeval_init(&ctx->nla_channels);
- animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, ctime, flush_to_original, ctx);
+ animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, anim_eval_context, flush_to_original, ctx);
BLI_assert(ELEM(ctx->strip.act, NULL, adt->action));
BLI_addtail(cache, ctx);
@@ -2492,8 +2545,11 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
* and that the flags for which parts of the anim-data settings need to be recalculated
* have been set already by the depsgraph. Now, we use the recalc
*/
-void BKE_animsys_evaluate_animdata(
- ID *id, AnimData *adt, float ctime, eAnimData_Recalc recalc, const bool flush_to_original)
+void BKE_animsys_evaluate_animdata(ID *id,
+ AnimData *adt,
+ const AnimationEvalContext *anim_eval_context,
+ eAnimData_Recalc recalc,
+ const bool flush_to_original)
{
PointerRNA id_ptr;
@@ -2516,11 +2572,11 @@ void BKE_animsys_evaluate_animdata(
/* evaluate NLA-stack
* - active action is evaluated as part of the NLA stack as the last item
*/
- animsys_calculate_nla(&id_ptr, adt, ctime, flush_to_original);
+ animsys_calculate_nla(&id_ptr, adt, anim_eval_context, flush_to_original);
}
/* evaluate Active Action only */
else if (adt->action) {
- animsys_evaluate_action_ex(&id_ptr, adt->action, ctime, flush_to_original);
+ animsys_evaluate_action_ex(&id_ptr, adt->action, anim_eval_context, flush_to_original);
}
}
@@ -2530,7 +2586,7 @@ void BKE_animsys_evaluate_animdata(
* - Drivers should be in the appropriate order to be evaluated without problems...
*/
if (recalc & ADT_RECALC_DRIVERS) {
- animsys_evaluate_drivers(&id_ptr, adt, ctime);
+ animsys_evaluate_drivers(&id_ptr, adt, anim_eval_context);
}
/* always execute 'overrides'
@@ -2558,6 +2614,8 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
}
const bool flush_to_original = DEG_is_active(depsgraph);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
/* macros for less typing
* - only evaluate animation data for id if it has users (and not just fake ones)
@@ -2568,7 +2626,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
for (id = first; id; id = id->next) { \
if (ID_REAL_USERS(id) > 0) { \
AnimData *adt = BKE_animdata_from_id(id); \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
} \
} \
(void)0
@@ -2587,9 +2645,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float
if (ntp->nodetree) { \
AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
BKE_animsys_evaluate_animdata( \
- &ntp->nodetree->id, adt2, ctime, ADT_RECALC_ANIM, flush_to_original); \
+ &ntp->nodetree->id, adt2, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); \
} \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \
} \
} \
(void)0
@@ -2706,7 +2764,10 @@ void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id)
* which should get handled as part of the dependency graph instead. */
DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime);
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM, flush_to_original);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
void BKE_animsys_update_driver_array(ID *id)
@@ -2768,7 +2829,9 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu
if (BKE_animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
/* Evaluate driver, and write results to COW-domain destination */
const float ctime = DEG_get_ctime(depsgraph);
- const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, ctime);
+ const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context);
ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
/* Flush results & status codes to original data for UI (T59984) */
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 4bd0c77af28..6118325c231 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1147,7 +1147,7 @@ void BKE_collections_after_lib_link(Main *bmain)
/** \name Collection Children
* \{ */
-static bool collection_find_instance_recursive(Collection *collection,
+static bool collection_instance_find_recursive(Collection *collection,
Collection *instance_collection)
{
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
@@ -1159,7 +1159,7 @@ static bool collection_find_instance_recursive(Collection *collection,
}
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) {
- if (collection_find_instance_recursive(collection_child->collection, instance_collection)) {
+ if (collection_instance_find_recursive(collection_child->collection, instance_collection)) {
return true;
}
}
@@ -1167,21 +1167,88 @@ static bool collection_find_instance_recursive(Collection *collection,
return false;
}
-bool BKE_collection_find_cycle(Collection *new_ancestor, Collection *collection)
+/**
+ * Find potential cycles in collections.
+ *
+ * \param new_ancestor the potential new owner of given \a collection, or the collection to check
+ * if the later is NULL.
+ * \param collection the collection we want to add to \a new_ancestor, may be NULL if we just want
+ * to ensure \a new_ancestor does not already have cycles.
+ * \return true if a cycle is found.
+ */
+bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
{
if (collection == new_ancestor) {
return true;
}
+ if (collection == NULL) {
+ collection = new_ancestor;
+ }
+
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->parents) {
- if (BKE_collection_find_cycle(parent->collection, collection)) {
+ if (BKE_collection_cycle_find(parent->collection, collection)) {
return true;
}
}
/* Find possible objects in collection or its children, that would instantiate the given ancestor
* collection (that would also make a fully invalid cycle of dependencies) .*/
- return collection_find_instance_recursive(collection, new_ancestor);
+ return collection_instance_find_recursive(collection, new_ancestor);
+}
+
+static bool collection_instance_fix_recursive(Collection *parent_collection,
+ Collection *collection)
+{
+ bool cycles_found = false;
+
+ LISTBASE_FOREACH (CollectionObject *, collection_object, &parent_collection->gobject) {
+ if (collection_object->ob != NULL &&
+ collection_object->ob->instance_collection == collection) {
+ id_us_min(&collection->id);
+ collection_object->ob->instance_collection = NULL;
+ cycles_found = true;
+ }
+ }
+
+ LISTBASE_FOREACH (CollectionChild *, collection_child, &parent_collection->children) {
+ if (collection_instance_fix_recursive(collection_child->collection, collection)) {
+ cycles_found = true;
+ }
+ }
+
+ return cycles_found;
+}
+
+static bool collection_cycle_fix_recursive(Main *bmain,
+ Collection *parent_collection,
+ Collection *collection)
+{
+ bool cycles_found = false;
+
+ LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->parents) {
+ if (BKE_collection_cycle_find(parent->collection, collection)) {
+ BKE_collection_child_remove(bmain, parent->collection, parent_collection);
+ cycles_found = true;
+ }
+ else if (collection_cycle_fix_recursive(bmain, parent->collection, collection)) {
+ cycles_found = true;
+ }
+ }
+
+ return cycles_found;
+}
+
+/**
+ * Find and fix potential cycles in collections.
+ *
+ * \param collection the collection to check for existing cycles.
+ * \return true if cycles are found and fixed.
+ */
+bool BKE_collection_cycles_fix(Main *bmain, Collection *collection)
+{
+ return collection_cycle_fix_recursive(bmain, collection, collection) ||
+ collection_instance_fix_recursive(collection, collection);
}
static CollectionChild *collection_find_child(Collection *parent, Collection *collection)
@@ -1223,7 +1290,7 @@ static bool collection_child_add(Collection *parent,
if (child) {
return false;
}
- if (BKE_collection_find_cycle(parent, collection)) {
+ if (BKE_collection_cycle_find(parent, collection)) {
return false;
}
@@ -1301,7 +1368,7 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
child = child_next) {
child_next = child->next;
- if (child->collection == NULL || BKE_collection_find_cycle(collection, child->collection)) {
+ if (child->collection == NULL || BKE_collection_cycle_find(collection, child->collection)) {
BLI_freelinkN(&collection->children, child);
}
else {
@@ -1464,7 +1531,7 @@ bool BKE_collection_move(Main *bmain,
if (collection->flag & COLLECTION_IS_MASTER) {
return false;
}
- if (BKE_collection_find_cycle(to_parent, collection)) {
+ if (BKE_collection_cycle_find(to_parent, collection)) {
return false;
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 06c28776840..2ef32895db9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -53,6 +53,7 @@
#include "BKE_action.h"
#include "BKE_anim_path.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_bvhutils.h"
#include "BKE_cachefile.h"
@@ -2625,7 +2626,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+static void actcon_get_tarmat(struct Depsgraph *depsgraph,
bConstraint *con,
bConstraintOb *cob,
bConstraintTarget *ct,
@@ -2679,6 +2680,8 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
s = (vec[axis] - data->min) / (data->max - data->min);
CLAMP(s, 0, 1);
t = (s * (data->end - data->start)) + data->start;
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ t);
if (G.debug & G_DEBUG) {
printf("do Action Constraint %s - Ob %s Pchan %s\n",
@@ -2693,7 +2696,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
/* evaluate using workob */
/* FIXME: we don't have any consistent standards on limiting effects on object... */
- what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t);
+ what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, &anim_eval_context);
BKE_object_to_mat4(&workob, ct->matrix);
}
else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
@@ -2710,7 +2713,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
tchan->rotmode = pchan->rotmode;
/* evaluate action using workob (it will only set the PoseChannel in question) */
- what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, t);
+ what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, &anim_eval_context);
/* convert animation to matrices for use here */
BKE_pchan_calc_mat(tchan);
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 746aff1697c..acbbf50701a 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1872,17 +1872,18 @@ float evaluate_fcurve_only_curve(FCurve *fcu, float evaltime)
float evaluate_fcurve_driver(PathResolvedRNA *anim_rna,
FCurve *fcu,
ChannelDriver *driver_orig,
- float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
BLI_assert(fcu->driver != NULL);
float cvalue = 0.0f;
+ float evaltime = anim_eval_context->eval_time;
/* If there is a driver (only if this F-Curve is acting as 'driver'),
* evaluate it to find value to use as "evaltime" since drivers essentially act as alternative
* input (i.e. in place of 'time') for F-Curves. */
if (fcu->driver) {
/* evaltime now serves as input for the curve */
- evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, evaltime);
+ evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, anim_eval_context);
/* only do a default 1-1 mapping if it's unlikely that anything else will set a value... */
if (fcu->totvert == 0) {
@@ -1924,7 +1925,9 @@ bool BKE_fcurve_is_empty(FCurve *fcu)
}
/* Calculate the value of the given F-Curve at the given frame, and set its curval */
-float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime)
+float calculate_fcurve(PathResolvedRNA *anim_rna,
+ FCurve *fcu,
+ const AnimationEvalContext *anim_eval_context)
{
/* only calculate + set curval (overriding the existing value) if curve has
* any data which warrants this...
@@ -1936,10 +1939,10 @@ float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime)
/* calculate and set curval (evaluates driver too if necessary) */
float curval;
if (fcu->driver) {
- curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, evaltime);
+ curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, anim_eval_context);
}
else {
- curval = evaluate_fcurve(fcu, evaltime);
+ curval = evaluate_fcurve(fcu, anim_eval_context->eval_time);
}
fcu->curval = curval; /* debug display only, not thread safe! */
return curval;
diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c
index a0625918a62..10d804f437e 100644
--- a/source/blender/blenkernel/intern/fcurve_driver.c
+++ b/source/blender/blenkernel/intern/fcurve_driver.c
@@ -43,6 +43,7 @@
#include "BLT_translation.h"
#include "BKE_action.h"
+#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_fcurve_driver.h"
@@ -1232,24 +1233,25 @@ static void evaluate_driver_min_max(ChannelDriver *driver)
static void evaluate_driver_python(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
/* check for empty or invalid expression */
if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) {
driver->curval = 0.0f;
}
- else if (!driver_try_evaluate_simple_expr(driver, driver_orig, &driver->curval, evaltime)) {
+ else if (!driver_try_evaluate_simple_expr(
+ driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) {
#ifdef WITH_PYTHON
/* this evaluates the expression using Python, and returns its result:
* - on errors it reports, then returns 0.0f
*/
BLI_mutex_lock(&python_driver_lock);
- driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, evaltime);
+ driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context);
BLI_mutex_unlock(&python_driver_lock);
#else /* WITH_PYTHON*/
- UNUSED_VARS(anim_rna, evaltime);
+ UNUSED_VARS(anim_rna, anim_eval_context);
#endif /* WITH_PYTHON*/
}
}
@@ -1262,7 +1264,7 @@ static void evaluate_driver_python(PathResolvedRNA *anim_rna,
float evaluate_driver(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
/* check if driver can be evaluated */
if (driver_orig->flag & DRIVER_FLAG_INVALID) {
@@ -1279,7 +1281,7 @@ float evaluate_driver(PathResolvedRNA *anim_rna,
evaluate_driver_min_max(driver);
break;
case DRIVER_TYPE_PYTHON: /* expression */
- evaluate_driver_python(anim_rna, driver, driver_orig, evaltime);
+ evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context);
break;
default:
/* special 'hack' - just use stored value
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 52a3521189b..5086145c0ff 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -143,103 +143,78 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int o_shift[3],
int n_shift[3])
{
- int x, y, z;
struct MANTA *fluid_old = fds->fluid;
const int block_size = fds->noise_scale;
int new_shift[3] = {0};
sub_v3_v3v3_int(new_shift, n_shift, o_shift);
- /* allocate new fluid data */
+ /* Allocate new fluid data. */
BKE_fluid_reallocate_fluid(fds, n_res, 0);
int o_total_cells = o_res[0] * o_res[1] * o_res[2];
int n_total_cells = n_res[0] * n_res[1] * n_res[2];
- /* boundary cells will be skipped when copying data */
- int bwidth = fds->boundary_width;
-
- /* copy values from old fluid to new */
+ /* Copy values from old fluid to new fluid object. */
if (o_total_cells > 1 && n_total_cells > 1) {
- /* base smoke */
- float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b;
- float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b;
- float dummy, *dummy_s;
- int *dummy_p;
- /* noise smoke */
+ float *o_dens = manta_smoke_get_density(fluid_old);
+ float *o_react = manta_smoke_get_react(fluid_old);
+ float *o_flame = manta_smoke_get_flame(fluid_old);
+ float *o_fuel = manta_smoke_get_fuel(fluid_old);
+ float *o_heat = manta_smoke_get_heat(fluid_old);
+ float *o_vx = manta_get_velocity_x(fluid_old);
+ float *o_vy = manta_get_velocity_y(fluid_old);
+ float *o_vz = manta_get_velocity_z(fluid_old);
+ float *o_r = manta_smoke_get_color_r(fluid_old);
+ float *o_g = manta_smoke_get_color_g(fluid_old);
+ float *o_b = manta_smoke_get_color_b(fluid_old);
+
+ float *n_dens = manta_smoke_get_density(fds->fluid);
+ float *n_react = manta_smoke_get_react(fds->fluid);
+ float *n_flame = manta_smoke_get_flame(fds->fluid);
+ float *n_fuel = manta_smoke_get_fuel(fds->fluid);
+ float *n_heat = manta_smoke_get_heat(fds->fluid);
+ float *n_vx = manta_get_velocity_x(fds->fluid);
+ float *n_vy = manta_get_velocity_y(fds->fluid);
+ float *n_vz = manta_get_velocity_z(fds->fluid);
+ float *n_r = manta_smoke_get_color_r(fds->fluid);
+ float *n_g = manta_smoke_get_color_g(fds->fluid);
+ float *n_b = manta_smoke_get_color_b(fds->fluid);
+
+ /* Noise smoke fields. */
int wt_res_old[3];
- float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw,
- *o_wt_tcu2, *o_wt_tcv2, *o_wt_tcw2, *o_wt_r, *o_wt_g, *o_wt_b;
- float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw,
- *n_wt_tcu2, *n_wt_tcv2, *n_wt_tcw2, *n_wt_r, *n_wt_g, *n_wt_b;
-
- if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- manta_smoke_turbulence_export(fluid_old,
- &o_wt_dens,
- &o_wt_react,
- &o_wt_flame,
- &o_wt_fuel,
- &o_wt_r,
- &o_wt_g,
- &o_wt_b,
- &o_wt_tcu,
- &o_wt_tcv,
- &o_wt_tcw,
- &o_wt_tcu2,
- &o_wt_tcv2,
- &o_wt_tcw2);
- manta_smoke_turbulence_get_res(fluid_old, wt_res_old);
- manta_smoke_turbulence_export(fds->fluid,
- &n_wt_dens,
- &n_wt_react,
- &n_wt_flame,
- &n_wt_fuel,
- &n_wt_r,
- &n_wt_g,
- &n_wt_b,
- &n_wt_tcu,
- &n_wt_tcv,
- &n_wt_tcw,
- &n_wt_tcu2,
- &n_wt_tcv2,
- &n_wt_tcw2);
- }
-
- manta_smoke_export(fluid_old,
- &dummy,
- &dummy,
- &o_dens,
- &o_react,
- &o_flame,
- &o_fuel,
- &o_heat,
- &o_vx,
- &o_vy,
- &o_vz,
- &o_r,
- &o_g,
- &o_b,
- &dummy_p,
- &dummy_s);
- manta_smoke_export(fds->fluid,
- &dummy,
- &dummy,
- &n_dens,
- &n_react,
- &n_flame,
- &n_fuel,
- &n_heat,
- &n_vx,
- &n_vy,
- &n_vz,
- &n_r,
- &n_g,
- &n_b,
- &dummy_p,
- &dummy_s);
-
- for (x = o_min[0]; x < o_max[0]; x++) {
- for (y = o_min[1]; y < o_max[1]; y++) {
- for (z = o_min[2]; z < o_max[2]; z++) {
+ float *o_wt_dens = manta_noise_get_density(fluid_old);
+ float *o_wt_react = manta_noise_get_react(fluid_old);
+ float *o_wt_flame = manta_noise_get_flame(fluid_old);
+ float *o_wt_fuel = manta_noise_get_fuel(fluid_old);
+ float *o_wt_r = manta_noise_get_color_r(fluid_old);
+ float *o_wt_g = manta_noise_get_color_g(fluid_old);
+ float *o_wt_b = manta_noise_get_color_b(fluid_old);
+ float *o_wt_tcu = manta_noise_get_texture_u(fluid_old);
+ float *o_wt_tcv = manta_noise_get_texture_v(fluid_old);
+ float *o_wt_tcw = manta_noise_get_texture_w(fluid_old);
+ float *o_wt_tcu2 = manta_noise_get_texture_u2(fluid_old);
+ float *o_wt_tcv2 = manta_noise_get_texture_v2(fluid_old);
+ float *o_wt_tcw2 = manta_noise_get_texture_w2(fluid_old);
+
+ float *n_wt_dens = manta_noise_get_density(fds->fluid);
+ float *n_wt_react = manta_noise_get_react(fds->fluid);
+ float *n_wt_flame = manta_noise_get_flame(fds->fluid);
+ float *n_wt_fuel = manta_noise_get_fuel(fds->fluid);
+ float *n_wt_r = manta_noise_get_color_r(fds->fluid);
+ float *n_wt_g = manta_noise_get_color_g(fds->fluid);
+ float *n_wt_b = manta_noise_get_color_b(fds->fluid);
+ float *n_wt_tcu = manta_noise_get_texture_u(fds->fluid);
+ float *n_wt_tcv = manta_noise_get_texture_v(fds->fluid);
+ float *n_wt_tcw = manta_noise_get_texture_w(fds->fluid);
+ float *n_wt_tcu2 = manta_noise_get_texture_u2(fds->fluid);
+ float *n_wt_tcv2 = manta_noise_get_texture_v2(fds->fluid);
+ float *n_wt_tcw2 = manta_noise_get_texture_w2(fds->fluid);
+
+ manta_noise_get_res(fluid_old, wt_res_old);
+
+ for (int z = o_min[2]; z < o_max[2]; z++) {
+ for (int y = o_min[1]; y < o_max[1]; y++) {
+ for (int x = o_min[0]; x < o_max[0]; x++) {
/* old grid index */
int xo = x - o_min[0];
int yo = y - o_min[1];
@@ -251,20 +226,31 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
int zn = z - n_min[2] - new_shift[2];
int index_new = manta_get_index(xn, n_res[0], yn, n_res[1], zn);
- /* skip if outside new domain */
+ /* Skip if outside new domain. */
if (xn < 0 || xn >= n_res[0] || yn < 0 || yn >= n_res[1] || zn < 0 || zn >= n_res[2]) {
continue;
}
- /* skip if trying to copy from old boundary cell */
+# if 0
+ /* Note (sebbas):
+ * Disabling this "skip section" as not copying borders results in weird cut-off effects.
+ * It is possible that this cutting off is the reason for line effects as seen in T74559.
+ * Since domain borders will be handled on the simulation side anyways,
+ * copying border values should not be an issue. */
+
+ /* boundary cells will be skipped when copying data */
+ int bwidth = fds->boundary_width;
+
+ /* Skip if trying to copy from old boundary cell. */
if (xo < bwidth || yo < bwidth || zo < bwidth || xo >= o_res[0] - bwidth ||
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth) {
continue;
}
- /* skip if trying to copy into new boundary cell */
+ /* Skip if trying to copy into new boundary cell. */
if (xn < bwidth || yn < bwidth || zn < bwidth || xn >= n_res[0] - bwidth ||
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth) {
continue;
}
+# endif
/* copy data */
if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
@@ -1406,8 +1392,7 @@ static void update_obstacles(Depsgraph *depsgraph,
/* Cannot use static mode with adaptive domain.
* The adaptive domain might expand and only later in the simulations discover the static
* object. */
- bool is_static = is_static_object(effecobj) &&
- ((fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) == 0);
+ bool is_static = is_static_object(effecobj) && !use_adaptivedomain;
/* Check for initialized effector object. */
if ((fmd2->type & MOD_FLUID_TYPE_EFFEC) && fmd2->effector) {
@@ -2264,15 +2249,15 @@ static void adaptive_domain_adjust(
int x, y, z;
float *density = manta_smoke_get_density(fds->fluid);
float *fuel = manta_smoke_get_fuel(fds->fluid);
- float *bigdensity = manta_smoke_turbulence_get_density(fds->fluid);
- float *bigfuel = manta_smoke_turbulence_get_fuel(fds->fluid);
+ float *bigdensity = manta_noise_get_density(fds->fluid);
+ float *bigfuel = manta_noise_get_fuel(fds->fluid);
float *vx = manta_get_velocity_x(fds->fluid);
float *vy = manta_get_velocity_y(fds->fluid);
float *vz = manta_get_velocity_z(fds->fluid);
int wt_res[3];
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- manta_smoke_turbulence_get_res(fds->fluid, wt_res);
+ manta_noise_get_res(fds->fluid, wt_res);
}
INIT_MINMAX(min_vel, max_vel);
@@ -3951,6 +3936,12 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
break;
}
+ /* Adaptive domain needs to know about current state, so save it here. */
+ copy_v3_v3_int(o_res, fds->res);
+ copy_v3_v3_int(o_min, fds->res_min);
+ copy_v3_v3_int(o_max, fds->res_max);
+ copy_v3_v3_int(o_shift, fds->shift);
+
bool read_partial = false, read_all = false;
/* Try to read from cache and keep track of read success. */
if (read_cache) {
@@ -3983,28 +3974,15 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
has_config = manta_read_config(fds->fluid, fmd, noise_frame);
/* Only reallocate when just reading cache or when resuming during bake. */
- if ((!baking_noise || (baking_noise && resume_noise)) && has_config &&
- manta_needs_realloc(fds->fluid, fmd)) {
- BKE_fluid_reallocate_fluid(fds, fds->res, 1);
+ if (has_data && has_config && manta_needs_realloc(fds->fluid, fmd)) {
+ BKE_fluid_reallocate_copy_fluid(
+ fds, o_res, fds->res, o_min, fds->res_min, o_max, o_shift, fds->shift);
}
read_partial = !baking_data && !baking_noise && next_noise;
read_all = !read_partial && with_resumable_cache;
has_noise = manta_read_noise(fds->fluid, fmd, noise_frame, read_all);
- /* When using the adaptive domain, copy all data that was read to a new fluid object. */
- if (with_adaptive && baking_noise) {
- /* Adaptive domain needs to know about current state, so save it, then copy. */
- copy_v3_v3_int(o_res, fds->res);
- copy_v3_v3_int(o_min, fds->res_min);
- copy_v3_v3_int(o_max, fds->res_max);
- copy_v3_v3_int(o_shift, fds->shift);
- if (has_config && manta_needs_realloc(fds->fluid, fmd)) {
- BKE_fluid_reallocate_copy_fluid(
- fds, o_res, fds->res, o_min, fds->res_min, o_max, o_shift, fds->shift);
- }
- }
-
read_partial = !baking_data && !baking_noise && next_data && next_noise;
read_all = !read_partial && with_resumable_cache;
has_data = manta_read_data(fds->fluid, fmd, data_frame, read_all);
@@ -4316,7 +4294,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
{
float bv[6] = {0};
float light[3];
- int a, z, slabsize = fds->res[0] * fds->res[1], size = fds->res[0] * fds->res[1] * fds->res[2];
+ int slabsize = fds->res[0] * fds->res[1];
float *density = manta_smoke_get_density(fds->fluid);
float *shadow = manta_smoke_get_shadow(fds->fluid);
float correct = -7.0f * fds->dx;
@@ -4325,54 +4303,49 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
return;
}
- /* convert light pos to sim cell space */
+ /* Convert light pos to sim cell space. */
mul_m4_v3(fds->imat, light);
light[0] = (light[0] - fds->p0[0]) / fds->cell_size[0] - 0.5f - (float)fds->res_min[0];
light[1] = (light[1] - fds->p0[1]) / fds->cell_size[1] - 0.5f - (float)fds->res_min[1];
light[2] = (light[2] - fds->p0[2]) / fds->cell_size[2] - 0.5f - (float)fds->res_min[2];
- for (a = 0; a < size; a++) {
- shadow[a] = -1.0f;
- }
-
- /* calculate domain bounds in sim cell space */
+ /* Calculate domain bounds in sim cell space. */
// 0,2,4 = 0.0f
bv[1] = (float)fds->res[0]; // x
bv[3] = (float)fds->res[1]; // y
bv[5] = (float)fds->res[2]; // z
- for (z = 0; z < fds->res[2]; z++) {
+ for (int z = 0; z < fds->res[2]; z++) {
size_t index = z * slabsize;
- int x, y;
- for (y = 0; y < fds->res[1]; y++) {
- for (x = 0; x < fds->res[0]; x++, index++) {
+ for (int y = 0; y < fds->res[1]; y++) {
+ for (int x = 0; x < fds->res[0]; x++, index++) {
float voxel_center[3];
float pos[3];
int cell[3];
float t_ray = 1.0;
- if (shadow[index] >= 0.0f) {
- continue;
- }
+ /* Reset shadow value.*/
+ shadow[index] = -1.0f;
+
voxel_center[0] = (float)x;
voxel_center[1] = (float)y;
voxel_center[2] = (float)z;
- // get starting cell (light pos)
+ /* Get starting cell (light pos). */
if (BLI_bvhtree_bb_raycast(bv, light, voxel_center, pos) > FLT_EPSILON) {
- // we're outside -> use point on side of domain
+ /* We're outside -> use point on side of domain. */
cell[0] = (int)floor(pos[0]);
cell[1] = (int)floor(pos[1]);
cell[2] = (int)floor(pos[2]);
}
else {
- // we're inside -> use light itself
+ /* We're inside -> use light itself. */
cell[0] = (int)floor(light[0]);
cell[1] = (int)floor(light[1]);
cell[2] = (int)floor(light[2]);
}
- /* clamp within grid bounds */
+ /* Clamp within grid bounds */
CLAMP(cell[0], 0, fds->res[0] - 1);
CLAMP(cell[1], 0, fds->res[1] - 1);
CLAMP(cell[2], 0, fds->res[2] - 1);
@@ -4390,7 +4363,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, ViewLayer *v
fds->res,
correct);
- // convention -> from a RGBA float array, use G value for t_ray
+ /* Convention -> from a RGBA float array, use G value for t_ray. */
shadow[index] = t_ray;
}
}
diff --git a/source/blender/blenkernel/intern/lib_id_delete.c b/source/blender/blenkernel/intern/lib_id_delete.c
index b4f2caac861..561db7d62c2 100644
--- a/source/blender/blenkernel/intern/lib_id_delete.c
+++ b/source/blender/blenkernel/intern/lib_id_delete.c
@@ -144,15 +144,14 @@ void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_i
}
#endif
+ Key *key = ((flag & LIB_ID_FREE_NO_MAIN) == 0) ? BKE_key_from_id(id) : NULL;
+
if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
BKE_libblock_relink_ex(bmain, id, NULL, NULL, 0);
}
- if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
- Key *key = BKE_key_from_id(id);
- if (key != NULL) {
- BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
- }
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0 && key != NULL) {
+ BKE_id_free_ex(bmain, &key->id, flag, use_flag_from_idtag);
}
BKE_libblock_free_datablock(id, flag);
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index a6e2b6a7835..322149bc3ce 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1120,11 +1120,11 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
TaskPool *task_pool = BLI_task_pool_create(bmain, TASK_PRIORITY_HIGH);
FOREACH_MAIN_ID_BEGIN (bmain, id) {
- if ((ID_IS_OVERRIDE_LIBRARY_REAL(id) && force_auto) ||
- (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH)) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
+ (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) {
BLI_task_pool_push(task_pool, lib_override_library_operations_create_cb, id, false, NULL);
- id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH;
}
+ id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH;
}
FOREACH_MAIN_ID_END;
@@ -1276,8 +1276,6 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
Key *local_key = BKE_key_from_id(local);
Key *tmp_key = BKE_key_from_id(tmp_id);
if (local_key != NULL && tmp_key != NULL) {
- /* This is some kind of hard-coded 'always enforced override'... */
- tmp_key->from = local_key->from;
tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
}
@@ -1296,6 +1294,12 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
* So when we'll free tmp_id, we'll actually free old, outdated data from local. */
BKE_lib_id_swap(bmain, local, tmp_id);
+ if (local_key != NULL && tmp_key != NULL) {
+ /* This is some kind of hard-coded 'always enforced override'... */
+ BKE_lib_id_swap(bmain, &local_key->id, &tmp_key->id);
+ tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
+ }
+
/* Again, horribly inn-efficient in our case, we need something off-Main
* (aka more generic nolib copy/free stuff)! */
/* XXX And crashing in complex cases (e.g. because depsgraph uses same data...). */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d48ea33cc65..a344d2a163f 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2746,7 +2746,10 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
{
/* Execute drivers and animation. */
const bool flush_to_original = DEG_is_active(depsgraph);
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_ALL, flush_to_original);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ ctime);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ALL, flush_to_original);
object_where_is_calc_ex(depsgraph, scene, ob, ctime, NULL, NULL);
}
@@ -4643,9 +4646,13 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* was originally ID_RECALC_ALL - TODO - which flags are really needed??? */
/* TODO(sergey): What about animation? */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ frame);
+
ob->id.recalc |= ID_RECALC_ALL;
if (update_mesh) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
/* ignore cache clear during subframe updates
* to not mess up cache validity */
object_cacheIgnoreClear(ob, 1);
@@ -4659,12 +4666,14 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph,
/* for curve following objects, parented curve has to be updated too */
if (ob->type == OB_CURVE) {
Curve *cu = ob->data;
- BKE_animsys_evaluate_animdata(&cu->id, cu->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &cu->id, cu->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
}
/* and armatures... */
if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
- BKE_animsys_evaluate_animdata(&arm->id, arm->adt, frame, ADT_RECALC_ANIM, flush_to_original);
+ BKE_animsys_evaluate_animdata(
+ &arm->id, arm->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original);
BKE_pose_where_is(depsgraph, scene, ob);
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index bf9aea81181..bec9cbbad79 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4854,8 +4854,10 @@ void particle_system_update(struct Depsgraph *depsgraph,
for (i = 0; i <= part->hair_step; i++) {
hcfra = 100.0f * (float)i / (float)psys->part->hair_step;
if ((part->flag & PART_HAIR_REGROW) == 0) {
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, hcfra);
BKE_animsys_evaluate_animdata(
- &part_local->id, part_local->adt, hcfra, ADT_RECALC_ANIM, false);
+ &part_local->id, part_local->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
}
system_step(&sim, hcfra, use_render_params);
psys->cfra = hcfra;
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index 30a371b5b28..ff3829bdebb 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -183,6 +183,10 @@ static float seq_prefetch_cfra(PrefetchJob *pfjob)
{
return pfjob->cfra + pfjob->num_frames_prefetched;
}
+static AnimationEvalContext seq_prefetch_anim_eval_context(PrefetchJob *pfjob)
+{
+ return BKE_animsys_eval_context_construct(pfjob->depsgraph, seq_prefetch_cfra(pfjob));
+}
void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end)
{
@@ -435,8 +439,9 @@ static void *seq_prefetch_frames(void *job)
seq_prefetch_update_depsgraph(pfjob);
AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id);
+ AnimationEvalContext anim_eval_context = seq_prefetch_anim_eval_context(pfjob);
BKE_animsys_evaluate_animdata(
- &pfjob->context_cpy.scene->id, adt, seq_prefetch_cfra(pfjob), ADT_RECALC_ALL, false);
+ &pfjob->context_cpy.scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
/* This is quite hacky solution:
* We need cross-reference original scene with copy for cache.
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 6921a13e2c2..31ae71622f7 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -3361,7 +3361,9 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
/* anim-data */
adt = BKE_animdata_from_id(&mask->id);
- BKE_animsys_evaluate_animdata(&mask_temp->id, adt, mask->sfra + nr, ADT_RECALC_ANIM, false);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ context->depsgraph, mask->sfra + nr);
+ BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false);
maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__);
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index c72747a8c51..67e9afdf7fa 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -32,6 +32,8 @@
extern "C" {
#endif
+struct AnimationEvalContext;
+
/* --------------- NLA Evaluation DataTypes ----------------------- */
/* used for list of strips to accumulate at current time */
@@ -168,13 +170,17 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode);
/* these functions are only defined here to avoid problems with the order
* in which they get defined. */
-NlaEvalStrip *nlastrips_ctime_get_strip(
- ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original);
+NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
+ ListBase *strips,
+ short index,
+ const struct AnimationEvalContext *anim_eval_context,
+ const bool flush_to_original);
void nlastrip_evaluate(PointerRNA *ptr,
NlaEvalData *channels,
ListBase *modifiers,
NlaEvalStrip *nes,
NlaEvalSnapshot *snapshot,
+ const struct AnimationEvalContext *anim_eval_context,
const bool flush_to_original);
void nladata_flush_channels(PointerRNA *ptr,
NlaEvalData *channels,
diff --git a/source/blender/blenlib/BLI_allocator.hh b/source/blender/blenlib/BLI_allocator.hh
index d57703f71bc..d49b98cb33b 100644
--- a/source/blender/blenlib/BLI_allocator.hh
+++ b/source/blender/blenlib/BLI_allocator.hh
@@ -84,8 +84,8 @@ class RawAllocator {
void *ptr = malloc(size + alignment + sizeof(MemHead));
void *used_ptr = (void *)((uintptr_t)POINTER_OFFSET(ptr, alignment + sizeof(MemHead)) &
~((uintptr_t)alignment - 1));
- uint offset = (uint)((uintptr_t)used_ptr - (uintptr_t)ptr);
- BLI_assert(offset >= sizeof(MemHead));
+ int offset = (int)((uintptr_t)used_ptr - (uintptr_t)ptr);
+ BLI_assert((size_t)offset >= sizeof(MemHead));
((MemHead *)used_ptr - 1)->offset = (int)offset;
return used_ptr;
}
diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh
index c411fc50f15..c7b4bdc977f 100644
--- a/source/blender/blenlib/BLI_array.hh
+++ b/source/blender/blenlib/BLI_array.hh
@@ -13,6 +13,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
#ifndef __BLI_ARRAY_HH__
#define __BLI_ARRAY_HH__
@@ -52,11 +53,8 @@ template<
typename T,
/**
* The number of values that can be stored in the array, without doing a heap allocation.
- *
- * When T is large, the small buffer optimization is disabled by default to avoid large
- * unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
/**
* The allocator used by this array. Should rarely be changed, except when you don't want that
* MEM_* functions are used internally.
@@ -68,7 +66,7 @@ class Array {
T *data_;
/** Number of elements in the array. */
- uint size_;
+ int64_t size_;
/** Used for allocations when the inline buffer is too small. */
Allocator allocator_;
@@ -117,7 +115,7 @@ class Array {
* even for non-trivial types. This should not be the default though, because one can easily mess
* up when dealing with uninitialized memory.
*/
- explicit Array(uint size)
+ explicit Array(int64_t size)
{
size_ = size;
data_ = this->get_buffer_for_size(size);
@@ -128,8 +126,9 @@ class Array {
* Create a new array with the given size. All values will be initialized by copying the given
* default.
*/
- Array(uint size, const T &value)
+ Array(int64_t size, const T &value)
{
+ BLI_assert(size >= 0);
size_ = size;
data_ = this->get_buffer_for_size(size);
uninitialized_fill_n(data_, size_, value);
@@ -147,8 +146,9 @@ class Array {
* Usage:
* Array<std::string> my_strings(10, NoInitialization());
*/
- Array(uint size, NoInitialization)
+ Array(int64_t size, NoInitialization)
{
+ BLI_assert(size >= 0);
size_ = size;
data_ = this->get_buffer_for_size(size);
}
@@ -203,14 +203,16 @@ class Array {
return *this;
}
- T &operator[](uint index)
+ T &operator[](int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return data_[index];
}
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return data_[index];
}
@@ -250,7 +252,7 @@ class Array {
/**
* Returns the number of elements in the array.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -264,22 +266,14 @@ class Array {
}
/**
- * Copies the value to all indices in the array.
+ * Copies the given value to every element in the array.
*/
- void fill(const T &value)
+ void fill(const T &value) const
{
initialized_fill_n(data_, size_, value);
}
/**
- * Copies the value to the given indices in the array.
- */
- void fill_indices(Span<uint> indices, const T &value)
- {
- MutableSpan<T>(*this).fill_indices(indices, value);
- }
-
- /**
* Get a pointer to the beginning of the array.
*/
const T *data() const
@@ -340,13 +334,13 @@ class Array {
* Get the value of the InlineBufferCapacity template argument. This is the number of elements
* that can be stored without doing an allocation.
*/
- static uint inline_buffer_capacity()
+ static int64_t inline_buffer_capacity()
{
return InlineBufferCapacity;
}
private:
- T *get_buffer_for_size(uint size)
+ T *get_buffer_for_size(int64_t size)
{
if (size <= InlineBufferCapacity) {
return inline_buffer_;
@@ -356,9 +350,9 @@ class Array {
}
}
- T *allocate(uint size)
+ T *allocate(int64_t size)
{
- return (T *)allocator_.allocate(size * sizeof(T), alignof(T), AT);
+ return (T *)allocator_.allocate((size_t)size * sizeof(T), alignof(T), AT);
}
bool uses_inline_buffer() const
@@ -367,6 +361,13 @@ class Array {
}
};
+/**
+ * Same as a normal Array, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
+using RawArray = Array<T, InlineBufferCapacity, RawAllocator>;
+
} // namespace blender
#endif /* __BLI_ARRAY_HH__ */
diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh
index 265013c0013..72caa5b1118 100644
--- a/source/blender/blenlib/BLI_color.hh
+++ b/source/blender/blenlib/BLI_color.hh
@@ -62,12 +62,12 @@ struct Color4f {
return !(a == b);
}
- uint32_t hash() const
+ uint64_t hash() const
{
- uint32_t x1 = *(uint32_t *)&r;
- uint32_t x2 = *(uint32_t *)&g;
- uint32_t x3 = *(uint32_t *)&b;
- uint32_t x4 = *(uint32_t *)&a;
+ uint64_t x1 = *(uint32_t *)&r;
+ uint64_t x2 = *(uint32_t *)&g;
+ uint64_t x3 = *(uint32_t *)&b;
+ uint64_t x4 = *(uint32_t *)&a;
return (x1 * 1283591) ^ (x2 * 850177) ^ (x3 * 735391) ^ (x4 * 442319);
}
};
@@ -119,10 +119,10 @@ struct Color4b {
return !(a == b);
}
- uint32_t hash() const
+ uint64_t hash() const
{
- return ((uint32_t)r * 1283591) ^ ((uint32_t)g * 850177) ^ ((uint32_t)b * 735391) ^
- ((uint32_t)a * 442319);
+ return ((uint64_t)r * 1283591) ^ ((uint64_t)g * 850177) ^ ((uint64_t)b * 735391) ^
+ ((uint64_t)a * 442319);
}
};
diff --git a/source/blender/blenlib/BLI_disjoint_set.hh b/source/blender/blenlib/BLI_disjoint_set.hh
index 3b8453669aa..e0580709a44 100644
--- a/source/blender/blenlib/BLI_disjoint_set.hh
+++ b/source/blender/blenlib/BLI_disjoint_set.hh
@@ -29,16 +29,17 @@ namespace blender {
class DisjointSet {
private:
- Array<uint> parents_;
- Array<uint> ranks_;
+ Array<int64_t> parents_;
+ Array<int64_t> ranks_;
public:
/**
* Create a new disjoint set with the given size. Initially, every element is in a separate set.
*/
- DisjointSet(uint size) : parents_(size), ranks_(size, 0)
+ DisjointSet(int64_t size) : parents_(size), ranks_(size, 0)
{
- for (uint i = 0; i < size; i++) {
+ BLI_assert(size >= 0);
+ for (int64_t i = 0; i < size; i++) {
parents_[i] = i;
}
}
@@ -47,10 +48,10 @@ class DisjointSet {
* Join the sets containing elements x and y. Nothing happens when they have been in the same set
* before.
*/
- void join(uint x, uint y)
+ void join(int64_t x, int64_t y)
{
- uint root1 = this->find_root(x);
- uint root2 = this->find_root(y);
+ int64_t root1 = this->find_root(x);
+ int64_t root2 = this->find_root(y);
/* x and y are in the same set already. */
if (root1 == root2) {
@@ -71,27 +72,27 @@ class DisjointSet {
/**
* Return true when x and y are in the same set.
*/
- bool in_same_set(uint x, uint y)
+ bool in_same_set(int64_t x, int64_t y)
{
- uint root1 = this->find_root(x);
- uint root2 = this->find_root(y);
+ int64_t root1 = this->find_root(x);
+ int64_t root2 = this->find_root(y);
return root1 == root2;
}
/**
* Find the element that represents the set containing x currently.
*/
- uint find_root(uint x)
+ int64_t find_root(int64_t x)
{
/* Find root by following parents. */
- uint root = x;
+ int64_t root = x;
while (parents_[root] != root) {
root = parents_[root];
}
/* Compress path. */
while (parents_[x] != root) {
- uint parent = parents_[x];
+ int64_t parent = parents_[x];
parents_[x] = root;
x = parent;
}
diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh
index a7c5f1436d1..0870d8c4c30 100644
--- a/source/blender/blenlib/BLI_dot_export.hh
+++ b/source/blender/blenlib/BLI_dot_export.hh
@@ -274,13 +274,13 @@ class NodeWithSocketsRef {
return *node_;
}
- NodePort input(uint index) const
+ NodePort input(int index) const
{
std::string port = "\"in" + std::to_string(index) + "\"";
return NodePort(*node_, port);
}
- NodePort output(uint index) const
+ NodePort output(int index) const
{
std::string port = "\"out" + std::to_string(index) + "\"";
return NodePort(*node_, port);
diff --git a/source/blender/blenlib/BLI_float3.hh b/source/blender/blenlib/BLI_float3.hh
index a36cedad41d..b2633985ac7 100644
--- a/source/blender/blenlib/BLI_float3.hh
+++ b/source/blender/blenlib/BLI_float3.hh
@@ -188,11 +188,11 @@ struct float3 {
z = -z;
}
- uint32_t hash() const
+ uint64_t hash() const
{
- uint32_t x1 = *(uint32_t *)&x;
- uint32_t x2 = *(uint32_t *)&y;
- uint32_t x3 = *(uint32_t *)&z;
+ uint64_t x1 = *(uint32_t *)&x;
+ uint64_t x2 = *(uint32_t *)&y;
+ uint64_t x3 = *(uint32_t *)&z;
return (x1 * 435109) ^ (x2 * 380867) ^ (x3 * 1059217);
}
diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh
index ef83f9ffc19..185cffd13ac 100644
--- a/source/blender/blenlib/BLI_float4x4.hh
+++ b/source/blender/blenlib/BLI_float4x4.hh
@@ -109,10 +109,10 @@ struct float4x4 {
return result;
}
- uint32_t hash() const
+ uint64_t hash() const
{
- uint32_t h = 435109;
- for (uint i = 0; i < 16; i++) {
+ uint64_t h = 435109;
+ for (int i = 0; i < 16; i++) {
float value = ((const float *)this)[i];
h = h * 33 + (*(uint32_t *)&value);
}
diff --git a/source/blender/blenlib/BLI_hash.hh b/source/blender/blenlib/BLI_hash.hh
index 5cd4ce3c1a9..b14a4ca933c 100644
--- a/source/blender/blenlib/BLI_hash.hh
+++ b/source/blender/blenlib/BLI_hash.hh
@@ -38,7 +38,7 @@
* multiple `operator()` in a specialization of #DefaultHash. All those methods have to compute the
* same hash for values that compare equal.
*
- * The computed hash is an unsigned 32 bit integer. Ideally, the hash function would generate
+ * The computed hash is an unsigned 64 bit integer. Ideally, the hash function would generate
* uniformly random hash values for a set of keys. However, in many cases trivial hash functions
* are faster and produce a good enough distribution. In general it is better when more information
* is in the lower bits of the hash. By choosing a good probing strategy, the effects of a bad hash
@@ -49,7 +49,7 @@
* There are three main ways to provide a hash table implementation with a custom hash function.
*
* - When you want to provide a default hash function for your own custom type: Add a `hash`
- * member function to it. The function should return `uint32_t` and take no arguments. This
+ * member function to it. The function should return `uint64_t` and take no arguments. This
* method will be called by the default implementation of #DefaultHash. It will automatically be
* used by hash table implementations.
*
@@ -58,7 +58,7 @@
* either global or BLI namespace.
*
* template<> struct blender::DefaultHash<TheType> {
- * uint32_t operator()(const TheType &value) const {
+ * uint64_t operator()(const TheType &value) const {
* return ...;
* }
* };
@@ -68,7 +68,7 @@
* table explicitly.
*
* struct MyCustomHash {
- * uint32_t operator()(const TheType &value) const {
+ * uint64_t operator()(const TheType &value) const {
* return ...;
* }
* };
@@ -91,7 +91,7 @@ namespace blender {
* that you have to implement a hash function using one of three strategies listed above.
*/
template<typename T> struct DefaultHash {
- uint32_t operator()(const T &value) const
+ uint64_t operator()(const T &value) const
{
return value.hash();
}
@@ -101,7 +101,7 @@ template<typename T> struct DefaultHash {
* Use the same hash function for const and non const variants of a type.
*/
template<typename T> struct DefaultHash<const T> {
- uint32_t operator()(const T &value) const
+ uint64_t operator()(const T &value) const
{
return DefaultHash<T>{}(value);
}
@@ -109,9 +109,9 @@ template<typename T> struct DefaultHash<const T> {
#define TRIVIAL_DEFAULT_INT_HASH(TYPE) \
template<> struct DefaultHash<TYPE> { \
- uint32_t operator()(TYPE value) const \
+ uint64_t operator()(TYPE value) const \
{ \
- return (uint32_t)value; \
+ return (uint64_t)value; \
} \
}
@@ -127,43 +127,29 @@ TRIVIAL_DEFAULT_INT_HASH(int16_t);
TRIVIAL_DEFAULT_INT_HASH(uint16_t);
TRIVIAL_DEFAULT_INT_HASH(int32_t);
TRIVIAL_DEFAULT_INT_HASH(uint32_t);
-
-template<> struct DefaultHash<uint64_t> {
- uint32_t operator()(uint64_t value) const
- {
- uint32_t low = (uint32_t)value;
- uint32_t high = (uint32_t)(value >> 32);
- return low ^ (high * 0x45d9f3b);
- }
-};
-
-template<> struct DefaultHash<int64_t> {
- uint32_t operator()(uint64_t value) const
- {
- return DefaultHash<uint64_t>{}((uint64_t)value);
- }
-};
+TRIVIAL_DEFAULT_INT_HASH(int64_t);
+TRIVIAL_DEFAULT_INT_HASH(uint64_t);
/**
* One should try to avoid using floats as keys in hash tables, but sometimes it is convenient.
*/
template<> struct DefaultHash<float> {
- uint32_t operator()(float value) const
+ uint64_t operator()(float value) const
{
return *(uint32_t *)&value;
}
};
template<> struct DefaultHash<bool> {
- uint32_t operator()(bool value) const
+ uint64_t operator()(bool value) const
{
- return (uint32_t)(value != false) * 1298191;
+ return (uint64_t)(value != false) * 1298191;
}
};
-inline uint32_t hash_string(StringRef str)
+inline uint64_t hash_string(StringRef str)
{
- uint32_t hash = 5381;
+ uint64_t hash = 5381;
for (char c : str) {
hash = hash * 33 + c;
}
@@ -175,21 +161,21 @@ template<> struct DefaultHash<std::string> {
* Take a #StringRef as parameter to support heterogeneous lookups in hash table implementations
* when std::string is used as key.
*/
- uint32_t operator()(StringRef value) const
+ uint64_t operator()(StringRef value) const
{
return hash_string(value);
}
};
template<> struct DefaultHash<StringRef> {
- uint32_t operator()(StringRef value) const
+ uint64_t operator()(StringRef value) const
{
return hash_string(value);
}
};
template<> struct DefaultHash<StringRefNull> {
- uint32_t operator()(StringRef value) const
+ uint64_t operator()(StringRef value) const
{
return hash_string(value);
}
@@ -199,26 +185,26 @@ template<> struct DefaultHash<StringRefNull> {
* While we cannot guarantee that the lower 4 bits of a pointer are zero, it is often the case.
*/
template<typename T> struct DefaultHash<T *> {
- uint32_t operator()(const T *value) const
+ uint64_t operator()(const T *value) const
{
uintptr_t ptr = (uintptr_t)value;
- uint32_t hash = (uint32_t)(ptr >> 4);
+ uint64_t hash = (uint64_t)(ptr >> 4);
return hash;
}
};
template<typename T> struct DefaultHash<std::unique_ptr<T>> {
- uint32_t operator()(const std::unique_ptr<T> &value) const
+ uint64_t operator()(const std::unique_ptr<T> &value) const
{
return DefaultHash<T *>{}(value.get());
}
};
template<typename T1, typename T2> struct DefaultHash<std::pair<T1, T2>> {
- uint32_t operator()(const std::pair<T1, T2> &value) const
+ uint64_t operator()(const std::pair<T1, T2> &value) const
{
- uint32_t hash1 = DefaultHash<T1>{}(value.first);
- uint32_t hash2 = DefaultHash<T2>{}(value.second);
+ uint64_t hash1 = DefaultHash<T1>{}(value.first);
+ uint64_t hash2 = DefaultHash<T2>{}(value.second);
return hash1 ^ (hash2 * 33);
}
};
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index aaed772071d..5d8f8862a09 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -42,59 +42,64 @@ namespace blender {
* Those should eventually be de-duplicated with functions in BLI_math_base.h.
* \{ */
-inline constexpr int is_power_of_2_i_constexpr(const int n)
+inline constexpr int64_t is_power_of_2_constexpr(const int64_t x)
{
- return (n & (n - 1)) == 0;
+ BLI_assert(x >= 0);
+ return (x & (x - 1)) == 0;
}
-inline constexpr uint32_t log2_floor_u_constexpr(const uint32_t x)
+inline constexpr int64_t log2_floor_constexpr(const int64_t x)
{
- return x <= 1 ? 0 : 1 + log2_floor_u_constexpr(x >> 1);
+ BLI_assert(x >= 0);
+ return x <= 1 ? 0 : 1 + log2_floor_constexpr(x >> 1);
}
-inline constexpr uint32_t log2_ceil_u_constexpr(const uint32_t x)
+inline constexpr int64_t log2_ceil_constexpr(const int64_t x)
{
- return (is_power_of_2_i_constexpr((int)x)) ? log2_floor_u_constexpr(x) :
- log2_floor_u_constexpr(x) + 1;
+ BLI_assert(x >= 0);
+ return (is_power_of_2_constexpr((int)x)) ? log2_floor_constexpr(x) : log2_floor_constexpr(x) + 1;
}
-inline constexpr uint32_t power_of_2_max_u_constexpr(const uint32_t x)
+inline constexpr int64_t power_of_2_max_constexpr(const int64_t x)
{
- return 1u << log2_ceil_u_constexpr(x);
+ BLI_assert(x >= 0);
+ return 1ll << log2_ceil_constexpr(x);
}
template<typename IntT> inline constexpr IntT ceil_division(const IntT x, const IntT y)
{
- BLI_STATIC_ASSERT(!std::is_signed_v<IntT>, "");
+ BLI_assert(x >= 0);
+ BLI_assert(y >= 0);
return x / y + ((x % y) != 0);
}
template<typename IntT> inline constexpr IntT floor_division(const IntT x, const IntT y)
{
- BLI_STATIC_ASSERT(!std::is_signed_v<IntT>, "");
+ BLI_assert(x >= 0);
+ BLI_assert(y >= 0);
return x / y;
}
-inline constexpr uint32_t ceil_division_by_fraction(const uint32_t x,
- const uint32_t numerator,
- const uint32_t denominator)
+inline constexpr int64_t ceil_division_by_fraction(const int64_t x,
+ const int64_t numerator,
+ const int64_t denominator)
{
- return (uint32_t)ceil_division((uint64_t)x * (uint64_t)denominator, (uint64_t)numerator);
+ return (int64_t)ceil_division((uint64_t)x * (uint64_t)denominator, (uint64_t)numerator);
}
-inline constexpr uint32_t floor_multiplication_with_fraction(const uint32_t x,
- const uint32_t numerator,
- const uint32_t denominator)
+inline constexpr int64_t floor_multiplication_with_fraction(const int64_t x,
+ const int64_t numerator,
+ const int64_t denominator)
{
- return (uint32_t)((uint64_t)x * (uint64_t)numerator / (uint64_t)denominator);
+ return (int64_t)((uint64_t)x * (uint64_t)numerator / (uint64_t)denominator);
}
-inline constexpr uint32_t total_slot_amount_for_usable_slots(
- const uint32_t min_usable_slots,
- const uint32_t max_load_factor_numerator,
- const uint32_t max_load_factor_denominator)
+inline constexpr int64_t total_slot_amount_for_usable_slots(
+ const int64_t min_usable_slots,
+ const int64_t max_load_factor_numerator,
+ const int64_t max_load_factor_denominator)
{
- return power_of_2_max_u_constexpr(ceil_division_by_fraction(
+ return power_of_2_max_constexpr(ceil_division_by_fraction(
min_usable_slots, max_load_factor_numerator, max_load_factor_denominator));
}
@@ -121,16 +126,16 @@ class LoadFactor {
BLI_assert(numerator < denominator);
}
- void compute_total_and_usable_slots(uint32_t min_total_slots,
- uint32_t min_usable_slots,
- uint32_t *r_total_slots,
- uint32_t *r_usable_slots) const
+ void compute_total_and_usable_slots(int64_t min_total_slots,
+ int64_t min_usable_slots,
+ int64_t *r_total_slots,
+ int64_t *r_usable_slots) const
{
BLI_assert(is_power_of_2_i((int)min_total_slots));
- uint32_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
+ int64_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
total_slots = std::max(total_slots, min_total_slots);
- const uint32_t usable_slots = floor_multiplication_with_fraction(
+ const int64_t usable_slots = floor_multiplication_with_fraction(
total_slots, numerator_, denominator_);
BLI_assert(min_usable_slots <= usable_slots);
@@ -138,9 +143,9 @@ class LoadFactor {
*r_usable_slots = usable_slots;
}
- static constexpr uint32_t compute_total_slots(uint32_t min_usable_slots,
- uint8_t numerator,
- uint8_t denominator)
+ static constexpr int64_t compute_total_slots(int64_t min_usable_slots,
+ uint8_t numerator,
+ uint8_t denominator)
{
return total_slot_amount_for_usable_slots(min_usable_slots, numerator, denominator);
}
@@ -262,27 +267,27 @@ template<typename Pointer> struct PointerKeyInfo {
class HashTableStats {
private:
- Vector<uint32_t> keys_by_collision_count_;
- uint32_t total_collisions_;
+ Vector<int64_t> keys_by_collision_count_;
+ int64_t total_collisions_;
float average_collisions_;
- uint32_t size_;
- uint32_t capacity_;
- uint32_t removed_amount_;
+ int64_t size_;
+ int64_t capacity_;
+ int64_t removed_amount_;
float load_factor_;
float removed_load_factor_;
- uint32_t size_per_element_;
- uint32_t size_in_bytes_;
+ int64_t size_per_element_;
+ int64_t size_in_bytes_;
const void *address_;
public:
/**
* Requires that the hash table has the following methods:
- * - count_collisions(key) -> uint32_t
- * - size() -> uint32_t
- * - capacity() -> uint32_t
- * - removed_amount() -> uint32_t
- * - size_per_element() -> uint32_t
- * - size_in_bytes() -> uint32_t
+ * - count_collisions(key) -> int64_t
+ * - size() -> int64_t
+ * - capacity() -> int64_t
+ * - removed_amount() -> int64_t
+ * - size_per_element() -> int64_t
+ * - size_in_bytes() -> int64_t
*/
template<typename HashTable, typename Keys>
HashTableStats(const HashTable &hash_table, const Keys &keys)
@@ -296,7 +301,7 @@ class HashTableStats {
address_ = (const void *)&hash_table;
for (const auto &key : keys) {
- uint32_t collisions = hash_table.count_collisions(key);
+ int64_t collisions = hash_table.count_collisions(key);
if (keys_by_collision_count_.size() <= collisions) {
keys_by_collision_count_.append_n_times(0,
collisions - keys_by_collision_count_.size() + 1);
@@ -325,7 +330,7 @@ class HashTableStats {
std::cout << " Size per Slot: " << size_per_element_ << " bytes\n";
std::cout << " Average Collisions: " << average_collisions_ << "\n";
- for (uint32_t collision_count : keys_by_collision_count_.index_range()) {
+ for (int64_t collision_count : keys_by_collision_count_.index_range()) {
std::cout << " " << collision_count
<< " Collisions: " << keys_by_collision_count_[collision_count] << "\n";
}
diff --git a/source/blender/blenlib/BLI_index_mask.hh b/source/blender/blenlib/BLI_index_mask.hh
index 93bbb269d30..ff271faa0c2 100644
--- a/source/blender/blenlib/BLI_index_mask.hh
+++ b/source/blender/blenlib/BLI_index_mask.hh
@@ -46,7 +46,7 @@ namespace blender {
class IndexMask {
private:
/* The underlying reference to sorted integers. */
- Span<uint> indices_;
+ Span<int64_t> indices_;
public:
/* Creates an IndexMask that contains no indices. */
@@ -57,10 +57,10 @@ class IndexMask {
* This constructor asserts that the given integers are in ascending order and that there are no
* duplicates.
*/
- IndexMask(Span<uint> indices) : indices_(indices)
+ IndexMask(Span<int64_t> indices) : indices_(indices)
{
#ifdef DEBUG
- for (uint i = 1; i < indices.size(); i++) {
+ for (int64_t i = 1; i < indices.size(); i++) {
BLI_assert(indices[i - 1] < indices[i]);
}
#endif
@@ -84,28 +84,28 @@ class IndexMask {
* Do this:
* do_something_with_an_index_mask({3, 4, 5});
*/
- IndexMask(const std::initializer_list<uint> &indices) : IndexMask(Span<uint>(indices))
+ IndexMask(const std::initializer_list<int64_t> &indices) : IndexMask(Span<int64_t>(indices))
{
}
/**
* Creates an IndexMask that references the indices [0, n-1].
*/
- explicit IndexMask(uint n) : IndexMask(IndexRange(n))
+ explicit IndexMask(int64_t n) : IndexMask(IndexRange(n))
{
}
- operator Span<uint>() const
+ operator Span<int64_t>() const
{
return indices_;
}
- const uint *begin() const
+ const int64_t *begin() const
{
return indices_.begin();
}
- const uint *end() const
+ const int64_t *end() const
{
return indices_.end();
}
@@ -114,7 +114,7 @@ class IndexMask {
* Returns the n-th index referenced by this IndexMask. The `index_mask` method returns an
* IndexRange containing all indices that can be used as parameter here.
*/
- uint operator[](uint n) const
+ int64_t operator[](int64_t n) const
{
return indices_[n];
}
@@ -123,7 +123,7 @@ class IndexMask {
* Returns the minimum size an array has to have, if the integers in this IndexMask are going to
* be used as indices in that array.
*/
- uint min_array_size() const
+ int64_t min_array_size() const
{
if (indices_.size() == 0) {
return 0;
@@ -133,7 +133,7 @@ class IndexMask {
}
}
- Span<uint> indices() const
+ Span<int64_t> indices() const
{
return indices_;
}
@@ -167,12 +167,12 @@ class IndexMask {
{
if (this->is_range()) {
IndexRange range = this->as_range();
- for (uint i : range) {
+ for (int64_t i : range) {
callback(i);
}
}
else {
- for (uint i : indices_) {
+ for (int64_t i : indices_) {
callback(i);
}
}
@@ -193,7 +193,7 @@ class IndexMask {
/**
* Returns the largest index that is referenced by this IndexMask.
*/
- uint last() const
+ int64_t last() const
{
return indices_.last();
}
@@ -201,7 +201,7 @@ class IndexMask {
/**
* Returns the number of indices referenced by this IndexMask.
*/
- uint size() const
+ int64_t size() const
{
return indices_.size();
}
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh
index 1ae08e834ae..7c813f58b2c 100644
--- a/source/blender/blenlib/BLI_index_range.hh
+++ b/source/blender/blenlib/BLI_index_range.hh
@@ -27,29 +27,29 @@
* I'd argue that the second loop is more readable and less error prone than the first one. That is
* not necessarily always the case, but often it is.
*
- * for (uint i = 0; i < 10; i++) {
- * for (uint j = 0; j < 20; j++) {
- * for (uint k = 0; k < 30; k++) {
+ * for (int64_t i = 0; i < 10; i++) {
+ * for (int64_t j = 0; j < 20; j++) {
+ * for (int64_t k = 0; k < 30; k++) {
*
- * for (uint i : IndexRange(10)) {
- * for (uint j : IndexRange(20)) {
- * for (uint k : IndexRange(30)) {
+ * for (int64_t i : IndexRange(10)) {
+ * for (int64_t j : IndexRange(20)) {
+ * for (int64_t k : IndexRange(30)) {
*
* Some containers like blender::Vector have an index_range() method. This will return the
* IndexRange that contains all indices that can be used to access the container. This is
* particularly useful when you want to iterate over the indices and the elements (much like
* Python's enumerate(), just worse). Again, I think the second example here is better:
*
- * for (uint i = 0; i < my_vector_with_a_long_name.size(); i++) {
+ * for (int64_t i = 0; i < my_vector_with_a_long_name.size(); i++) {
* do_something(i, my_vector_with_a_long_name[i]);
*
- * for (uint i : my_vector_with_a_long_name.index_range()) {
+ * for (int64_t i : my_vector_with_a_long_name.index_range()) {
* do_something(i, my_vector_with_a_long_name[i]);
*
* Ideally this could be could be even closer to Python's enumerate(). We might get that in the
* future with newer C++ versions.
*
- * One other important feature is the as_span method. This method returns an Span<uint>
+ * One other important feature is the as_span method. This method returns an Span<int64_t>
* that contains the interval as individual numbers.
*/
@@ -70,18 +70,21 @@ template<typename T> class Span;
class IndexRange {
private:
- uint start_ = 0;
- uint size_ = 0;
+ int64_t start_ = 0;
+ int64_t size_ = 0;
public:
IndexRange() = default;
- explicit IndexRange(uint size) : start_(0), size_(size)
+ explicit IndexRange(int64_t size) : start_(0), size_(size)
{
+ BLI_assert(size >= 0);
}
- IndexRange(uint start, uint size) : start_(start), size_(size)
+ IndexRange(int64_t start, int64_t size) : start_(start), size_(size)
{
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
}
template<typename T>
@@ -91,10 +94,10 @@ class IndexRange {
class Iterator {
private:
- uint current_;
+ int64_t current_;
public:
- Iterator(uint current) : current_(current)
+ Iterator(int64_t current) : current_(current)
{
}
@@ -109,7 +112,7 @@ class IndexRange {
return current_ != iterator.current_;
}
- uint operator*() const
+ int64_t operator*() const
{
return current_;
}
@@ -128,8 +131,9 @@ class IndexRange {
/**
* Access an element in the range.
*/
- uint operator[](uint index) const
+ int64_t operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return start_ + index;
}
@@ -145,7 +149,7 @@ class IndexRange {
/**
* Get the amount of numbers in the range.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -153,16 +157,18 @@ class IndexRange {
/**
* Create a new range starting at the end of the current one.
*/
- IndexRange after(uint n) const
+ IndexRange after(int64_t n) const
{
+ BLI_assert(n >= 0);
return IndexRange(start_ + size_, n);
}
/**
* Create a new range that ends at the start of the current one.
*/
- IndexRange before(uint n) const
+ IndexRange before(int64_t n) const
{
+ BLI_assert(n >= 0);
return IndexRange(start_ - n, n);
}
@@ -170,7 +176,7 @@ class IndexRange {
* Get the first element in the range.
* Asserts when the range is empty.
*/
- uint first() const
+ int64_t first() const
{
BLI_assert(this->size() > 0);
return start_;
@@ -180,7 +186,7 @@ class IndexRange {
* Get the last element in the range.
* Asserts when the range is empty.
*/
- uint last() const
+ int64_t last() const
{
BLI_assert(this->size() > 0);
return start_ + size_ - 1;
@@ -189,7 +195,7 @@ class IndexRange {
/**
* Get the element one after the end. The returned value is undefined when the range is empty.
*/
- uint one_after_last() const
+ int64_t one_after_last() const
{
return start_ + size_;
}
@@ -197,7 +203,7 @@ class IndexRange {
/**
* Get the first element in the range. The returned value is undefined when the range is empty.
*/
- uint start() const
+ int64_t start() const
{
return start_;
}
@@ -205,7 +211,7 @@ class IndexRange {
/**
* Returns true when the range contains a certain number, otherwise false.
*/
- bool contains(uint value) const
+ bool contains(int64_t value) const
{
return value >= start_ && value < start_ + size_;
}
@@ -213,9 +219,11 @@ class IndexRange {
/**
* Returns a new range, that contains a sub-interval of the current one.
*/
- IndexRange slice(uint start, uint size) const
+ IndexRange slice(int64_t start, int64_t size) const
{
- uint new_start = start_ + start;
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
+ int64_t new_start = start_ + start;
BLI_assert(new_start + size <= start_ + size_ || size == 0);
return IndexRange(new_start, size);
}
@@ -227,7 +235,7 @@ class IndexRange {
/**
* Get read-only access to a memory buffer that contains the range as actual numbers.
*/
- Span<uint> as_span() const;
+ Span<int64_t> as_span() const;
friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
{
diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh
index b13d88d5b93..39a3ed27f42 100644
--- a/source/blender/blenlib/BLI_linear_allocator.hh
+++ b/source/blender/blenlib/BLI_linear_allocator.hh
@@ -39,10 +39,10 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
uintptr_t current_begin_;
uintptr_t current_end_;
- uint next_min_alloc_size_;
+ int64_t next_min_alloc_size_;
#ifdef DEBUG
- uint debug_allocated_amount_ = 0;
+ int64_t debug_allocated_amount_ = 0;
#endif
public:
@@ -66,8 +66,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
*
* The alignment has to be a power of 2.
*/
- void *allocate(const uint size, const uint alignment)
+ void *allocate(const int64_t size, const int64_t alignment)
{
+ BLI_assert(size >= 0);
BLI_assert(alignment >= 1);
BLI_assert(is_power_of_2_i(alignment));
@@ -105,7 +106,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
*
* This method only allocates memory and does not construct the instance.
*/
- template<typename T> MutableSpan<T> allocate_array(uint size)
+ template<typename T> MutableSpan<T> allocate_array(int64_t size)
{
return MutableSpan<T>((T *)this->allocate(sizeof(T) * size, alignof(T)), size);
}
@@ -141,22 +142,22 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
*/
StringRefNull copy_string(StringRef str)
{
- const uint alloc_size = str.size() + 1;
+ const int64_t alloc_size = str.size() + 1;
char *buffer = (char *)this->allocate(alloc_size, 1);
str.copy(buffer, alloc_size);
return StringRefNull((const char *)buffer);
}
- MutableSpan<void *> allocate_elements_and_pointer_array(uint element_amount,
- uint element_size,
- uint element_alignment)
+ MutableSpan<void *> allocate_elements_and_pointer_array(int64_t element_amount,
+ int64_t element_size,
+ int64_t element_alignment)
{
void *pointer_buffer = this->allocate(element_amount * sizeof(void *), alignof(void *));
void *elements_buffer = this->allocate(element_amount * element_size, element_alignment);
MutableSpan<void *> pointers((void **)pointer_buffer, element_amount);
void *next_element_buffer = elements_buffer;
- for (uint i : IndexRange(element_amount)) {
+ for (int64_t i : IndexRange(element_amount)) {
pointers[i] = next_element_buffer;
next_element_buffer = POINTER_OFFSET(next_element_buffer, element_size);
}
@@ -165,13 +166,13 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
}
template<typename T, typename... Args>
- Span<T *> construct_elements_and_pointer_array(uint n, Args &&... args)
+ Span<T *> construct_elements_and_pointer_array(int64_t n, Args &&... args)
{
MutableSpan<void *> void_pointers = this->allocate_elements_and_pointer_array(
n, sizeof(T), alignof(T));
MutableSpan<T *> pointers = void_pointers.cast<T *>();
- for (uint i : IndexRange(n)) {
+ for (int64_t i : IndexRange(n)) {
new ((void *)pointers[i]) T(std::forward<Args>(args)...);
}
@@ -194,9 +195,9 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
}
private:
- void allocate_new_buffer(uint min_allocation_size)
+ void allocate_new_buffer(int64_t min_allocation_size)
{
- for (uint i : unused_borrowed_buffers_.index_range()) {
+ for (int64_t i : unused_borrowed_buffers_.index_range()) {
Span<char> buffer = unused_borrowed_buffers_[i];
if (buffer.size() >= min_allocation_size) {
unused_borrowed_buffers_.remove_and_reorder(i);
@@ -206,7 +207,7 @@ template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopya
}
}
- const uint size_in_bytes = power_of_2_min_u(
+ const int64_t size_in_bytes = power_of_2_min_u(
std::max(min_allocation_size, next_min_alloc_size_));
next_min_alloc_size_ = size_in_bytes * 2;
diff --git a/source/blender/blenlib/BLI_listbase_wrapper.hh b/source/blender/blenlib/BLI_listbase_wrapper.hh
index 047099eb36e..46f4a9d49fa 100644
--- a/source/blender/blenlib/BLI_listbase_wrapper.hh
+++ b/source/blender/blenlib/BLI_listbase_wrapper.hh
@@ -96,9 +96,9 @@ template<typename T> class ListBaseWrapper {
return (T *)ptr;
}
- uint index_of(const T *value) const
+ int64_t index_of(const T *value) const
{
- uint index = 0;
+ int64_t index = 0;
for (T *ptr : *this) {
if (ptr == value) {
return index;
@@ -106,7 +106,7 @@ template<typename T> class ListBaseWrapper {
index++;
}
BLI_assert(false);
- return 0;
+ return -1;
}
};
diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh
index 6bbd4ee09db..dd375272fdb 100644
--- a/source/blender/blenlib/BLI_map.hh
+++ b/source/blender/blenlib/BLI_map.hh
@@ -92,11 +92,8 @@ template<
* The minimum number of elements that can be stored in this Map without doing a heap
* allocation. This is useful when you expect to have many small maps. However, keep in mind
* that (unlike vector) initializing a map has a O(n) cost in the number of slots.
- *
- * When Key or Value are large, the small buffer optimization is disabled by default to avoid
- * large unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint32_t InlineBufferCapacity = (sizeof(Key) + sizeof(Value) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key) + sizeof(Value)),
/**
* The strategy used to deal with collisions. They are defined in BLI_probing_strategies.hh.
*/
@@ -129,20 +126,20 @@ class Map {
* Slots are either empty, occupied or removed. The number of occupied slots can be computed by
* subtracting the removed slots from the occupied-and-removed slots.
*/
- uint32_t removed_slots_;
- uint32_t occupied_and_removed_slots_;
+ int64_t removed_slots_;
+ int64_t occupied_and_removed_slots_;
/**
* The maximum number of slots that can be used (either occupied or removed) until the set has to
* grow. This is the total number of slots times the max load factor.
*/
- uint32_t usable_slots_;
+ int64_t usable_slots_;
/**
* The number of slots minus one. This is a bit mask that can be used to turn any integer into a
* valid slot index efficiently.
*/
- uint32_t slot_mask_;
+ uint64_t slot_mask_;
/** This is called to hash incoming keys. */
Hash hash_;
@@ -577,8 +574,8 @@ class Map {
*/
template<typename FuncT> void foreach_item(const FuncT &func) const
{
- uint32_t size = slots_.size();
- for (uint32_t i = 0; i < size; i++) {
+ int64_t size = slots_.size();
+ for (int64_t i = 0; i < size; i++) {
const Slot &slot = slots_[i];
if (slot.is_occupied()) {
const Key &key = *slot.key();
@@ -594,10 +591,10 @@ class Map {
*/
template<typename SubIterator> struct BaseIterator {
Slot *slots_;
- uint32_t total_slots_;
- uint32_t current_slot_;
+ int64_t total_slots_;
+ int64_t current_slot_;
- BaseIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ BaseIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: slots_(const_cast<Slot *>(slots)), total_slots_(total_slots), current_slot_(current_slot)
{
}
@@ -621,7 +618,7 @@ class Map {
SubIterator begin() const
{
- for (uint32_t i = 0; i < total_slots_; i++) {
+ for (int64_t i = 0; i < total_slots_; i++) {
if (slots_[i].is_occupied()) {
return SubIterator(slots_, total_slots_, i);
}
@@ -642,7 +639,7 @@ class Map {
class KeyIterator final : public BaseIterator<KeyIterator> {
public:
- KeyIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ KeyIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<KeyIterator>(slots, total_slots, current_slot)
{
}
@@ -655,7 +652,7 @@ class Map {
class ValueIterator final : public BaseIterator<ValueIterator> {
public:
- ValueIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ ValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<ValueIterator>(slots, total_slots, current_slot)
{
}
@@ -668,7 +665,7 @@ class Map {
class MutableValueIterator final : public BaseIterator<MutableValueIterator> {
public:
- MutableValueIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ MutableValueIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<MutableValueIterator>(slots, total_slots, current_slot)
{
}
@@ -696,7 +693,7 @@ class Map {
class ItemIterator final : public BaseIterator<ItemIterator> {
public:
- ItemIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ ItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<ItemIterator>(slots, total_slots, current_slot)
{
}
@@ -710,7 +707,7 @@ class Map {
class MutableItemIterator final : public BaseIterator<MutableItemIterator> {
public:
- MutableItemIterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ MutableItemIterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: BaseIterator<MutableItemIterator>(slots, total_slots, current_slot)
{
}
@@ -783,7 +780,7 @@ class Map {
/**
* Return the number of key-value-pairs that are stored in the map.
*/
- uint32_t size() const
+ int64_t size() const
{
return occupied_and_removed_slots_ - removed_slots_;
}
@@ -801,7 +798,7 @@ class Map {
/**
* Returns the number of available slots. This is mostly for debugging purposes.
*/
- uint32_t capacity() const
+ int64_t capacity() const
{
return slots_.size();
}
@@ -809,7 +806,7 @@ class Map {
/**
* Returns the amount of removed slots in the set. This is mostly for debugging purposes.
*/
- uint32_t removed_amount() const
+ int64_t removed_amount() const
{
return removed_slots_;
}
@@ -817,7 +814,7 @@ class Map {
/**
* Returns the bytes required per element. This is mostly for debugging purposes.
*/
- uint32_t size_per_element() const
+ int64_t size_per_element() const
{
return sizeof(Slot);
}
@@ -826,16 +823,16 @@ class Map {
* Returns the approximate memory requirements of the map in bytes. This becomes more exact the
* larger the map becomes.
*/
- uint32_t size_in_bytes() const
+ int64_t size_in_bytes() const
{
- return (uint32_t)(sizeof(Slot) * slots_.size());
+ return (int64_t)(sizeof(Slot) * slots_.size());
}
/**
* Potentially resize the map such that the specified number of elements can be added without
* another grow operation.
*/
- void reserve(uint32_t n)
+ void reserve(int64_t n)
{
if (usable_slots_ < n) {
this->realloc_and_reinsert(n);
@@ -855,18 +852,19 @@ class Map {
* Get the number of collisions that the probing strategy has to go through to find the key or
* determine that it is not in the map.
*/
- uint32_t count_collisions(const Key &key) const
+ int64_t count_collisions(const Key &key) const
{
return this->count_collisions__impl(key, hash_(key));
}
private:
- BLI_NOINLINE void realloc_and_reinsert(uint32_t min_usable_slots)
+ BLI_NOINLINE void realloc_and_reinsert(int64_t min_usable_slots)
{
- uint32_t total_slots, usable_slots;
+ int64_t total_slots, usable_slots;
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
- uint32_t new_slot_mask = total_slots - 1;
+ BLI_assert(total_slots >= 1);
+ const uint64_t new_slot_mask = (uint64_t)total_slots - 1;
/**
* Optimize the case when the map was empty beforehand. We can avoid some copies here.
@@ -901,9 +899,9 @@ class Map {
void add_after_grow_and_destruct_old(Slot &old_slot,
SlotArray &new_slots,
- uint32_t new_slot_mask)
+ uint64_t new_slot_mask)
{
- uint32_t hash = old_slot.get_hash(Hash());
+ uint64_t hash = old_slot.get_hash(Hash());
SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
Slot &slot = new_slots[slot_index];
if (slot.is_empty()) {
@@ -914,7 +912,7 @@ class Map {
SLOT_PROBING_END();
}
- template<typename ForwardKey> bool contains__impl(const ForwardKey &key, uint32_t hash) const
+ template<typename ForwardKey> bool contains__impl(const ForwardKey &key, uint64_t hash) const
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -928,7 +926,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- void add_new__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ void add_new__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
BLI_assert(!this->contains_as(key));
@@ -945,7 +943,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- bool add__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ bool add__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
this->ensure_can_add();
@@ -962,7 +960,7 @@ class Map {
MAP_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool remove__impl(const ForwardKey &key, uint32_t hash)
+ template<typename ForwardKey> bool remove__impl(const ForwardKey &key, uint64_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -977,7 +975,7 @@ class Map {
MAP_SLOT_PROBING_END();
}
- template<typename ForwardKey> void remove_contained__impl(const ForwardKey &key, uint32_t hash)
+ template<typename ForwardKey> void remove_contained__impl(const ForwardKey &key, uint64_t hash)
{
BLI_assert(this->contains_as(key));
@@ -992,7 +990,7 @@ class Map {
MAP_SLOT_PROBING_END();
}
- template<typename ForwardKey> Value pop__impl(const ForwardKey &key, uint32_t hash)
+ template<typename ForwardKey> Value pop__impl(const ForwardKey &key, uint64_t hash)
{
BLI_assert(this->contains_as(key));
@@ -1009,7 +1007,7 @@ class Map {
}
template<typename ForwardKey>
- std::optional<Value> pop_try__impl(const ForwardKey &key, uint32_t hash)
+ std::optional<Value> pop_try__impl(const ForwardKey &key, uint64_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1026,7 +1024,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- Value pop_default__impl(const ForwardKey &key, ForwardValue &&default_value, uint32_t hash)
+ Value pop_default__impl(const ForwardKey &key, ForwardValue &&default_value, uint64_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1046,7 +1044,7 @@ class Map {
auto add_or_modify__impl(ForwardKey &&key,
const CreateValueF &create_value,
const ModifyValueF &modify_value,
- uint32_t hash) -> decltype(create_value(nullptr))
+ uint64_t hash) -> decltype(create_value(nullptr))
{
using CreateReturnT = decltype(create_value(nullptr));
using ModifyReturnT = decltype(modify_value(nullptr));
@@ -1071,7 +1069,7 @@ class Map {
}
template<typename ForwardKey, typename CreateValueF>
- Value &lookup_or_add_cb__impl(ForwardKey &&key, const CreateValueF &create_value, uint32_t hash)
+ Value &lookup_or_add_cb__impl(ForwardKey &&key, const CreateValueF &create_value, uint64_t hash)
{
this->ensure_can_add();
@@ -1089,7 +1087,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- Value &lookup_or_add__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ Value &lookup_or_add__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
this->ensure_can_add();
@@ -1107,7 +1105,7 @@ class Map {
}
template<typename ForwardKey, typename ForwardValue>
- bool add_overwrite__impl(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ bool add_overwrite__impl(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
auto create_func = [&](Value *ptr) {
new ((void *)ptr) Value(std::forward<ForwardValue>(value));
@@ -1122,7 +1120,7 @@ class Map {
}
template<typename ForwardKey>
- const Value *lookup_ptr__impl(const ForwardKey &key, uint32_t hash) const
+ const Value *lookup_ptr__impl(const ForwardKey &key, uint64_t hash) const
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -1136,9 +1134,9 @@ class Map {
}
template<typename ForwardKey>
- uint32_t count_collisions__impl(const ForwardKey &key, uint32_t hash) const
+ int64_t count_collisions__impl(const ForwardKey &key, uint64_t hash) const
{
- uint32_t collisions = 0;
+ int64_t collisions = 0;
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -1162,6 +1160,21 @@ class Map {
};
/**
+ * Same as a normal Map, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename Key,
+ typename Value,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key) +
+ sizeof(Value)),
+ typename ProbingStrategy = DefaultProbingStrategy,
+ typename Hash = DefaultHash<Key>,
+ typename IsEqual = DefaultEquality,
+ typename Slot = typename DefaultMapSlot<Key, Value>::type>
+using RawMap =
+ Map<Key, Value, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
+
+/**
* A wrapper for std::unordered_map with the API of blender::Map. This can be used for
* benchmarking.
*/
@@ -1171,9 +1184,9 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
MapType map_;
public:
- uint32_t size() const
+ int64_t size() const
{
- return (uint32_t)map_.size();
+ return (int64_t)map_.size();
}
bool is_empty() const
@@ -1181,7 +1194,7 @@ template<typename Key, typename Value> class StdUnorderedMapWrapper {
return map_.empty();
}
- void reserve(uint32_t n)
+ void reserve(int64_t n)
{
map_.reserve(n);
}
diff --git a/source/blender/blenlib/BLI_map_slots.hh b/source/blender/blenlib/BLI_map_slots.hh
index ff3ed34eb9d..b5360795a13 100644
--- a/source/blender/blenlib/BLI_map_slots.hh
+++ b/source/blender/blenlib/BLI_map_slots.hh
@@ -155,7 +155,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* Returns the hash of the currently stored key. In this simple map slot implementation, we just
* computed the hash here. Other implementations might store the hash in the slot instead.
*/
- template<typename Hash> uint32_t get_hash(const Hash &hash)
+ template<typename Hash> uint64_t get_hash(const Hash &hash)
{
BLI_assert(this->is_occupied());
return hash(*key_buffer_);
@@ -165,7 +165,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* Move the other slot into this slot and destruct it. We do destruction here, because this way
* we can avoid a comparison with the state, since we know the slot is occupied.
*/
- void relocate_occupied_here(SimpleMapSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(SimpleMapSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -181,7 +181,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* key. The hash can be used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
{
if (state_ == Occupied) {
return is_equal(key, *key_buffer_);
@@ -194,7 +194,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* constructed by calling the constructor with the given key/value as parameter.
*/
template<typename ForwardKey, typename ForwardValue>
- void occupy(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ void occupy(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
BLI_assert(!this->is_occupied());
this->occupy_without_value(std::forward<ForwardKey>(key), hash);
@@ -205,7 +205,7 @@ template<typename Key, typename Value> class SimpleMapSlot {
* Change the state of this slot from empty/removed to occupied, but leave the value
* uninitialized. The caller is responsible to construct the value afterwards.
*/
- template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
state_ = Occupied;
@@ -292,13 +292,13 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
return KeyInfo::is_empty(key_);
}
- template<typename Hash> uint32_t get_hash(const Hash &hash)
+ template<typename Hash> uint64_t get_hash(const Hash &hash)
{
BLI_assert(this->is_occupied());
return hash(key_);
}
- void relocate_occupied_here(IntrusiveMapSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(IntrusiveMapSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -309,14 +309,14 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key, key_);
}
template<typename ForwardKey, typename ForwardValue>
- void occupy(ForwardKey &&key, ForwardValue &&value, uint32_t hash)
+ void occupy(ForwardKey &&key, ForwardValue &&value, uint64_t hash)
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
@@ -324,7 +324,7 @@ template<typename Key, typename Value, typename KeyInfo> class IntrusiveMapSlot
new (&value_buffer_) Value(std::forward<ForwardValue>(value));
}
- template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy_without_value(ForwardKey &&key, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh
index b73e0e95312..9f65fe0742e 100644
--- a/source/blender/blenlib/BLI_memory_utils.hh
+++ b/source/blender/blenlib/BLI_memory_utils.hh
@@ -43,8 +43,10 @@ namespace blender {
* After:
* ptr: uninitialized
*/
-template<typename T> void destruct_n(T *ptr, uint n)
+template<typename T> void destruct_n(T *ptr, int64_t n)
{
+ BLI_assert(n >= 0);
+
static_assert(std::is_nothrow_destructible_v<T>,
"This should be true for all types. Destructors are noexcept by default.");
@@ -54,7 +56,7 @@ template<typename T> void destruct_n(T *ptr, uint n)
return;
}
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
ptr[i].~T();
}
}
@@ -70,15 +72,17 @@ template<typename T> void destruct_n(T *ptr, uint n)
* After:
* ptr: initialized
*/
-template<typename T> void default_construct_n(T *ptr, uint n)
+template<typename T> void default_construct_n(T *ptr, int64_t n)
{
+ BLI_assert(n >= 0);
+
/* This is not strictly necessary, because the loop below will be optimized away anyway. It is
* nice to make behavior this explicitly, though. */
if (std::is_trivially_constructible_v<T>) {
return;
}
- uint current = 0;
+ int64_t current = 0;
try {
for (; current < n; current++) {
new ((void *)(ptr + current)) T;
@@ -102,9 +106,11 @@ template<typename T> void default_construct_n(T *ptr, uint n)
* src: initialized
* dst: initialized
*/
-template<typename T> void initialized_copy_n(const T *src, uint n, T *dst)
+template<typename T> void initialized_copy_n(const T *src, int64_t n, T *dst)
{
- for (uint i = 0; i < n; i++) {
+ BLI_assert(n >= 0);
+
+ for (int64_t i = 0; i < n; i++) {
dst[i] = src[i];
}
}
@@ -121,9 +127,11 @@ template<typename T> void initialized_copy_n(const T *src, uint n, T *dst)
* src: initialized
* dst: initialized
*/
-template<typename T> void uninitialized_copy_n(const T *src, uint n, T *dst)
+template<typename T> void uninitialized_copy_n(const T *src, int64_t n, T *dst)
{
- uint current = 0;
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
try {
for (; current < n; current++) {
new ((void *)(dst + current)) T(src[current]);
@@ -147,9 +155,12 @@ template<typename T> void uninitialized_copy_n(const T *src, uint n, T *dst)
* src: initialized
* dst: initialized
*/
-template<typename From, typename To> void uninitialized_convert_n(const From *src, uint n, To *dst)
+template<typename From, typename To>
+void uninitialized_convert_n(const From *src, int64_t n, To *dst)
{
- uint current = 0;
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
try {
for (; current < n; current++) {
new ((void *)(dst + current)) To((To)src[current]);
@@ -173,9 +184,11 @@ template<typename From, typename To> void uninitialized_convert_n(const From *sr
* src: initialized, moved-from
* dst: initialized
*/
-template<typename T> void initialized_move_n(T *src, uint n, T *dst)
+template<typename T> void initialized_move_n(T *src, int64_t n, T *dst)
{
- for (uint i = 0; i < n; i++) {
+ BLI_assert(n >= 0);
+
+ for (int64_t i = 0; i < n; i++) {
dst[i] = std::move(src[i]);
}
}
@@ -192,9 +205,11 @@ template<typename T> void initialized_move_n(T *src, uint n, T *dst)
* src: initialized, moved-from
* dst: initialized
*/
-template<typename T> void uninitialized_move_n(T *src, uint n, T *dst)
+template<typename T> void uninitialized_move_n(T *src, int64_t n, T *dst)
{
- uint current = 0;
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
try {
for (; current < n; current++) {
new ((void *)(dst + current)) T(std::move(src[current]));
@@ -219,8 +234,10 @@ template<typename T> void uninitialized_move_n(T *src, uint n, T *dst)
* src: uninitialized
* dst: initialized
*/
-template<typename T> void initialized_relocate_n(T *src, uint n, T *dst)
+template<typename T> void initialized_relocate_n(T *src, int64_t n, T *dst)
{
+ BLI_assert(n >= 0);
+
initialized_move_n(src, n, dst);
destruct_n(src, n);
}
@@ -238,8 +255,10 @@ template<typename T> void initialized_relocate_n(T *src, uint n, T *dst)
* src: uninitialized
* dst: initialized
*/
-template<typename T> void uninitialized_relocate_n(T *src, uint n, T *dst)
+template<typename T> void uninitialized_relocate_n(T *src, int64_t n, T *dst)
{
+ BLI_assert(n >= 0);
+
uninitialized_move_n(src, n, dst);
destruct_n(src, n);
}
@@ -254,9 +273,11 @@ template<typename T> void uninitialized_relocate_n(T *src, uint n, T *dst)
* After:
* dst: initialized
*/
-template<typename T> void initialized_fill_n(T *dst, uint n, const T &value)
+template<typename T> void initialized_fill_n(T *dst, int64_t n, const T &value)
{
- for (uint i = 0; i < n; i++) {
+ BLI_assert(n >= 0);
+
+ for (int64_t i = 0; i < n; i++) {
dst[i] = value;
}
}
@@ -271,9 +292,11 @@ template<typename T> void initialized_fill_n(T *dst, uint n, const T &value)
* After:
* dst: initialized
*/
-template<typename T> void uninitialized_fill_n(T *dst, uint n, const T &value)
+template<typename T> void uninitialized_fill_n(T *dst, int64_t n, const T &value)
{
- uint current = 0;
+ BLI_assert(n >= 0);
+
+ int64_t current = 0;
try {
for (; current < n; current++) {
new ((void *)(dst + current)) T(value);
@@ -334,9 +357,9 @@ template<size_t Size, size_t Alignment> class alignas(Alignment) AlignedBuffer {
* lifetime of the object they are embedded in. It's used by containers with small buffer
* optimization and hash table implementations.
*/
-template<typename T, size_t Size = 1> class TypedBuffer {
+template<typename T, int64_t Size = 1> class TypedBuffer {
private:
- AlignedBuffer<sizeof(T) * Size, alignof(T)> buffer_;
+ AlignedBuffer<sizeof(T) * (size_t)Size, alignof(T)> buffer_;
public:
operator T *()
@@ -396,6 +419,15 @@ template<typename From, typename To>
inline constexpr bool is_convertible_pointer_v =
std::is_convertible_v<From, To> &&std::is_pointer_v<From> &&std::is_pointer_v<To>;
+/**
+ * Inline buffers for small-object-optimization should be disable by default. Otherwise we might
+ * get large unexpected allocations on the stack.
+ */
+inline constexpr int64_t default_inline_buffer_capacity(size_t element_size)
+{
+ return ((int64_t)element_size < 100) ? 4 : 0;
+}
+
} // namespace blender
#endif /* __BLI_MEMORY_UTILS_HH__ */
diff --git a/source/blender/blenlib/BLI_probing_strategies.hh b/source/blender/blenlib/BLI_probing_strategies.hh
index d2b16ac3516..0e5338fa6ed 100644
--- a/source/blender/blenlib/BLI_probing_strategies.hh
+++ b/source/blender/blenlib/BLI_probing_strategies.hh
@@ -25,17 +25,17 @@
* values based on an initial hash value.
*
* A probing strategy has to implement the following methods:
- * - Constructor(uint32_t hash): Start a new probing sequence based on the given hash.
- * - get() const -> uint32_t: Get the current value in the sequence.
+ * - Constructor(uint64_t hash): Start a new probing sequence based on the given hash.
+ * - get() const -> uint64_t: Get the current value in the sequence.
* - next() -> void: Update the internal state, so that the next value can be accessed with get().
- * - linear_steps() -> uint32_t: Returns number of linear probing steps that should be done.
+ * - linear_steps() -> int64_t: Returns number of linear probing steps that should be done.
*
* Using linear probing steps between larger jumps can result in better performance, due to
* improved cache usage. It's a way of getting the benefits or linear probing without the
* clustering issues. However, more linear steps can also make things slower when the initial hash
* produces many collisions.
*
- * Every probing strategy has to guarantee, that every possible uint32_t is returned eventually.
+ * Every probing strategy has to guarantee, that every possible uint64_t is returned eventually.
* This is necessary for correctness. If this is not the case, empty slots might not be found.
*
* The SLOT_PROBING_BEGIN and SLOT_PROBING_END macros can be used to implement a loop that iterates
@@ -65,10 +65,10 @@ namespace blender {
*/
class LinearProbingStrategy {
private:
- uint32_t hash_;
+ uint64_t hash_;
public:
- LinearProbingStrategy(const uint32_t hash) : hash_(hash)
+ LinearProbingStrategy(const uint64_t hash) : hash_(hash)
{
}
@@ -77,12 +77,12 @@ class LinearProbingStrategy {
hash_++;
}
- uint32_t get() const
+ uint64_t get() const
{
return hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return UINT32_MAX;
}
@@ -101,12 +101,12 @@ class LinearProbingStrategy {
*/
class QuadraticProbingStrategy {
private:
- uint32_t original_hash_;
- uint32_t current_hash_;
- uint32_t iteration_;
+ uint64_t original_hash_;
+ uint64_t current_hash_;
+ uint64_t iteration_;
public:
- QuadraticProbingStrategy(const uint32_t hash)
+ QuadraticProbingStrategy(const uint64_t hash)
: original_hash_(hash), current_hash_(hash), iteration_(1)
{
}
@@ -117,12 +117,12 @@ class QuadraticProbingStrategy {
iteration_++;
}
- uint32_t get() const
+ uint64_t get() const
{
return current_hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return 1;
}
@@ -138,13 +138,13 @@ class QuadraticProbingStrategy {
* PreShuffle: When true, the initial call to next() will be done to the constructor. This can help
* when the hash function has put little information into the lower bits.
*/
-template<uint32_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingStrategy {
+template<uint64_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingStrategy {
private:
- uint32_t hash_;
- uint32_t perturb_;
+ uint64_t hash_;
+ uint64_t perturb_;
public:
- PythonProbingStrategy(const uint32_t hash) : hash_(hash), perturb_(hash)
+ PythonProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
{
if (PreShuffle) {
this->next();
@@ -157,12 +157,12 @@ template<uint32_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingS
hash_ = 5 * hash_ + 1 + perturb_;
}
- uint32_t get() const
+ uint64_t get() const
{
return hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return LinearSteps;
}
@@ -173,13 +173,13 @@ template<uint32_t LinearSteps = 1, bool PreShuffle = false> class PythonProbingS
* method. This way more bits are taken into account earlier. After a couple of collisions (that
* should happen rarely), it will fallback to a sequence that hits every slot.
*/
-template<uint32_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbingStrategy {
+template<uint64_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbingStrategy {
private:
- uint32_t hash_;
- uint32_t perturb_;
+ uint64_t hash_;
+ uint64_t perturb_;
public:
- ShuffleProbingStrategy(const uint32_t hash) : hash_(hash), perturb_(hash)
+ ShuffleProbingStrategy(const uint64_t hash) : hash_(hash), perturb_(hash)
{
if (PreShuffle) {
this->next();
@@ -197,12 +197,12 @@ template<uint32_t LinearSteps = 2, bool PreShuffle = false> class ShuffleProbing
}
}
- uint32_t get() const
+ uint64_t get() const
{
return hash_;
}
- uint32_t linear_steps() const
+ int64_t linear_steps() const
{
return LinearSteps;
}
@@ -233,10 +233,10 @@ using DefaultProbingStrategy = PythonProbingStrategy<>;
#define SLOT_PROBING_BEGIN(PROBING_STRATEGY, HASH, MASK, R_SLOT_INDEX) \
PROBING_STRATEGY probing_strategy(HASH); \
do { \
- uint32_t linear_offset = 0; \
- uint32_t current_hash = probing_strategy.get(); \
+ int64_t linear_offset = 0; \
+ uint64_t current_hash = probing_strategy.get(); \
do { \
- uint32_t R_SLOT_INDEX = (current_hash + linear_offset) & MASK;
+ int64_t R_SLOT_INDEX = (int64_t)((current_hash + (uint64_t)linear_offset) & MASK);
#define SLOT_PROBING_END() \
} while (++linear_offset < probing_strategy.linear_steps()); \
diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh
index bfc4d276165..612ac0bbe19 100644
--- a/source/blender/blenlib/BLI_rand.hh
+++ b/source/blender/blenlib/BLI_rand.hh
@@ -86,7 +86,7 @@ class RandomNumberGenerator {
/**
* Simulate getting \a n random values.
*/
- void skip(uint n)
+ void skip(int64_t n)
{
while (n--) {
this->step();
diff --git a/source/blender/blenlib/BLI_resource_collector.hh b/source/blender/blenlib/BLI_resource_collector.hh
index 672a1269962..10d610da618 100644
--- a/source/blender/blenlib/BLI_resource_collector.hh
+++ b/source/blender/blenlib/BLI_resource_collector.hh
@@ -51,7 +51,7 @@ class ResourceCollector : NonCopyable, NonMovable {
~ResourceCollector()
{
/* Free in reversed order. */
- for (uint i = m_resources.size(); i--;) {
+ for (int64_t i = m_resources.size(); i--;) {
ResourceData &data = m_resources[i];
data.free(data.data);
}
diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh
index c5096f84c80..90adea69e06 100644
--- a/source/blender/blenlib/BLI_set.hh
+++ b/source/blender/blenlib/BLI_set.hh
@@ -89,11 +89,8 @@ template<
* The minimum number of elements that can be stored in this Set without doing a heap
* allocation. This is useful when you expect to have many small sets. However, keep in mind
* that (unlike vector) initializing a set has a O(n) cost in the number of slots.
- *
- * When Key is large, the small buffer optimization is disabled by default to avoid large
- * unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint32_t InlineBufferCapacity = (sizeof(Key) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
/**
* The strategy used to deal with collisions. They are defined in BLI_probing_strategies.hh.
*/
@@ -128,20 +125,20 @@ class Set {
* Slots are either empty, occupied or removed. The number of occupied slots can be computed by
* subtracting the removed slots from the occupied-and-removed slots.
*/
- uint32_t removed_slots_;
- uint32_t occupied_and_removed_slots_;
+ int64_t removed_slots_;
+ int64_t occupied_and_removed_slots_;
/**
* The maximum number of slots that can be used (either occupied or removed) until the set has to
* grow. This is the total number of slots times the max load factor.
*/
- uint32_t usable_slots_;
+ int64_t usable_slots_;
/**
* The number of slots minus one. This is a bit mask that can be used to turn any integer into a
* valid slot index efficiently.
*/
- uint32_t slot_mask_;
+ uint64_t slot_mask_;
/** This is called to hash incoming keys. */
Hash hash_;
@@ -384,11 +381,11 @@ class Set {
class Iterator {
private:
const Slot *slots_;
- uint32_t total_slots_;
- uint32_t current_slot_;
+ int64_t total_slots_;
+ int64_t current_slot_;
public:
- Iterator(const Slot *slots, uint32_t total_slots, uint32_t current_slot)
+ Iterator(const Slot *slots, int64_t total_slots, int64_t current_slot)
: slots_(slots), total_slots_(total_slots), current_slot_(current_slot)
{
}
@@ -418,7 +415,7 @@ class Set {
Iterator begin() const
{
- for (uint32_t i = 0; i < slots_.size(); i++) {
+ for (int64_t i = 0; i < slots_.size(); i++) {
if (slots_[i].is_occupied()) {
return Iterator(slots_.data(), slots_.size(), i);
}
@@ -444,7 +441,7 @@ class Set {
* Get the number of collisions that the probing strategy has to go through to find the key or
* determine that it is not in the set.
*/
- uint32_t count_collisions(const Key &key) const
+ int64_t count_collisions(const Key &key) const
{
return this->count_collisions__impl(key, hash_(key));
}
@@ -470,7 +467,7 @@ class Set {
/**
* Returns the number of keys stored in the set.
*/
- uint32_t size() const
+ int64_t size() const
{
return occupied_and_removed_slots_ - removed_slots_;
}
@@ -486,7 +483,7 @@ class Set {
/**
* Returns the number of available slots. This is mostly for debugging purposes.
*/
- uint32_t capacity() const
+ int64_t capacity() const
{
return slots_.size();
}
@@ -494,7 +491,7 @@ class Set {
/**
* Returns the amount of removed slots in the set. This is mostly for debugging purposes.
*/
- uint32_t removed_amount() const
+ int64_t removed_amount() const
{
return removed_slots_;
}
@@ -502,7 +499,7 @@ class Set {
/**
* Returns the bytes required per element. This is mostly for debugging purposes.
*/
- uint32_t size_per_element() const
+ int64_t size_per_element() const
{
return sizeof(Slot);
}
@@ -511,7 +508,7 @@ class Set {
* Returns the approximate memory requirements of the set in bytes. This is more correct for
* larger sets.
*/
- uint32_t size_in_bytes() const
+ int64_t size_in_bytes() const
{
return sizeof(Slot) * slots_.size();
}
@@ -520,7 +517,7 @@ class Set {
* Potentially resize the set such that it can hold the specified number of keys without another
* grow operation.
*/
- void reserve(const uint32_t n)
+ void reserve(const int64_t n)
{
if (usable_slots_ < n) {
this->realloc_and_reinsert(n);
@@ -554,12 +551,13 @@ class Set {
}
private:
- BLI_NOINLINE void realloc_and_reinsert(const uint32_t min_usable_slots)
+ BLI_NOINLINE void realloc_and_reinsert(const int64_t min_usable_slots)
{
- uint32_t total_slots, usable_slots;
+ int64_t total_slots, usable_slots;
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
- const uint32_t new_slot_mask = total_slots - 1;
+ BLI_assert(total_slots >= 1);
+ const uint64_t new_slot_mask = (uint64_t)total_slots - 1;
/**
* Optimize the case when the set was empty beforehand. We can avoid some copies here.
@@ -595,9 +593,9 @@ class Set {
void add_after_grow_and_destruct_old(Slot &old_slot,
SlotArray &new_slots,
- const uint32_t new_slot_mask)
+ const uint64_t new_slot_mask)
{
- const uint32_t hash = old_slot.get_hash(Hash());
+ const uint64_t hash = old_slot.get_hash(Hash());
SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
Slot &slot = new_slots[slot_index];
@@ -610,7 +608,7 @@ class Set {
}
template<typename ForwardKey>
- bool contains__impl(const ForwardKey &key, const uint32_t hash) const
+ bool contains__impl(const ForwardKey &key, const uint64_t hash) const
{
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -624,7 +622,7 @@ class Set {
}
template<typename ForwardKey>
- const Key &lookup_key__impl(const ForwardKey &key, const uint32_t hash) const
+ const Key &lookup_key__impl(const ForwardKey &key, const uint64_t hash) const
{
BLI_assert(this->contains_as(key));
@@ -637,7 +635,7 @@ class Set {
}
template<typename ForwardKey>
- const Key *lookup_key_ptr__impl(const ForwardKey &key, const uint32_t hash) const
+ const Key *lookup_key_ptr__impl(const ForwardKey &key, const uint64_t hash) const
{
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -650,7 +648,7 @@ class Set {
SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint64_t hash)
{
BLI_assert(!this->contains_as(key));
@@ -666,7 +664,7 @@ class Set {
SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint64_t hash)
{
this->ensure_can_add();
@@ -683,7 +681,7 @@ class Set {
SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint32_t hash)
+ template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint64_t hash)
{
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -699,7 +697,7 @@ class Set {
}
template<typename ForwardKey>
- void remove_contained__impl(const ForwardKey &key, const uint32_t hash)
+ void remove_contained__impl(const ForwardKey &key, const uint64_t hash)
{
BLI_assert(this->contains_as(key));
removed_slots_++;
@@ -714,9 +712,9 @@ class Set {
}
template<typename ForwardKey>
- uint32_t count_collisions__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t count_collisions__impl(const ForwardKey &key, const uint64_t hash) const
{
- uint32_t collisions = 0;
+ int64_t collisions = 0;
SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash)) {
@@ -749,9 +747,9 @@ template<typename Key> class StdUnorderedSetWrapper {
SetType set_;
public:
- uint32_t size() const
+ int64_t size() const
{
- return (uint32_t)set_.size();
+ return (int64_t)set_.size();
}
bool is_empty() const
@@ -759,7 +757,7 @@ template<typename Key> class StdUnorderedSetWrapper {
return set_.empty();
}
- void reserve(uint32_t n)
+ void reserve(int64_t n)
{
set_.reserve(n);
}
@@ -820,6 +818,18 @@ template<typename Key> class StdUnorderedSetWrapper {
}
};
+/**
+ * Same as a normal Set, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename Key,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)),
+ typename ProbingStrategy = DefaultProbingStrategy,
+ typename Hash = DefaultHash<Key>,
+ typename IsEqual = DefaultEquality,
+ typename Slot = typename DefaultSetSlot<Key>::type>
+using RawSet = Set<Key, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
+
} // namespace blender
#endif /* __BLI_SET_HH__ */
diff --git a/source/blender/blenlib/BLI_set_slots.hh b/source/blender/blenlib/BLI_set_slots.hh
index d3891e78b52..b78ed37f534 100644
--- a/source/blender/blenlib/BLI_set_slots.hh
+++ b/source/blender/blenlib/BLI_set_slots.hh
@@ -133,7 +133,7 @@ template<typename Key> class SimpleSetSlot {
* Return the hash of the currently stored key. In this simple set slot implementation, we just
* compute the hash here. Other implementations might store the hash in the slot instead.
*/
- template<typename Hash> uint32_t get_hash(const Hash &hash) const
+ template<typename Hash> uint64_t get_hash(const Hash &hash) const
{
BLI_assert(this->is_occupied());
return hash(*key_buffer_);
@@ -143,7 +143,7 @@ template<typename Key> class SimpleSetSlot {
* Move the other slot into this slot and destruct it. We do destruction here, because this way
* we can avoid a comparison with the state, since we know the slot is occupied.
*/
- void relocate_occupied_here(SimpleSetSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(SimpleSetSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -157,7 +157,7 @@ template<typename Key> class SimpleSetSlot {
* key. The hash is used by other slot implementations to determine inequality faster.
*/
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, uint64_t UNUSED(hash)) const
{
if (state_ == Occupied) {
return is_equal(key, *key_buffer_);
@@ -169,7 +169,7 @@ template<typename Key> class SimpleSetSlot {
* Change the state of this slot from empty/removed to occupied. The key has to be constructed
* by calling the constructor with the given key as parameter.
*/
- template<typename ForwardKey> void occupy(ForwardKey &&key, uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
state_ = Occupied;
@@ -199,7 +199,7 @@ template<typename Key> class HashedSetSlot {
Removed = 2,
};
- uint32_t hash_;
+ uint64_t hash_;
State state_;
TypedBuffer<Key> key_buffer_;
@@ -254,13 +254,13 @@ template<typename Key> class HashedSetSlot {
return state_ == Empty;
}
- template<typename Hash> uint32_t get_hash(const Hash &UNUSED(hash)) const
+ template<typename Hash> uint64_t get_hash(const Hash &UNUSED(hash)) const
{
BLI_assert(this->is_occupied());
return hash_;
}
- void relocate_occupied_here(HashedSetSlot &other, const uint32_t hash)
+ void relocate_occupied_here(HashedSetSlot &other, const uint64_t hash)
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -271,7 +271,7 @@ template<typename Key> class HashedSetSlot {
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint32_t hash) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t hash) const
{
/* hash_ might be uninitialized here, but that is ok. */
if (hash_ == hash) {
@@ -282,7 +282,7 @@ template<typename Key> class HashedSetSlot {
return false;
}
- template<typename ForwardKey> void occupy(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t hash)
{
BLI_assert(!this->is_occupied());
state_ = Occupied;
@@ -336,13 +336,13 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
return KeyInfo::is_empty(key_);
}
- template<typename Hash> uint32_t get_hash(const Hash &hash) const
+ template<typename Hash> uint64_t get_hash(const Hash &hash) const
{
BLI_assert(this->is_occupied());
return hash(key_);
}
- void relocate_occupied_here(IntrusiveSetSlot &other, const uint32_t UNUSED(hash))
+ void relocate_occupied_here(IntrusiveSetSlot &other, const uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -351,13 +351,13 @@ template<typename Key, typename KeyInfo> class IntrusiveSetSlot {
}
template<typename ForwardKey, typename IsEqual>
- bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint32_t UNUSED(hash)) const
+ bool contains(const ForwardKey &key, const IsEqual &is_equal, const uint64_t UNUSED(hash)) const
{
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
return is_equal(key_, key);
}
- template<typename ForwardKey> void occupy(ForwardKey &&key, const uint32_t UNUSED(hash))
+ template<typename ForwardKey> void occupy(ForwardKey &&key, const uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(KeyInfo::is_not_empty_or_removed(key));
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index 57ef9ce9eb6..2d875fe73be 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -88,7 +88,7 @@ namespace blender {
template<typename T> class Span {
private:
const T *start_ = nullptr;
- uint size_ = 0;
+ int64_t size_ = 0;
public:
/**
@@ -96,13 +96,15 @@ template<typename T> class Span {
*/
Span() = default;
- Span(const T *start, uint size) : start_(start), size_(size)
+ Span(const T *start, int64_t size) : start_(start), size_(size)
{
+ BLI_assert(size >= 0);
}
template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
- Span(const U *start, uint size) : start_((const T *)start), size_(size)
+ Span(const U *start, int64_t size) : start_((const T *)start), size_(size)
{
+ BLI_assert(size >= 0);
}
/**
@@ -116,11 +118,11 @@ template<typename T> class Span {
* Span<int> span = {1, 2, 3, 4};
* call_function_with_array(span);
*/
- Span(const std::initializer_list<T> &list) : Span(list.begin(), (uint)list.size())
+ Span(const std::initializer_list<T> &list) : Span(list.begin(), (int64_t)list.size())
{
}
- Span(const std::vector<T> &vector) : Span(vector.data(), (uint)vector.size())
+ Span(const std::vector<T> &vector) : Span(vector.data(), (int64_t)vector.size())
{
}
@@ -142,8 +144,10 @@ template<typename T> class Span {
* Returns a contiguous part of the array. This invokes undefined behavior when the slice does
* not stay within the bounds of the array.
*/
- Span slice(uint start, uint size) const
+ Span slice(int64_t start, int64_t size) const
{
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
BLI_assert(start + size <= this->size() || size == 0);
return Span(start_ + start, size);
}
@@ -157,8 +161,9 @@ template<typename T> class Span {
* Returns a new Span with n elements removed from the beginning. This invokes undefined
* behavior when the array is too small.
*/
- Span drop_front(uint n) const
+ Span drop_front(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(n, this->size() - n);
}
@@ -167,8 +172,9 @@ template<typename T> class Span {
* Returns a new Span with n elements removed from the beginning. This invokes undefined
* behavior when the array is too small.
*/
- Span drop_back(uint n) const
+ Span drop_back(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(0, this->size() - n);
}
@@ -177,8 +183,9 @@ template<typename T> class Span {
* Returns a new Span that only contains the first n elements. This invokes undefined
* behavior when the array is too small.
*/
- Span take_front(uint n) const
+ Span take_front(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(0, n);
}
@@ -187,8 +194,9 @@ template<typename T> class Span {
* Returns a new Span that only contains the last n elements. This invokes undefined
* behavior when the array is too small.
*/
- Span take_back(uint n) const
+ Span take_back(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(this->size() - n, n);
}
@@ -216,8 +224,9 @@ template<typename T> class Span {
* Access an element in the array. This invokes undefined behavior when the index is out of
* bounds.
*/
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return start_[index];
}
@@ -225,7 +234,7 @@ template<typename T> class Span {
/**
* Returns the number of elements in the referenced array.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -241,7 +250,7 @@ template<typename T> class Span {
/**
* Returns the number of bytes referenced by this Span.
*/
- uint size_in_bytes() const
+ int64_t size_in_bytes() const
{
return sizeof(T) * size_;
}
@@ -273,9 +282,9 @@ template<typename T> class Span {
* Does a linear search to count how often the value is in the array.
* Returns the number of occurrences.
*/
- uint count(const T &value) const
+ int64_t count(const T &value) const
{
- uint counter = 0;
+ int64_t counter = 0;
for (const T &element : *this) {
if (element == value) {
counter++;
@@ -308,9 +317,9 @@ template<typename T> class Span {
* Returns the element at the given index. If the index is out of range, return the fallback
* value.
*/
- T get(uint index, const T &fallback) const
+ T get(int64_t index, const T &fallback) const
{
- if (index < size_) {
+ if (index < size_ && index >= 0) {
return start_[index];
}
return fallback;
@@ -326,9 +335,9 @@ template<typename T> class Span {
* changed. */
BLI_assert(size_ < 1000);
- for (uint i = 0; i < size_; i++) {
+ for (int64_t i = 0; i < size_; i++) {
const T &value = start_[i];
- for (uint j = i + 1; j < size_; j++) {
+ for (int64_t j = i + 1; j < size_; j++) {
if (value == start_[j]) {
return true;
}
@@ -348,7 +357,7 @@ template<typename T> class Span {
* changed. */
BLI_assert(size_ < 1000);
- for (uint i = 0; i < size_; i++) {
+ for (int64_t i = 0; i < size_; i++) {
const T &value = start_[i];
if (other.contains(value)) {
return true;
@@ -361,19 +370,19 @@ template<typename T> class Span {
* Returns the index of the first occurrence of the given value. This invokes undefined behavior
* when the value is not in the array.
*/
- uint first_index(const T &search_value) const
+ int64_t first_index(const T &search_value) const
{
- const int index = this->first_index_try(search_value);
+ const int64_t index = this->first_index_try(search_value);
BLI_assert(index >= 0);
- return (uint)index;
+ return (int64_t)index;
}
/**
* Returns the index of the first occurrence of the given value or -1 if it does not exist.
*/
- int first_index_try(const T &search_value) const
+ int64_t first_index_try(const T &search_value) const
{
- for (uint i = 0; i < size_; i++) {
+ for (int64_t i = 0; i < size_; i++) {
if (start_[i] == search_value) {
return i;
}
@@ -396,7 +405,7 @@ template<typename T> class Span {
template<typename NewT> Span<NewT> cast() const
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
- uint new_size = size_ * sizeof(T) / sizeof(NewT);
+ int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
return Span<NewT>(reinterpret_cast<const NewT *>(start_), new_size);
}
@@ -431,12 +440,12 @@ template<typename T> class Span {
template<typename T> class MutableSpan {
private:
T *start_;
- uint size_;
+ int64_t size_;
public:
MutableSpan() = default;
- MutableSpan(T *start, const uint size) : start_(start), size_(size)
+ MutableSpan(T *start, const int64_t size) : start_(start), size_(size)
{
}
@@ -456,7 +465,7 @@ template<typename T> class MutableSpan {
/**
* Returns the number of elements in the array.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -473,9 +482,9 @@ template<typename T> class MutableSpan {
* Replace a subset of all elements with the given value. This invokes undefined behavior when
* one of the indices is out of bounds.
*/
- void fill_indices(Span<uint> indices, const T &value)
+ void fill_indices(Span<int64_t> indices, const T &value)
{
- for (uint i : indices) {
+ for (int64_t i : indices) {
BLI_assert(i < size_);
start_[i] = value;
}
@@ -500,7 +509,7 @@ template<typename T> class MutableSpan {
return start_ + size_;
}
- T &operator[](const uint index) const
+ T &operator[](const int64_t index) const
{
BLI_assert(index < this->size());
return start_[index];
@@ -510,7 +519,7 @@ template<typename T> class MutableSpan {
* Returns a contiguous part of the array. This invokes undefined behavior when the slice would
* go out of bounds.
*/
- MutableSpan slice(const uint start, const uint length) const
+ MutableSpan slice(const int64_t start, const int64_t length) const
{
BLI_assert(start + length <= this->size());
return MutableSpan(start_ + start, length);
@@ -520,7 +529,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan with n elements removed from the beginning. This invokes
* undefined behavior when the array is too small.
*/
- MutableSpan drop_front(const uint n) const
+ MutableSpan drop_front(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(n, this->size() - n);
@@ -530,7 +539,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan with n elements removed from the end. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan drop_back(const uint n) const
+ MutableSpan drop_back(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(0, this->size() - n);
@@ -540,7 +549,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan that only contains the first n elements. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan take_front(const uint n) const
+ MutableSpan take_front(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(0, n);
@@ -550,7 +559,7 @@ template<typename T> class MutableSpan {
* Return a new MutableSpan that only contains the last n elements. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan take_back(const uint n) const
+ MutableSpan take_back(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(this->size() - n, n);
@@ -585,12 +594,27 @@ template<typename T> class MutableSpan {
}
/**
+ * Does a linear search to count how often the value is in the array.
+ * Returns the number of occurrences.
+ */
+ int64_t count(const T &value) const
+ {
+ int64_t counter = 0;
+ for (const T &element : *this) {
+ if (element == value) {
+ counter++;
+ }
+ }
+ return counter;
+ }
+
+ /**
* Returns a new span to the same underlying memory buffer. No conversions are done.
*/
template<typename NewT> MutableSpan<NewT> cast() const
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
- uint new_size = size_ * sizeof(T) / sizeof(NewT);
+ int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
return MutableSpan<NewT>(reinterpret_cast<NewT *>(start_), new_size);
}
};
@@ -602,7 +626,7 @@ template<typename T1, typename T2> void assert_same_size(const T1 &v1, const T2
{
UNUSED_VARS_NDEBUG(v1, v2);
#ifdef DEBUG
- uint size = v1.size();
+ int64_t size = v1.size();
BLI_assert(size == v1.size());
BLI_assert(size == v2.size());
#endif
@@ -613,7 +637,7 @@ void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3)
{
UNUSED_VARS_NDEBUG(v1, v2, v3);
#ifdef DEBUG
- uint size = v1.size();
+ int64_t size = v1.size();
BLI_assert(size == v1.size());
BLI_assert(size == v2.size());
BLI_assert(size == v3.size());
diff --git a/source/blender/blenlib/BLI_stack.hh b/source/blender/blenlib/BLI_stack.hh
index a5a95186e37..75ae9df79a4 100644
--- a/source/blender/blenlib/BLI_stack.hh
+++ b/source/blender/blenlib/BLI_stack.hh
@@ -60,7 +60,7 @@ template<typename T> struct StackChunk {
/** Pointer to one element past the end of the referenced buffer. */
T *capacity_end;
- uint capacity() const
+ int64_t capacity() const
{
return capacity_end - begin;
}
@@ -73,11 +73,8 @@ template<
* The number of values that can be stored in this stack, without doing a heap allocation.
* Sometimes it can make sense to increase this value a lot. The memory in the inline buffer is
* not initialized when it is not needed.
- *
- * When T is large, the small buffer optimization is disabled by default to avoid large
- * unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
/**
* The allocator used by this stack. Should rarely be changed, except when you don't want that
* MEM_* is used internally.
@@ -103,7 +100,7 @@ class Stack {
/**
* Number of elements in the entire stack. The sum of initialized element counts in the chunks.
*/
- uint size_;
+ int64_t size_;
/** The buffer used to implement small object optimization. */
TypedBuffer<T, InlineBufferCapacity> inline_buffer_;
@@ -298,8 +295,8 @@ class Stack {
this->activate_next_chunk(remaining_values.size());
}
- const uint remaining_capacity = top_chunk_->capacity_end - top_;
- const uint amount = std::min(remaining_values.size(), remaining_capacity);
+ const int64_t remaining_capacity = top_chunk_->capacity_end - top_;
+ const int64_t amount = std::min(remaining_values.size(), remaining_capacity);
uninitialized_copy_n(remaining_values.data(), amount, top_);
top_ += amount;
@@ -320,7 +317,7 @@ class Stack {
/**
* Returns the number of elements in the stack.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -344,11 +341,11 @@ class Stack {
*
* This invokes undefined behavior when the currently active chunk is not full.
*/
- void activate_next_chunk(const uint size_hint)
+ void activate_next_chunk(const int64_t size_hint)
{
BLI_assert(top_ == top_chunk_->capacity_end);
if (top_chunk_->above == nullptr) {
- const uint new_capacity = std::max(size_hint, top_chunk_->capacity() * 2 + 10);
+ const int64_t new_capacity = std::max(size_hint, top_chunk_->capacity() * 2 + 10);
/* Do a single memory allocation for the Chunk and the array it references. */
void *buffer = allocator_.allocate(
@@ -381,6 +378,13 @@ class Stack {
}
};
+/**
+ * Same as a normal Stack, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
+using RawStack = Stack<T, InlineBufferCapacity, RawAllocator>;
+
} /* namespace blender */
#endif /* __BLI_STACK_HH__ */
diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh
index 5b555b8cd1d..06fc66f6b55 100644
--- a/source/blender/blenlib/BLI_string_ref.hh
+++ b/source/blender/blenlib/BLI_string_ref.hh
@@ -60,9 +60,9 @@ class StringRef;
class StringRefBase {
protected:
const char *data_;
- uint size_;
+ int64_t size_;
- StringRefBase(const char *data, const uint size) : data_(data), size_(size)
+ StringRefBase(const char *data, const int64_t size) : data_(data), size_(size)
{
}
@@ -70,7 +70,7 @@ class StringRefBase {
/**
* Return the (byte-)length of the referenced string, without any null-terminator.
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -94,7 +94,7 @@ class StringRefBase {
*/
operator std::string() const
{
- return std::string(data_, size_);
+ return std::string(data_, (size_t)size_);
}
const char *begin() const
@@ -114,7 +114,7 @@ class StringRefBase {
*/
void unsafe_copy(char *dst) const
{
- memcpy(dst, data_, size_);
+ memcpy(dst, data_, (size_t)size_);
dst[size_] = '\0';
}
@@ -122,7 +122,7 @@ class StringRefBase {
* Copy the string into a buffer. The copied string will be null-terminated. This invokes
* undefined behavior when dst_size is too small. (Should we define the behavior?)
*/
- void copy(char *dst, const uint dst_size) const
+ void copy(char *dst, const int64_t dst_size) const
{
if (size_ < dst_size) {
this->unsafe_copy(dst);
@@ -137,7 +137,7 @@ class StringRefBase {
* Copy the string into a char array. The copied string will be null-terminated. This invokes
* undefined behavior when dst is too small.
*/
- template<uint N> void copy(char (&dst)[N])
+ template<size_t N> void copy(char (&dst)[N])
{
this->copy(dst, N);
}
@@ -152,7 +152,7 @@ class StringRefBase {
*/
bool endswith(StringRef suffix) const;
- StringRef substr(uint start, const uint size) const;
+ StringRef substr(int64_t start, const int64_t size) const;
};
/**
@@ -168,7 +168,7 @@ class StringRefNull : public StringRefBase {
/**
* Construct a StringRefNull from a null terminated c-string. The pointer must not point to NULL.
*/
- StringRefNull(const char *str) : StringRefBase(str, (uint)strlen(str))
+ StringRefNull(const char *str) : StringRefBase(str, (int64_t)strlen(str))
{
BLI_assert(str != NULL);
BLI_assert(data_[size_] == '\0');
@@ -178,9 +178,9 @@ class StringRefNull : public StringRefBase {
* Construct a StringRefNull from a null terminated c-string. This invokes undefined behavior
* when the given size is not the correct size of the string.
*/
- StringRefNull(const char *str, const uint size) : StringRefBase(str, size)
+ StringRefNull(const char *str, const int64_t size) : StringRefBase(str, size)
{
- BLI_assert((uint)strlen(str) == size);
+ BLI_assert((int64_t)strlen(str) == size);
}
/**
@@ -194,8 +194,9 @@ class StringRefNull : public StringRefBase {
/**
* Get the char at the given index.
*/
- char operator[](const uint index) const
+ char operator[](const int64_t index) const
{
+ BLI_assert(index >= 0);
/* Use '<=' instead of just '<', so that the null character can be accessed as well. */
BLI_assert(index <= size_);
return data_[index];
@@ -231,11 +232,11 @@ class StringRef : public StringRefBase {
/**
* Create a StringRef from a null-terminated c-string.
*/
- StringRef(const char *str) : StringRefBase(str, str ? (uint)strlen(str) : 0)
+ StringRef(const char *str) : StringRefBase(str, str ? (int64_t)strlen(str) : 0)
{
}
- StringRef(const char *str, const uint length) : StringRefBase(str, length)
+ StringRef(const char *str, const int64_t length) : StringRefBase(str, length)
{
}
@@ -244,7 +245,7 @@ class StringRef : public StringRefBase {
* second point points to a smaller address than the first one.
*/
StringRef(const char *begin, const char *one_after_end)
- : StringRefBase(begin, (uint)(one_after_end - begin))
+ : StringRefBase(begin, (int64_t)(one_after_end - begin))
{
BLI_assert(begin <= one_after_end);
}
@@ -253,15 +254,16 @@ class StringRef : public StringRefBase {
* Reference a std::string. Remember that when the std::string is destructed, the StringRef
* will point to uninitialized memory.
*/
- StringRef(const std::string &str) : StringRefBase(str.data(), (uint)str.size())
+ StringRef(const std::string &str) : StringRefBase(str.data(), (int64_t)str.size())
{
}
/**
* Return a new StringRef that does not contain the first n chars.
*/
- StringRef drop_prefix(const uint n) const
+ StringRef drop_prefix(const int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= size_);
return StringRef(data_ + n, size_ - n);
}
@@ -279,8 +281,9 @@ class StringRef : public StringRefBase {
/**
* Get the char at the given index.
*/
- char operator[](uint index) const
+ char operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < size_);
return data_[index];
}
@@ -297,7 +300,7 @@ inline std::ostream &operator<<(std::ostream &stream, StringRef ref)
inline std::ostream &operator<<(std::ostream &stream, StringRefNull ref)
{
- stream << std::string(ref.data(), ref.size());
+ stream << std::string(ref.data(), (size_t)ref.size());
return stream;
}
@@ -315,7 +318,7 @@ inline bool operator==(StringRef a, StringRef b)
if (a.size() != b.size()) {
return false;
}
- return STREQLEN(a.data(), b.data(), a.size());
+ return STREQLEN(a.data(), b.data(), (size_t)a.size());
}
inline bool operator!=(StringRef a, StringRef b)
@@ -331,7 +334,7 @@ inline bool StringRefBase::startswith(StringRef prefix) const
if (size_ < prefix.size_) {
return false;
}
- for (uint i = 0; i < prefix.size_; i++) {
+ for (int64_t i = 0; i < prefix.size_; i++) {
if (data_[i] != prefix.data_[i]) {
return false;
}
@@ -347,8 +350,8 @@ inline bool StringRefBase::endswith(StringRef suffix) const
if (size_ < suffix.size_) {
return false;
}
- const uint offset = size_ - suffix.size_;
- for (uint i = 0; i < suffix.size_; i++) {
+ const int64_t offset = size_ - suffix.size_;
+ for (int64_t i = 0; i < suffix.size_; i++) {
if (data_[offset + i] != suffix.data_[i]) {
return false;
}
@@ -359,8 +362,10 @@ inline bool StringRefBase::endswith(StringRef suffix) const
/**
* Return a new #StringRef containing only a sub-string of the original string.
*/
-inline StringRef StringRefBase::substr(const uint start, const uint size) const
+inline StringRef StringRefBase::substr(const int64_t start, const int64_t size) const
{
+ BLI_assert(size >= 0);
+ BLI_assert(start >= 0);
BLI_assert(start + size <= size_);
return StringRef(data_ + start, size);
}
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index 1fe38464ad0..1bb674093bb 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -70,7 +70,7 @@ template<
* When T is large, the small buffer optimization is disabled by default to avoid large
* unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
/**
* The allocator used by this vector. Should rarely be changed, except when you don't want that
* MEM_* is used internally.
@@ -100,8 +100,8 @@ class Vector {
* annoying. Knowing the size of a vector is often quite essential when debugging some code.
*/
#ifndef NDEBUG
- uint debug_size_;
-# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = (uint)((ptr)->end_ - (ptr)->begin_)
+ int64_t debug_size_;
+# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = (int64_t)((ptr)->end_ - (ptr)->begin_)
#else
# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
#endif
@@ -110,7 +110,7 @@ class Vector {
* Be a friend with other vector instantiations. This is necessary to implement some memory
* management logic.
*/
- template<typename OtherT, uint OtherInlineBufferCapacity, typename OtherAllocator>
+ template<typename OtherT, int64_t OtherInlineBufferCapacity, typename OtherAllocator>
friend class Vector;
public:
@@ -131,7 +131,7 @@ class Vector {
* The elements will be default constructed.
* If T is trivially constructible, the elements in the vector are not touched.
*/
- explicit Vector(uint size) : Vector()
+ explicit Vector(int64_t size) : Vector()
{
this->resize(size);
}
@@ -139,7 +139,7 @@ class Vector {
/**
* Create a vector filled with a specific value.
*/
- Vector(uint size, const T &value) : Vector()
+ Vector(int64_t size, const T &value) : Vector()
{
this->resize(size, value);
}
@@ -150,7 +150,7 @@ class Vector {
template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
Vector(Span<U> values, Allocator allocator = {}) : Vector(allocator)
{
- const uint size = values.size();
+ const int64_t size = values.size();
this->reserve(size);
this->increase_size_by_unchecked(size);
uninitialized_convert_n<U, T>(values.data(), size, begin_);
@@ -217,7 +217,7 @@ class Vector {
* Create a copy of a vector with a different InlineBufferCapacity. This needs to be handled
* separately, so that the other one is a valid copy constructor.
*/
- template<uint OtherInlineBufferCapacity>
+ template<int64_t OtherInlineBufferCapacity>
Vector(const Vector<T, OtherInlineBufferCapacity, Allocator> &other)
: Vector(other.as_span(), other.allocator_)
{
@@ -227,11 +227,11 @@ class Vector {
* Steal the elements from another vector. This does not do an allocation. The other vector will
* have zero elements afterwards.
*/
- template<uint OtherInlineBufferCapacity>
+ template<int64_t OtherInlineBufferCapacity>
Vector(Vector<T, OtherInlineBufferCapacity, Allocator> &&other) noexcept
: allocator_(other.allocator_)
{
- const uint size = other.size();
+ const int64_t size = other.size();
if (other.is_inline()) {
if (size <= InlineBufferCapacity) {
@@ -243,8 +243,8 @@ class Vector {
}
else {
/* Copy from inline buffer to newly allocated buffer. */
- const uint capacity = size;
- begin_ = (T *)allocator_.allocate(sizeof(T) * capacity, alignof(T), AT);
+ const int64_t capacity = size;
+ begin_ = (T *)allocator_.allocate(sizeof(T) * (size_t)capacity, alignof(T), AT);
end_ = begin_ + size;
capacity_end_ = begin_ + capacity;
uninitialized_relocate_n(other.begin_, size, begin_);
@@ -302,14 +302,16 @@ class Vector {
* Get the value at the given index. This invokes undefined behavior when the index is out of
* bounds.
*/
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return begin_[index];
}
- T &operator[](uint index)
+ T &operator[](int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return begin_[index];
}
@@ -351,7 +353,7 @@ class Vector {
* This won't necessarily make an allocation when min_capacity is small.
* The actual size of the vector does not change.
*/
- void reserve(const uint min_capacity)
+ void reserve(const int64_t min_capacity)
{
if (min_capacity > this->capacity()) {
this->realloc_to_at_least(min_capacity);
@@ -364,9 +366,10 @@ class Vector {
* destructed. If new_size is larger than the old size, the new elements at the end are default
* constructed. If T is trivially constructible, the memory is not touched by this function.
*/
- void resize(const uint new_size)
+ void resize(const int64_t new_size)
{
- const uint old_size = this->size();
+ BLI_assert(new_size >= 0);
+ const int64_t old_size = this->size();
if (new_size > old_size) {
this->reserve(new_size);
default_construct_n(begin_ + old_size, new_size - old_size);
@@ -384,9 +387,10 @@ class Vector {
* destructed. If new_size is larger than the old size, the new elements will be copy constructed
* from the given value.
*/
- void resize(const uint new_size, const T &value)
+ void resize(const int64_t new_size, const T &value)
{
- const uint old_size = this->size();
+ BLI_assert(new_size >= 0);
+ const int64_t old_size = this->size();
if (new_size > old_size) {
this->reserve(new_size);
uninitialized_fill_n(begin_ + old_size, new_size - old_size, value);
@@ -447,9 +451,9 @@ class Vector {
* Append the value to the vector and return the index that can be used to access the newly
* added value.
*/
- uint append_and_get_index(const T &value)
+ int64_t append_and_get_index(const T &value)
{
- const uint index = this->size();
+ const int64_t index = this->size();
this->append(value);
return index;
}
@@ -490,8 +494,9 @@ class Vector {
* Insert the same element n times at the end of the vector.
* This might result in a reallocation internally.
*/
- void append_n_times(const T &value, const uint n)
+ void append_n_times(const T &value, const int64_t n)
{
+ BLI_assert(n >= 0);
this->reserve(this->size() + n);
blender::uninitialized_fill_n(end_, n, value);
this->increase_size_by_unchecked(n);
@@ -503,7 +508,7 @@ class Vector {
* useful when you want to call constructors in the vector yourself. This should only be done in
* very rare cases and has to be justified every time.
*/
- void increase_size_by_unchecked(const uint n)
+ void increase_size_by_unchecked(const int64_t n)
{
BLI_assert(end_ + n <= capacity_end_);
end_ += n;
@@ -519,7 +524,7 @@ class Vector {
{
this->extend(array.data(), array.size());
}
- void extend(const T *start, uint amount)
+ void extend(const T *start, int64_t amount)
{
this->reserve(this->size() + amount);
this->extend_unchecked(start, amount);
@@ -545,8 +550,9 @@ class Vector {
{
this->extend_unchecked(array.data(), array.size());
}
- void extend_unchecked(const T *start, uint amount)
+ void extend_unchecked(const T *start, int64_t amount)
{
+ BLI_assert(amount >= 0);
BLI_assert(begin_ + amount <= capacity_end_);
blender::uninitialized_copy_n(start, amount, end_);
end_ += amount;
@@ -569,28 +575,12 @@ class Vector {
}
/**
- * Replace every element with a new value.
- */
- void fill(const T &value)
- {
- initialized_fill_n(begin_, this->size(), value);
- }
-
- /**
- * Copy the value to all positions specified by the indices array.
- */
- void fill_indices(Span<uint> indices, const T &value)
- {
- MutableSpan<T>(*this).fill_indices(indices, value);
- }
-
- /**
* Return how many values are currently stored in the vector.
*/
- uint size() const
+ int64_t size() const
{
- BLI_assert(debug_size_ == (uint)(end_ - begin_));
- return (uint)(end_ - begin_);
+ BLI_assert(debug_size_ == (int64_t)(end_ - begin_));
+ return (int64_t)(end_ - begin_);
}
/**
@@ -635,8 +625,9 @@ class Vector {
* Delete any element in the vector. The empty space will be filled by the previously last
* element. This takes O(1) time.
*/
- void remove_and_reorder(const uint index)
+ void remove_and_reorder(const int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
T *element_to_remove = begin_ + index;
end_--;
@@ -653,8 +644,8 @@ class Vector {
*/
void remove_first_occurrence_and_reorder(const T &value)
{
- const uint index = this->first_index_of(value);
- this->remove_and_reorder((uint)index);
+ const int64_t index = this->first_index_of(value);
+ this->remove_and_reorder(index);
}
/**
@@ -664,11 +655,12 @@ class Vector {
*
* This is similar to std::vector::erase.
*/
- void remove(const uint index)
+ void remove(const int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
- const uint last_index = this->size() - 1;
- for (uint i = index; i < last_index; i++) {
+ const int64_t last_index = this->size() - 1;
+ for (int64_t i = index; i < last_index; i++) {
begin_[i] = std::move(begin_[i + 1]);
}
begin_[last_index].~T();
@@ -680,11 +672,11 @@ class Vector {
* Do a linear search to find the value in the vector.
* When found, return the first index, otherwise return -1.
*/
- int first_index_of_try(const T &value) const
+ int64_t first_index_of_try(const T &value) const
{
for (const T *current = begin_; current != end_; current++) {
if (*current == value) {
- return (int)(current - begin_);
+ return (int64_t)(current - begin_);
}
}
return -1;
@@ -694,11 +686,11 @@ class Vector {
* Do a linear search to find the value in the vector and return the found index. This invokes
* undefined behavior when the value is not in the vector.
*/
- uint first_index_of(const T &value) const
+ int64_t first_index_of(const T &value) const
{
- const int index = this->first_index_of_try(value);
+ const int64_t index = this->first_index_of_try(value);
BLI_assert(index >= 0);
- return (uint)index;
+ return index;
}
/**
@@ -711,6 +703,14 @@ class Vector {
}
/**
+ * Copies the given value to every element in the vector.
+ */
+ void fill(const T &value) const
+ {
+ initialized_fill_n(begin_, this->size(), value);
+ }
+
+ /**
* Get access to the underlying array.
*/
T *data()
@@ -748,9 +748,9 @@ class Vector {
* Get the current capacity of the vector, i.e. the maximum number of elements the vector can
* hold, before it has to reallocate.
*/
- uint capacity() const
+ int64_t capacity() const
{
- return (uint)(capacity_end_ - begin_);
+ return (int64_t)(capacity_end_ - begin_);
}
/**
@@ -758,7 +758,7 @@ class Vector {
* Obviously, this should only be used when you actually need the index in the loop.
*
* Example:
- * for (uint i : myvector.index_range()) {
+ * for (int64_t i : myvector.index_range()) {
* do_something(i, my_vector[i]);
* }
*/
@@ -796,7 +796,7 @@ class Vector {
}
}
- BLI_NOINLINE void realloc_to_at_least(const uint min_capacity)
+ BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity)
{
if (this->capacity() >= min_capacity) {
return;
@@ -804,12 +804,12 @@ class Vector {
/* At least double the size of the previous allocation. Otherwise consecutive calls to grow can
* cause a reallocation every time even though min_capacity only increments. */
- const uint min_new_capacity = this->capacity() * 2;
+ const int64_t min_new_capacity = this->capacity() * 2;
- const uint new_capacity = std::max(min_capacity, min_new_capacity);
- const uint size = this->size();
+ const int64_t new_capacity = std::max(min_capacity, min_new_capacity);
+ const int64_t size = this->size();
- T *new_array = (T *)allocator_.allocate(new_capacity * (uint)sizeof(T), alignof(T), AT);
+ T *new_array = (T *)allocator_.allocate((size_t)new_capacity * sizeof(T), alignof(T), AT);
uninitialized_relocate_n(begin_, size, new_array);
if (!this->is_inline()) {
@@ -824,6 +824,13 @@ class Vector {
#undef UPDATE_VECTOR_SIZE
+/**
+ * Same as a normal Vector, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
+using RawVector = Vector<T, InlineBufferCapacity, RawAllocator>;
+
} /* namespace blender */
#endif /* __BLI_VECTOR_HH__ */
diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh
index dd1b17653c0..f007d41118f 100644
--- a/source/blender/blenlib/BLI_vector_set.hh
+++ b/source/blender/blenlib/BLI_vector_set.hh
@@ -106,20 +106,20 @@ class VectorSet {
* Slots are either empty, occupied or removed. The number of occupied slots can be computed by
* subtracting the removed slots from the occupied-and-removed slots.
*/
- uint32_t removed_slots_;
- uint32_t occupied_and_removed_slots_;
+ int64_t removed_slots_;
+ int64_t occupied_and_removed_slots_;
/**
* The maximum number of slots that can be used (either occupied or removed) until the set has to
* grow. This is the total number of slots times the max load factor.
*/
- uint32_t usable_slots_;
+ int64_t usable_slots_;
/**
* The number of slots minus one. This is a bit mask that can be used to turn any integer into a
* valid slot index efficiently.
*/
- uint32_t slot_mask_;
+ uint64_t slot_mask_;
/** This is called to hash incoming keys. */
Hash hash_;
@@ -238,8 +238,9 @@ class VectorSet {
/**
* Get the key stored at the given position in the vector.
*/
- const Key &operator[](const uint32_t index) const
+ const Key &operator[](const int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index <= this->size());
return keys_[index];
}
@@ -362,11 +363,11 @@ class VectorSet {
* Return the location of the key in the vector. It is assumed, that the key is in the vector
* set. If this is not necessarily the case, use `index_of_try`.
*/
- uint32_t index_of(const Key &key) const
+ int64_t index_of(const Key &key) const
{
return this->index_of_as(key);
}
- template<typename ForwardKey> uint32_t index_of_as(const ForwardKey &key) const
+ template<typename ForwardKey> int64_t index_of_as(const ForwardKey &key) const
{
return this->index_of__impl(key, hash_(key));
}
@@ -375,11 +376,11 @@ class VectorSet {
* Return the location of the key in the vector. If the key is not in the set, -1 is returned.
* If you know for sure that the key is in the set, it is better to use `index_of` instead.
*/
- int32_t index_of_try(const Key &key) const
+ int64_t index_of_try(const Key &key) const
{
- return (int32_t)this->index_of_try_as(key);
+ return this->index_of_try_as(key);
}
- template<typename ForwardKey> int32_t index_of_try_as(const ForwardKey &key) const
+ template<typename ForwardKey> int64_t index_of_try_as(const ForwardKey &key) const
{
return this->index_of_try__impl(key, hash_(key));
}
@@ -414,7 +415,7 @@ class VectorSet {
/**
* Returns the number of keys stored in the vector set.
*/
- uint32_t size() const
+ int64_t size() const
{
return occupied_and_removed_slots_ - removed_slots_;
}
@@ -430,7 +431,7 @@ class VectorSet {
/**
* Returns the number of available slots. This is mostly for debugging purposes.
*/
- uint32_t capacity() const
+ int64_t capacity() const
{
return slots_.size();
}
@@ -438,7 +439,7 @@ class VectorSet {
/**
* Returns the amount of removed slots in the set. This is mostly for debugging purposes.
*/
- uint32_t removed_amount() const
+ int64_t removed_amount() const
{
return removed_slots_;
}
@@ -446,7 +447,7 @@ class VectorSet {
/**
* Returns the bytes required per element. This is mostly for debugging purposes.
*/
- uint32_t size_per_element() const
+ int64_t size_per_element() const
{
return sizeof(Slot) + sizeof(Key);
}
@@ -455,15 +456,15 @@ class VectorSet {
* Returns the approximate memory requirements of the set in bytes. This is more correct for
* larger sets.
*/
- uint32_t size_in_bytes() const
+ int64_t size_in_bytes() const
{
- return (uint32_t)(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
+ return (int64_t)(sizeof(Slot) * slots_.size() + sizeof(Key) * usable_slots_);
}
/**
* Potentially resize the vector set such that it can hold n elements without doing another grow.
*/
- void reserve(const uint32_t n)
+ void reserve(const int64_t n)
{
if (usable_slots_ < n) {
this->realloc_and_reinsert(n);
@@ -474,18 +475,19 @@ class VectorSet {
* Get the number of collisions that the probing strategy has to go through to find the key or
* determine that it is not in the set.
*/
- uint32_t count_collisions(const Key &key) const
+ int64_t count_collisions(const Key &key) const
{
return this->count_collisions__impl(key, hash_(key));
}
private:
- BLI_NOINLINE void realloc_and_reinsert(const uint32_t min_usable_slots)
+ BLI_NOINLINE void realloc_and_reinsert(const int64_t min_usable_slots)
{
- uint32_t total_slots, usable_slots;
+ int64_t total_slots, usable_slots;
max_load_factor_.compute_total_and_usable_slots(
SlotArray::inline_buffer_capacity(), min_usable_slots, &total_slots, &usable_slots);
- const uint32_t new_slot_mask = total_slots - 1;
+ BLI_assert(total_slots >= 1);
+ const uint64_t new_slot_mask = (uint64_t)total_slots - 1;
/* Optimize the case when the set was empty beforehand. We can avoid some copies here. */
if (this->size() == 0) {
@@ -524,10 +526,10 @@ class VectorSet {
void add_after_grow_and_destruct_old(Slot &old_slot,
SlotArray &new_slots,
- const uint32_t new_slot_mask)
+ const uint64_t new_slot_mask)
{
const Key &key = keys_[old_slot.index()];
- const uint32_t hash = old_slot.get_hash(key, Hash());
+ const uint64_t hash = old_slot.get_hash(key, Hash());
SLOT_PROBING_BEGIN (ProbingStrategy, hash, new_slot_mask, slot_index) {
Slot &slot = new_slots[slot_index];
@@ -540,7 +542,7 @@ class VectorSet {
}
template<typename ForwardKey>
- bool contains__impl(const ForwardKey &key, const uint32_t hash) const
+ bool contains__impl(const ForwardKey &key, const uint64_t hash) const
{
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
@@ -553,7 +555,7 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> void add_new__impl(ForwardKey &&key, const uint64_t hash)
{
BLI_assert(!this->contains_as(key));
@@ -561,7 +563,7 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
- uint32_t index = this->size();
+ int64_t index = this->size();
new (keys_ + index) Key(std::forward<ForwardKey>(key));
slot.occupy(index, hash);
occupied_and_removed_slots_++;
@@ -571,13 +573,13 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint32_t hash)
+ template<typename ForwardKey> bool add__impl(ForwardKey &&key, const uint64_t hash)
{
this->ensure_can_add();
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.is_empty()) {
- uint32_t index = this->size();
+ int64_t index = this->size();
new (keys_ + index) Key(std::forward<ForwardKey>(key));
occupied_and_removed_slots_++;
slot.occupy(index, hash);
@@ -591,7 +593,7 @@ class VectorSet {
}
template<typename ForwardKey>
- uint32_t index_of__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t index_of__impl(const ForwardKey &key, const uint64_t hash) const
{
BLI_assert(this->contains_as(key));
@@ -604,11 +606,11 @@ class VectorSet {
}
template<typename ForwardKey>
- int32_t index_of_try__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t index_of_try__impl(const ForwardKey &key, const uint64_t hash) const
{
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash, keys_)) {
- return (int32_t)slot.index();
+ return slot.index();
}
if (slot.is_empty()) {
return -1;
@@ -621,10 +623,10 @@ class VectorSet {
{
BLI_assert(this->size() > 0);
- const uint32_t index_to_pop = this->size() - 1;
+ const int64_t index_to_pop = this->size() - 1;
Key key = std::move(keys_[index_to_pop]);
keys_[index_to_pop].~Key();
- const uint32_t hash = hash_(key);
+ const uint64_t hash = hash_(key);
removed_slots_++;
@@ -637,7 +639,7 @@ class VectorSet {
VECTOR_SET_SLOT_PROBING_END();
}
- template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint32_t hash)
+ template<typename ForwardKey> bool remove__impl(const ForwardKey &key, const uint64_t hash)
{
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash, keys_)) {
@@ -652,7 +654,7 @@ class VectorSet {
}
template<typename ForwardKey>
- void remove_contained__impl(const ForwardKey &key, const uint32_t hash)
+ void remove_contained__impl(const ForwardKey &key, const uint64_t hash)
{
BLI_assert(this->contains_as(key));
@@ -667,9 +669,9 @@ class VectorSet {
void remove_key_internal(Slot &slot)
{
- uint32_t index_to_remove = slot.index();
- uint32_t size = this->size();
- uint32_t last_element_index = size - 1;
+ int64_t index_to_remove = slot.index();
+ int64_t size = this->size();
+ int64_t last_element_index = size - 1;
if (index_to_remove < last_element_index) {
keys_[index_to_remove] = std::move(keys_[last_element_index]);
@@ -682,9 +684,9 @@ class VectorSet {
return;
}
- void update_slot_index(const Key &key, const uint32_t old_index, const uint32_t new_index)
+ void update_slot_index(const Key &key, const int64_t old_index, const int64_t new_index)
{
- uint32_t hash = hash_(key);
+ uint64_t hash = hash_(key);
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.has_index(old_index)) {
slot.update_index(new_index);
@@ -695,9 +697,9 @@ class VectorSet {
}
template<typename ForwardKey>
- uint32_t count_collisions__impl(const ForwardKey &key, const uint32_t hash) const
+ int64_t count_collisions__impl(const ForwardKey &key, const uint64_t hash) const
{
- uint32_t collisions = 0;
+ int64_t collisions = 0;
VECTOR_SET_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, is_equal_, hash, keys_)) {
@@ -719,9 +721,9 @@ class VectorSet {
}
}
- Key *allocate_keys_array(const uint32_t size)
+ Key *allocate_keys_array(const int64_t size)
{
- return (Key *)slots_.allocator().allocate((uint32_t)sizeof(Key) * size, alignof(Key), AT);
+ return (Key *)slots_.allocator().allocate(sizeof(Key) * (size_t)size, alignof(Key), AT);
}
void deallocate_keys_array(Key *keys)
@@ -730,6 +732,17 @@ class VectorSet {
}
};
+/**
+ * Same as a normal VectorSet, but does not use Blender's guarded allocator. This is useful when
+ * allocating memory with static storage duration.
+ */
+template<typename Key,
+ typename ProbingStrategy = DefaultProbingStrategy,
+ typename Hash = DefaultHash<Key>,
+ typename IsEqual = DefaultEquality,
+ typename Slot = typename DefaultVectorSetSlot<Key>::type>
+using RawVectorSet = VectorSet<Key, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>;
+
} // namespace blender
#endif /* __BLI_VECTOR_SET_HH__ */
diff --git a/source/blender/blenlib/BLI_vector_set_slots.hh b/source/blender/blenlib/BLI_vector_set_slots.hh
index e43b892b3f7..49e6d4daedb 100644
--- a/source/blender/blenlib/BLI_vector_set_slots.hh
+++ b/source/blender/blenlib/BLI_vector_set_slots.hh
@@ -53,7 +53,7 @@ template<typename Key> class SimpleVectorSetSlot {
/**
* After the default constructor has run, the slot has to be in the empty state.
*/
- int32_t state_ = s_is_empty;
+ int64_t state_ = s_is_empty;
public:
/**
@@ -75,10 +75,10 @@ template<typename Key> class SimpleVectorSetSlot {
/**
* Return the stored index. It is assumed that the slot is occupied.
*/
- uint32_t index() const
+ int64_t index() const
{
BLI_assert(this->is_occupied());
- return (uint32_t)state_;
+ return state_;
}
/**
@@ -88,7 +88,7 @@ template<typename Key> class SimpleVectorSetSlot {
template<typename ForwardKey, typename IsEqual>
bool contains(const ForwardKey &key,
const IsEqual &is_equal,
- uint32_t UNUSED(hash),
+ uint64_t UNUSED(hash),
const Key *keys) const
{
if (state_ >= 0) {
@@ -102,7 +102,7 @@ template<typename Key> class SimpleVectorSetSlot {
* we can avoid a comparison with the state, since we know the slot is occupied. For this
* specific slot implementation, this does not make a difference.
*/
- void relocate_occupied_here(SimpleVectorSetSlot &other, uint32_t UNUSED(hash))
+ void relocate_occupied_here(SimpleVectorSetSlot &other, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
BLI_assert(other.is_occupied());
@@ -113,20 +113,20 @@ template<typename Key> class SimpleVectorSetSlot {
* Change the state of this slot from empty/removed to occupied. The hash can be used by other
* slot implementations.
*/
- void occupy(uint32_t index, uint32_t UNUSED(hash))
+ void occupy(int64_t index, uint64_t UNUSED(hash))
{
BLI_assert(!this->is_occupied());
- state_ = (int32_t)index;
+ state_ = index;
}
/**
* The key has changed its position in the vector, so the index has to be updated. This method
* can assume that the slot is currently occupied.
*/
- void update_index(uint32_t index)
+ void update_index(int64_t index)
{
BLI_assert(this->is_occupied());
- state_ = (int32_t)index;
+ state_ = index;
}
/**
@@ -141,16 +141,16 @@ template<typename Key> class SimpleVectorSetSlot {
/**
* Return true if this slot is currently occupied and its corresponding key has the given index.
*/
- bool has_index(uint32_t index) const
+ bool has_index(int64_t index) const
{
- return (uint32_t)state_ == index;
+ return state_ == index;
}
/**
* Return the hash of the currently stored key. In this simple set slot implementation, we just
* compute the hash here. Other implementations might store the hash in the slot instead.
*/
- template<typename Hash> uint32_t get_hash(const Key &key, const Hash &hash) const
+ template<typename Hash> uint64_t get_hash(const Key &key, const Hash &hash) const
{
BLI_assert(this->is_occupied());
return hash(key);
diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc
index 9fa19143f91..43c6265a17d 100644
--- a/source/blender/blenlib/intern/BLI_index_range.cc
+++ b/source/blender/blenlib/intern/BLI_index_range.cc
@@ -24,28 +24,28 @@
namespace blender {
-static Vector<Array<uint, 0, RawAllocator>, 1, RawAllocator> arrays;
-static uint current_array_size = 0;
-static uint *current_array = nullptr;
+static RawVector<RawArray<int64_t, 0>> arrays;
+static int64_t current_array_size = 0;
+static int64_t *current_array = nullptr;
static std::mutex current_array_mutex;
-Span<uint> IndexRange::as_span() const
+Span<int64_t> IndexRange::as_span() const
{
- uint min_required_size = start_ + size_;
+ int64_t min_required_size = start_ + size_;
if (min_required_size <= current_array_size) {
- return Span<uint>(current_array + start_, size_);
+ return Span<int64_t>(current_array + start_, size_);
}
std::lock_guard<std::mutex> lock(current_array_mutex);
if (min_required_size <= current_array_size) {
- return Span<uint>(current_array + start_, size_);
+ return Span<int64_t>(current_array + start_, size_);
}
- uint new_size = std::max<uint>(1000, power_of_2_max_u(min_required_size));
- Array<uint, 0, RawAllocator> new_array(new_size);
- for (uint i = 0; i < new_size; i++) {
+ int64_t new_size = std::max<int64_t>(1000, power_of_2_max_u(min_required_size));
+ RawArray<int64_t, 0> new_array(new_size);
+ for (int64_t i = 0; i < new_size; i++) {
new_array[i] = i;
}
arrays.append(std::move(new_array));
@@ -54,7 +54,7 @@ Span<uint> IndexRange::as_span() const
std::atomic_thread_fence(std::memory_order_seq_cst);
current_array_size = new_size;
- return Span<uint>(current_array + start_, size_);
+ return Span<int64_t>(current_array + start_, size_);
}
} // namespace blender
diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc
index 0f60ea6fd1b..48b6dc826d0 100644
--- a/source/blender/blenlib/intern/dot_export.cc
+++ b/source/blender/blenlib/intern/dot_export.cc
@@ -263,8 +263,8 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
ss << "</b></td></tr>";
/* Sockets */
- uint socket_max_amount = std::max(input_names.size(), output_names.size());
- for (uint i = 0; i < socket_max_amount; i++) {
+ int socket_max_amount = std::max(input_names.size(), output_names.size());
+ for (int i = 0; i < socket_max_amount; i++) {
ss << "<tr>";
if (i < input_names.size()) {
StringRef name = input_names[i];
diff --git a/source/blender/blenlib/intern/rand.cc b/source/blender/blenlib/intern/rand.cc
index 279682ea171..9bafc422db5 100644
--- a/source/blender/blenlib/intern/rand.cc
+++ b/source/blender/blenlib/intern/rand.cc
@@ -93,8 +93,7 @@ void BLI_rng_srandom(RNG *rng, unsigned int seed)
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
{
- BLI_assert(bytes_len > UINT32_MAX);
- rng->rng.get_bytes(blender::MutableSpan(bytes, (uint32_t)bytes_len));
+ rng->rng.get_bytes(blender::MutableSpan(bytes, (int64_t)bytes_len));
}
int BLI_rng_get_int(RNG *rng)
@@ -428,11 +427,11 @@ float2 RandomNumberGenerator::get_triangle_sample(float2 v1, float2 v2, float2 v
void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
{
- constexpr uint mask_bytes = 2;
- constexpr uint rand_stride = (uint)sizeof(x_) - mask_bytes;
+ constexpr int64_t mask_bytes = 2;
+ constexpr int64_t rand_stride = (int64_t)sizeof(x_) - mask_bytes;
- uint last_len = 0;
- uint trim_len = r_bytes.size();
+ int64_t last_len = 0;
+ int64_t trim_len = r_bytes.size();
if (trim_len > rand_stride) {
last_len = trim_len % rand_stride;
@@ -444,13 +443,13 @@ void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
}
const char *data_src = (const char *)&x_;
- uint i = 0;
+ int64_t i = 0;
while (i != trim_len) {
BLI_assert(i < trim_len);
#ifdef __BIG_ENDIAN__
- for (uint j = (rand_stride + mask_bytes) - 1; j != mask_bytes - 1; j--)
+ for (int64_t j = (rand_stride + mask_bytes) - 1; j != mask_bytes - 1; j--)
#else
- for (uint j = 0; j != rand_stride; j++)
+ for (int64_t j = 0; j != rand_stride; j++)
#endif
{
r_bytes[i++] = data_src[j];
@@ -458,7 +457,7 @@ void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
this->step();
}
if (last_len) {
- for (uint j = 0; j != last_len; j++) {
+ for (int64_t j = 0; j != last_len; j++) {
r_bytes[i++] = data_src[j];
}
}
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index f17c04a8a5c..12da7629017 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -197,6 +197,14 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
* \note Keep this message at the bottom of the function.
*/
{
+ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
+ if (BKE_collection_cycles_fix(bmain, collection)) {
+ printf(
+ "WARNING: Cycle detected in collection '%s', fixed as best as possible.\n"
+ "You may have to reconstruct your View Layers...\n",
+ collection->id.name);
+ }
+ }
/* Keep this block, even when empty. */
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
index 1095905c570..750bccf0e52 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.cc
@@ -72,11 +72,11 @@ bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b)
return a.data == b.data && a.property_rna == b.property_rna;
}
-uint32_t AnimatedPropertyID::hash() const
+uint64_t AnimatedPropertyID::hash() const
{
uintptr_t ptr1 = (uintptr_t)data;
uintptr_t ptr2 = (uintptr_t)property_rna;
- return (uint32_t)(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
+ return (uint64_t)(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
}
namespace {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cache.h b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
index 43348e3bf23..e04ae3a3727 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cache.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cache.h
@@ -47,7 +47,7 @@ class AnimatedPropertyID {
AnimatedPropertyID(ID *id, StructRNA *type, const char *property_name);
AnimatedPropertyID(ID *id, StructRNA *type, void *data, const char *property_name);
- uint32_t hash() const;
+ uint64_t hash() const;
friend bool operator==(const AnimatedPropertyID &a, const AnimatedPropertyID &b);
/* Corresponds to PointerRNA.data. */
diff --git a/source/blender/depsgraph/intern/depsgraph_registry.cc b/source/blender/depsgraph/intern/depsgraph_registry.cc
index 6bfd2e881cc..c9d03e47ded 100644
--- a/source/blender/depsgraph/intern/depsgraph_registry.cc
+++ b/source/blender/depsgraph/intern/depsgraph_registry.cc
@@ -30,7 +30,7 @@
namespace blender {
namespace deg {
-static Map<Main *, VectorSet<Depsgraph *>> g_graph_registry;
+static RawMap<Main *, RawVectorSet<Depsgraph *>> g_graph_registry;
void register_graph(Depsgraph *depsgraph)
{
@@ -41,7 +41,7 @@ void register_graph(Depsgraph *depsgraph)
void unregister_graph(Depsgraph *depsgraph)
{
Main *bmain = depsgraph->bmain;
- VectorSet<Depsgraph *> &graphs = g_graph_registry.lookup(bmain);
+ RawVectorSet<Depsgraph *> &graphs = g_graph_registry.lookup(bmain);
graphs.remove(depsgraph);
// If this was the last depsgraph associated with the main, remove the main entry as well.
@@ -52,7 +52,7 @@ void unregister_graph(Depsgraph *depsgraph)
Span<Depsgraph *> get_all_registered_graphs(Main *bmain)
{
- VectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain);
+ RawVectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain);
if (graphs != nullptr) {
return *graphs;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
index f2d9a87ca9d..934403674a9 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.cc
@@ -41,7 +41,7 @@ bool operator==(const ModifierDataBackupID &a, const ModifierDataBackupID &b)
return a.modifier_data == b.modifier_data && a.type == b.type;
}
-uint32_t ModifierDataBackupID::hash() const
+uint64_t ModifierDataBackupID::hash() const
{
uintptr_t ptr = (uintptr_t)modifier_data;
return (ptr >> 4) ^ (uintptr_t)type;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
index dc16bdcc1b8..a5bdf2359ee 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_modifier.h
@@ -49,7 +49,7 @@ class ModifierDataBackupID {
friend bool operator==(const ModifierDataBackupID &a, const ModifierDataBackupID &b);
- uint32_t hash() const;
+ uint64_t hash() const;
ModifierData *modifier_data;
ModifierType type;
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index 34514ba9bd7..cd82b7be050 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -72,7 +72,7 @@ bool ComponentNode::OperationIDKey::operator==(const OperationIDKey &other) cons
return (opcode == other.opcode) && (STREQ(name, other.name)) && (name_tag == other.name_tag);
}
-uint32_t ComponentNode::OperationIDKey::hash() const
+uint64_t ComponentNode::OperationIDKey::hash() const
{
const int opcode_as_int = static_cast<int>(opcode);
return BLI_ghashutil_combine_hash(
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.h b/source/blender/depsgraph/intern/node/deg_node_component.h
index 3757a1dea5b..06582c88d8b 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.h
+++ b/source/blender/depsgraph/intern/node/deg_node_component.h
@@ -54,7 +54,7 @@ struct ComponentNode : public Node {
string identifier() const;
bool operator==(const OperationIDKey &other) const;
- uint32_t hash() const;
+ uint64_t hash() const;
};
/* Typedef for container of operations */
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc
index d0c23f326ce..8d19949adc8 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_id.cc
@@ -67,7 +67,7 @@ bool IDNode::ComponentIDKey::operator==(const ComponentIDKey &other) const
return type == other.type && STREQ(name, other.name);
}
-uint32_t IDNode::ComponentIDKey::hash() const
+uint64_t IDNode::ComponentIDKey::hash() const
{
const int type_as_int = static_cast<int>(type);
return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(type_as_int),
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h
index 9bd6130bbdc..04a9006ac10 100644
--- a/source/blender/depsgraph/intern/node/deg_node_id.h
+++ b/source/blender/depsgraph/intern/node/deg_node_id.h
@@ -51,7 +51,7 @@ const char *linkedStateAsString(eDepsNode_LinkedState_Type linked_state);
struct IDNode : public Node {
struct ComponentIDKey {
ComponentIDKey(NodeType type, const char *name = "");
- uint32_t hash() const;
+ uint64_t hash() const;
bool operator==(const ComponentIDKey &other) const;
NodeType type;
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 6c835c6d7ae..bc4efd82a03 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -43,6 +43,7 @@ struct GPUViewport;
struct ID;
struct Main;
struct Object;
+struct Render;
struct RenderEngine;
struct RenderEngineType;
struct Scene;
@@ -137,6 +138,9 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
struct DRWInstanceDataList *DRW_instance_data_list_create(void);
void DRW_instance_data_list_free(struct DRWInstanceDataList *idatalist);
+void DRW_render_context_enable(struct Render *render);
+void DRW_render_context_disable(struct Render *render);
+
void DRW_opengl_context_create(void);
void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index bac96ab1079..f42c60b04bf 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -601,7 +601,7 @@ RenderEngineType DRW_engine_viewport_eevee_type = {
NULL,
EEVEE_ENGINE,
N_("Eevee"),
- RE_INTERNAL | RE_USE_PREVIEW | RE_USE_STEREO_VIEWPORT,
+ RE_INTERNAL | RE_USE_PREVIEW | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
NULL,
&DRW_render_to_image,
NULL,
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
index bb7c947a0b9..8cee6c4ee9f 100644
--- a/source/blender/draw/engines/select/select_engine.c
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -378,7 +378,7 @@ RenderEngineType DRW_engine_viewport_select_type = {
NULL,
SELECT_ENGINE,
N_("Select ID"),
- RE_INTERNAL | RE_USE_STEREO_VIEWPORT,
+ RE_INTERNAL | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
NULL,
NULL,
NULL,
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 5fff55e2f26..53119723fab 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -641,7 +641,7 @@ RenderEngineType DRW_engine_viewport_workbench_type = {
NULL,
WORKBENCH_ENGINE,
N_("Workbench"),
- RE_INTERNAL | RE_USE_STEREO_VIEWPORT,
+ RE_INTERNAL | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT,
NULL,
&DRW_render_to_image,
NULL,
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 08fb80c11d2..712a93e8880 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1660,24 +1660,8 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
RenderEngineType *engine_type = engine->type;
RenderData *r = &scene->r;
Render *render = engine->re;
- /* Changing Context */
- if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
- }
- void *re_gl_context = RE_gl_context_get(render);
- void *re_gpu_context = NULL;
-
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_opengl_render_context_enable(re_gl_context);
- /* We need to query gpu context after a gl context has been bound. */
- re_gpu_context = RE_gpu_context_get(render);
- DRW_gpu_render_context_enable(re_gpu_context);
- }
- else {
- DRW_opengl_context_enable();
- }
+ DRW_render_context_enable(render);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@@ -1729,14 +1713,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph
/* Restore Drawing area. */
GPU_framebuffer_restore();
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_gpu_render_context_disable(re_gpu_context);
- DRW_opengl_render_context_disable(re_gl_context);
- }
- else {
- DRW_opengl_context_disable();
- }
+ DRW_render_context_disable(render);
DST.buffer_finish_called = false;
}
@@ -1749,24 +1726,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
DrawEngineType *draw_engine_type = engine_type->draw_engine;
Render *render = engine->re;
- if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
- }
-
- void *re_gl_context = RE_gl_context_get(render);
- void *re_gpu_context = NULL;
-
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_opengl_render_context_enable(re_gl_context);
- /* We need to query gpu context after a gl context has been bound. */
- re_gpu_context = RE_gpu_context_get(render);
- DRW_gpu_render_context_enable(re_gpu_context);
- }
- else {
- DRW_opengl_context_enable();
- }
-
/* IMPORTANT: We don't support immediate mode in render mode!
* This shall remain in effect until immediate mode supports
* multiple threads. */
@@ -1842,15 +1801,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
/* Reset state after drawing */
DRW_state_reset();
-
- /* Changing Context */
- if (re_gl_context != NULL) {
- DRW_gpu_render_context_disable(re_gpu_context);
- DRW_opengl_render_context_disable(re_gl_context);
- }
- else {
- DRW_opengl_context_disable();
- }
}
void DRW_render_object_iter(
@@ -2763,6 +2713,42 @@ void DRW_engines_free(void)
DRW_opengl_context_disable();
}
+void DRW_render_context_enable(Render *render)
+{
+ if (G.background && DST.gl_context == NULL) {
+ WM_init_opengl(G_MAIN);
+ }
+
+ void *re_gl_context = RE_gl_context_get(render);
+
+ /* Changing Context */
+ if (re_gl_context != NULL) {
+ DRW_opengl_render_context_enable(re_gl_context);
+ /* We need to query gpu context after a gl context has been bound. */
+ void *re_gpu_context = NULL;
+ re_gpu_context = RE_gpu_context_get(render);
+ DRW_gpu_render_context_enable(re_gpu_context);
+ }
+ else {
+ DRW_opengl_context_enable();
+ }
+}
+
+void DRW_render_context_disable(Render *render)
+{
+ void *re_gl_context = RE_gl_context_get(render);
+
+ if (re_gl_context != NULL) {
+ void *re_gpu_context = NULL;
+ re_gpu_context = RE_gpu_context_get(render);
+ DRW_gpu_render_context_disable(re_gpu_context);
+ DRW_opengl_render_context_disable(re_gl_context);
+ }
+ else {
+ DRW_opengl_context_disable();
+ }
+}
+
/** \} */
/** \name Init/Exit (DRW_opengl_ctx)
@@ -2903,8 +2889,8 @@ void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
* switch to it just to submit the final frame, which has notable performance impact.
*
* We could "inject" a context through DRW_opengl_render_context_enable(), but that would have to
- * work from the main thread, which is tricky to get working too. The preferable solution would be
- * using a separate thread for VR drawing where a single context can stay active. */
+ * work from the main thread, which is tricky to get working too. The preferable solution would
+ * be using a separate thread for VR drawing where a single context can stay active. */
void *DRW_xr_opengl_context_get(void)
{
return DST.gl_context;
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 79c465c1f33..53401e0c05a 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -4708,6 +4708,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
ToolSettings *ts = scene->toolsettings;
ListBase nla_cache = {NULL, NULL};
PointerRNA id_ptr, ptr;
@@ -4720,8 +4721,10 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
RNA_id_pointer_create(id, &id_ptr);
/* Get NLA context for value remapping */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, adt, (float)CFRA, false);
+ &nla_cache, &id_ptr, adt, &anim_eval_context, false);
/* get current frame and apply NLA-mapping to it (if applicable) */
cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
@@ -4738,7 +4741,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
/* insert a keyframe for this F-Curve */
done = insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
+ reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, nla_context, flag);
if (done) {
if (adt->action != NULL) {
@@ -4762,23 +4765,26 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
ReportList *reports = CTX_wm_reports(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
ToolSettings *ts = scene->toolsettings;
ListBase nla_cache = {NULL, NULL};
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
eInsertKeyFlags flag = 0;
bool done = false;
- float cfra;
/* Get RNA pointer */
RNA_id_pointer_create((ID *)key, &id_ptr);
/* Get NLA context for value remapping */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
- &nla_cache, &id_ptr, key->adt, (float)CFRA, false);
+ &nla_cache, &id_ptr, key->adt, &anim_eval_context, false);
/* get current frame and apply NLA-mapping to it (if applicable) */
- cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ const float remapped_frame = BKE_nla_tweakedit_remap(
+ key->adt, anim_eval_context.eval_time, NLATIME_CONVERT_UNMAP);
/* get flags for keyframing */
flag = ANIM_get_keyframing_flags(scene, true);
@@ -4791,13 +4797,21 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, &ptr, rna_path, 0);
/* set the special 'replace' flag if on a keyframe */
- if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
+ if (fcurve_frame_has_keyframe(fcu, remapped_frame, 0)) {
flag |= INSERTKEY_REPLACE;
}
/* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
+ const AnimationEvalContext remapped_anim_eval_context = BKE_animsys_eval_context_construct_at(
+ &anim_eval_context, remapped_frame);
+ done = insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &remapped_anim_eval_context,
+ ts->keyframe_type,
+ nla_context,
+ flag);
if (done) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
@@ -4848,7 +4862,11 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C,
}
/* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, flag);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ done = insert_keyframe_direct(
+ reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, flag);
if (done) {
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index bbb673caa71..50733afe6fb 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -419,6 +419,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->markers = ED_context_get_markers(C);
}
ac->view_layer = CTX_data_view_layer(C);
+ ac->depsgraph = CTX_data_depsgraph_pointer(C);
ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL;
ac->area = area;
ac->region = region;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 9cb41e06aa0..8c2f4216aa9 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1113,7 +1113,7 @@ static bool insert_keyframe_value(ReportList *reports,
PointerRNA *ptr,
PropertyRNA *prop,
FCurve *fcu,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
float curval,
eBezTriple_KeyframeType keytype,
eInsertKeyFlags flag)
@@ -1130,13 +1130,15 @@ static bool insert_keyframe_value(ReportList *reports,
return false;
}
+ float cfra = anim_eval_context->eval_time;
+
/* adjust frame on which to add keyframe */
if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
PathResolvedRNA anim_rna;
if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
/* for making it easier to add corrective drivers... */
- cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, cfra);
+ cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, anim_eval_context);
}
else {
cfra = 0.0f;
@@ -1202,7 +1204,7 @@ bool insert_keyframe_direct(ReportList *reports,
PointerRNA ptr,
PropertyRNA *prop,
FCurve *fcu,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
struct NlaKeyframingContext *nla_context,
eInsertKeyFlags flag)
@@ -1274,7 +1276,7 @@ bool insert_keyframe_direct(ReportList *reports,
MEM_freeN(values);
}
- return insert_keyframe_value(reports, &ptr, prop, fcu, cfra, curval, keytype, flag);
+ return insert_keyframe_value(reports, &ptr, prop, fcu, anim_eval_context, curval, keytype, flag);
}
/* Find or create the FCurve based on the given path, and insert the specified value into it. */
@@ -1286,7 +1288,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
const char group[],
const char rna_path[],
int array_index,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
float curval,
eBezTriple_KeyframeType keytype,
eInsertKeyFlags flag)
@@ -1320,12 +1322,35 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
update_autoflags_fcurve_direct(fcu, prop);
/* insert keyframe */
- return insert_keyframe_value(reports, ptr, prop, fcu, cfra, curval, keytype, flag);
+ return insert_keyframe_value(
+ reports, ptr, prop, fcu, anim_eval_context, curval, keytype, flag);
}
return false;
}
+static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval_context,
+ PointerRNA *id_ptr,
+ AnimData *adt,
+ bAction *act,
+ ListBase *nla_cache,
+ NlaKeyframingContext **r_nla_context)
+{
+ if (adt && adt->action == act) {
+ /* Get NLA context for value remapping. */
+ *r_nla_context = BKE_animsys_get_nla_keyframing_context(
+ nla_cache, id_ptr, adt, anim_eval_context, false);
+
+ /* Apply NLA-mapping to frame. */
+ const float remapped_frame = BKE_nla_tweakedit_remap(
+ adt, anim_eval_context->eval_time, NLATIME_CONVERT_UNMAP);
+ return BKE_animsys_eval_context_construct_at(anim_eval_context, remapped_frame);
+ }
+
+ *r_nla_context = NULL;
+ return *anim_eval_context;
+}
+
/**
* Main Keyframing API call
*
@@ -1346,7 +1371,7 @@ int insert_keyframe(Main *bmain,
const char group[],
const char rna_path[],
int array_index,
- float cfra,
+ const AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
ListBase *nla_cache,
eInsertKeyFlags flag)
@@ -1393,15 +1418,8 @@ int insert_keyframe(Main *bmain,
/* apply NLA-mapping to frame to use (if applicable) */
adt = BKE_animdata_from_id(id);
-
- if (adt && adt->action == act) {
- /* Get NLA context for value remapping. */
- nla_context = BKE_animsys_get_nla_keyframing_context(
- nla_cache ? nla_cache : &tmp_nla_cache, &id_ptr, adt, cfra, false);
-
- /* Apply NLA-mapping to frame. */
- cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
- }
+ const AnimationEvalContext remapped_context = nla_time_remap(
+ anim_eval_context, &id_ptr, adt, act, nla_cache ? nla_cache : &tmp_nla_cache, &nla_context);
/* Obtain values to insert. */
float value_buffer[RNA_MAX_ARRAY_LENGTH];
@@ -1435,7 +1453,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag)) {
@@ -1458,7 +1476,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag);
@@ -1477,7 +1495,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag);
@@ -1495,7 +1513,7 @@ int insert_keyframe(Main *bmain,
group,
rna_path,
array_index,
- cfra,
+ &remapped_context,
values[array_index],
keytype,
flag);
@@ -2375,7 +2393,8 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
PropertyRNA *prop = NULL;
char *path;
uiBut *but;
- float cfra = (float)CFRA;
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ CTX_data_depsgraph_pointer(C), (float)CFRA);
bool changed = false;
int index;
const bool all = RNA_boolean_get(op->ptr, "all");
@@ -2401,7 +2420,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
if (fcu) {
changed = insert_keyframe_direct(
- op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0);
+ op->reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, 0);
}
else {
BKE_report(op->reports,
@@ -2417,8 +2436,14 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
fcu = BKE_fcurve_find_by_rna_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special);
if (fcu && driven) {
- changed = insert_keyframe_direct(
- op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
+ changed = insert_keyframe_direct(op->reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ ts->keyframe_type,
+ NULL,
+ INSERTKEY_DRIVER);
}
}
else {
@@ -2461,7 +2486,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
group,
path,
index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
NULL,
flag) != 0);
@@ -2769,7 +2794,10 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
}
/* Returns whether the current value of a given property differs from the interpolated value. */
-bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float frame)
+bool fcurve_is_changed(PointerRNA ptr,
+ PropertyRNA *prop,
+ FCurve *fcu,
+ const AnimationEvalContext *anim_eval_context)
{
PathResolvedRNA anim_rna;
anim_rna.ptr = ptr;
@@ -2780,7 +2808,7 @@ bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float fra
int count, index = fcu->array_index;
float *values = setting_get_rna_values(&ptr, prop, buffer, RNA_MAX_ARRAY_LENGTH, &count);
- float fcurve_val = calculate_fcurve(&anim_rna, fcu, frame);
+ float fcurve_val = calculate_fcurve(&anim_rna, fcu, anim_eval_context);
float cur_val = (index >= 0 && index < count) ? values[index] : 0.0f;
if (values != buffer) {
@@ -2987,6 +3015,9 @@ bool ED_autokeyframe_property(
bContext *C, Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, float cfra)
{
Main *bmain = CTX_data_main(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
ID *id;
bAction *action;
FCurve *fcu;
@@ -3007,7 +3038,8 @@ bool ED_autokeyframe_property(
ReportList *reports = CTX_wm_reports(C);
ToolSettings *ts = scene->toolsettings;
- changed = insert_keyframe_direct(reports, *ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0);
+ changed = insert_keyframe_direct(
+ reports, *ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, 0);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
}
@@ -3020,7 +3052,7 @@ bool ED_autokeyframe_property(
ToolSettings *ts = scene->toolsettings;
changed = insert_keyframe_direct(
- reports, *ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
+ reports, *ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
}
}
@@ -3044,7 +3076,7 @@ bool ED_autokeyframe_property(
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
rnaindex,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
NULL,
flag) != 0;
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 5e4b39d9d81..876740b889a 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -1120,6 +1120,9 @@ int ANIM_apply_keyingset(
/* for each possible index, perform operation
* - assume that arraylen is greater than index
*/
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
for (; i < arraylen; i++) {
/* action to take depends on mode */
if (mode == MODIFYKEY_MODE_INSERT) {
@@ -1130,7 +1133,7 @@ int ANIM_apply_keyingset(
groupname,
ksp->rna_path,
i,
- cfra,
+ &anim_eval_context,
keytype,
&nla_cache,
kflag2);
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 6ce9ed06f1a..c9d0478270a 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -1023,7 +1023,8 @@ static void poselib_backup_free_data(tPoseLib_PreviewData *pld)
* - gets the string to print in the header
* - this code is based on the code for extract_pose_from_action in blenkernel/action.c
*/
-static void poselib_apply_pose(tPoseLib_PreviewData *pld)
+static void poselib_apply_pose(tPoseLib_PreviewData *pld,
+ const AnimationEvalContext *anim_eval_context)
{
PointerRNA *ptr = &pld->rna_ptr;
bArmature *arm = pld->arm;
@@ -1049,6 +1050,8 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
ked.f1 = ((float)frame) - 0.5f;
ked.f2 = ((float)frame) + 0.5f;
+ AnimationEvalContext anim_context_at_frame = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, frame);
/* start applying - only those channels which have a key at this point in time! */
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
@@ -1075,7 +1078,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld)
}
if (ok) {
- animsys_evaluate_action_group(ptr, act, agrp, (float)frame);
+ animsys_evaluate_action_group(ptr, act, agrp, &anim_context_at_frame);
}
}
}
@@ -1150,7 +1153,11 @@ static void poselib_preview_apply(bContext *C, wmOperator *op)
/* pose should be the right one to draw (unless we're temporarily not showing it) */
if ((pld->flag & PL_PREVIEW_SHOWORIGINAL) == 0) {
RNA_int_set(op->ptr, "pose_index", BLI_findindex(&pld->act->markers, pld->marker));
- poselib_apply_pose(pld);
+ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, 0.0f /* poselib_apply_pose() determines its own evaluation time. */);
+ poselib_apply_pose(pld, &anim_eval_context);
}
else {
RNA_int_set(op->ptr, "pose_index", -2); /* -2 means don't apply any pose */
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 1d2bf152777..615d59c3154 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -1219,7 +1219,9 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- float cframe = (float)CFRA;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
@@ -1240,7 +1242,8 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
workob.adt = ob->adt;
workob.pose = dummyPose;
- BKE_animsys_evaluate_animdata(&workob.id, workob.adt, cframe, ADT_RECALC_ANIM, false);
+ BKE_animsys_evaluate_animdata(
+ &workob.id, workob.adt, &anim_eval_context, ADT_RECALC_ANIM, false);
/* copy back values, but on selected bones only */
for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index f7d7627b850..21f15575a2f 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -48,6 +48,7 @@
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
+#include "BKE_animsys.h"
#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_curve.h"
@@ -399,6 +400,7 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
PointerRNA ptr,
PropertyRNA *prop,
+ Depsgraph *depsgraph,
FCurve *fcu,
Curve *cu,
tGpTimingData *gtd,
@@ -453,8 +455,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
if ((cfra - last_valid_time) < MIN_TIME_DELTA) {
cfra = last_valid_time + MIN_TIME_DELTA;
}
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
last_valid_time = cfra;
}
else if (G.debug & G_DEBUG) {
@@ -466,8 +476,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
if ((cfra - last_valid_time) < MIN_TIME_DELTA) {
cfra = last_valid_time + MIN_TIME_DELTA;
}
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
last_valid_time = cfra;
}
else {
@@ -475,8 +493,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
* and also far enough from (not yet added!) end_stroke keyframe!
*/
if ((cfra - last_valid_time) > MIN_TIME_DELTA && (end_stroke_time - cfra) > MIN_TIME_DELTA) {
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_BREAKDOWN, NULL, INSERTKEY_FAST);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context,
+ BEZT_KEYTYPE_BREAKDOWN,
+ NULL,
+ INSERTKEY_FAST);
last_valid_time = cfra;
}
else if (G.debug & G_DEBUG) {
@@ -496,6 +522,7 @@ static void gpencil_stroke_path_animation(bContext *C,
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
bAction *act;
FCurve *fcu;
PointerRNA ptr;
@@ -537,8 +564,16 @@ static void gpencil_stroke_path_animation(bContext *C,
cu->ctime = 0.0f;
cfra = (float)gtd->start_frame;
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ AnimationEvalContext anim_eval_context_start = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context_start,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
cu->ctime = cu->pathlen;
if (gtd->realtime) {
@@ -547,8 +582,16 @@ static void gpencil_stroke_path_animation(bContext *C,
else {
cfra = (float)gtd->end_frame;
}
- insert_keyframe_direct(
- reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST);
+ AnimationEvalContext anim_eval_context_end = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+ insert_keyframe_direct(reports,
+ ptr,
+ prop,
+ fcu,
+ &anim_eval_context_end,
+ BEZT_KEYTYPE_KEYFRAME,
+ NULL,
+ INSERTKEY_FAST);
}
else {
/* Use actual recorded timing! */
@@ -575,7 +618,7 @@ static void gpencil_stroke_path_animation(bContext *C,
}
gpencil_stroke_path_animation_add_keyframes(
- reports, ptr, prop, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time);
+ reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time);
BLI_rng_free(rng);
}
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index bffa11a32f2..9d9f2925c23 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -95,6 +95,8 @@ typedef struct bAnimContext {
struct Scene *scene;
/** active scene layer */
struct ViewLayer *view_layer;
+ /** active dependency graph */
+ struct Depsgraph *depsgraph;
/** active object */
struct Object *obact;
/** active set of markers */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 5635ef2800a..3fe6407aae7 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -38,6 +38,7 @@ struct Scene;
struct KeyingSet;
+struct AnimationEvalContext;
struct BezTriple;
struct FCurve;
struct bAction;
@@ -118,7 +119,7 @@ bool insert_keyframe_direct(struct ReportList *reports,
struct PointerRNA ptr,
struct PropertyRNA *prop,
struct FCurve *fcu,
- float cfra,
+ const struct AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
struct NlaKeyframingContext *nla,
eInsertKeyFlags flag);
@@ -136,7 +137,7 @@ int insert_keyframe(struct Main *bmain,
const char group[],
const char rna_path[],
int array_index,
- float cfra,
+ const struct AnimationEvalContext *anim_eval_context,
eBezTriple_KeyframeType keytype,
struct ListBase *nla_cache,
eInsertKeyFlags flag);
@@ -458,7 +459,7 @@ bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter);
bool fcurve_is_changed(struct PointerRNA ptr,
struct PropertyRNA *prop,
struct FCurve *fcu,
- float frame);
+ const struct AnimationEvalContext *anim_eval_context);
/**
* Main Keyframe Checking API call:
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 28b86674fdd..106145005bd 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -44,6 +44,7 @@
#include "BLI_utildefines.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_main.h"
@@ -1733,6 +1734,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
uiBut *but;
BLI_assert(block->active);
@@ -1761,7 +1763,9 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
}
}
- ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, (scene) ? scene->r.cfra : 0.0f);
+ ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
ui_but_anim_decorate_update_from_flag(but);
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 5bf2147aff5..8d12a1dd1ad 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -33,6 +33,7 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_fcurve_driver.h"
@@ -65,7 +66,7 @@ static FCurve *ui_but_get_fcurve(
but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special);
}
-void ui_but_anim_flag(uiBut *but, float cfra)
+void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
{
AnimData *adt;
bAction *act;
@@ -95,6 +96,7 @@ void ui_but_anim_flag(uiBut *but, float cfra)
* we need to correct the frame number to "look inside" the
* remapped action
*/
+ float cfra = anim_eval_context->eval_time;
if (adt) {
cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
@@ -105,7 +107,9 @@ void ui_but_anim_flag(uiBut *but, float cfra)
/* XXX: this feature is totally broken and useless with NLA */
if (adt == NULL || adt->nla_tracks.first == NULL) {
- if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, cfra)) {
+ const AnimationEvalContext remapped_context = BKE_animsys_eval_context_construct_at(
+ anim_eval_context, cfra);
+ if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, &remapped_context)) {
but->drawflag |= UI_BUT_ANIMATED_CHANGED;
}
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 43c91f1d2eb..988d19e30d3 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -47,6 +47,7 @@
#include "PIL_time.h"
+#include "BKE_animsys.h"
#include "BKE_blender_undo.h"
#include "BKE_brush.h"
#include "BKE_colorband.h"
@@ -8408,6 +8409,9 @@ void UI_context_update_anim_flag(const bContext *C)
{
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
+ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ depsgraph, (scene) ? scene->r.cfra : 0.0f);
uiBlock *block;
uiBut *but, *activebut;
@@ -8417,7 +8421,7 @@ void UI_context_update_anim_flag(const bContext *C)
for (block = region->uiblocks.first; block; block = block->next) {
for (but = block->buttons.first; but; but = but->next) {
- ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
+ ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
ui_but_anim_decorate_update_from_flag(but);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index a7cbfc23399..249134c6abf 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -32,6 +32,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
+struct AnimationEvalContext;
struct ARegion;
struct ID;
struct ImBuf;
@@ -938,7 +939,7 @@ int ui_but_align_opposite_to_area_align_get(const struct ARegion *region) ATTR_W
void ui_block_align_calc(uiBlock *block, const struct ARegion *region);
/* interface_anim.c */
-void ui_but_anim_flag(uiBut *but, float cfra);
+void ui_but_anim_flag(uiBut *but, const struct AnimationEvalContext *anim_eval_context);
void ui_but_anim_copy_driver(struct bContext *C);
void ui_but_anim_paste_driver(struct bContext *C);
bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index f027a62cbfd..b707aaa0ee9 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -5540,6 +5540,26 @@ void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
}
}
+static bool ui_layout_has_panel_label(const uiLayout *layout, const PanelType *pt)
+{
+ LISTBASE_FOREACH (uiItem *, subitem, &layout->items) {
+ if (subitem->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)subitem;
+ if (!(bitem->but->flag & UI_HIDDEN) && STREQ(bitem->but->str, pt->label)) {
+ return true;
+ }
+ }
+ else {
+ uiLayout *litem = (uiLayout *)subitem;
+ if (ui_layout_has_panel_label(litem, pt)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, bool show_header)
{
Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
@@ -5556,7 +5576,13 @@ static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout,
pt->draw_header(C, panel);
panel->layout = NULL;
}
- uiItemL(row, CTX_IFACE_(pt->translation_context, pt->label), ICON_NONE);
+
+ /* draw_header() is often used to add a checkbox to the header. If we add the label like below
+ * the label is disconnected from the checkbox, adding a weird looking gap. As workaround, let
+ * the checkbox add the label instead. */
+ if (!ui_layout_has_panel_label(row, pt)) {
+ uiItemL(row, CTX_IFACE_(pt->translation_context, pt->label), ICON_NONE);
+ }
}
panel->layout = layout;
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 873bdf2a674..347f6806d13 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1564,15 +1564,12 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
void **val_p;
float s[2], se1[2], se2[2], sint[2];
float r1[3], r2[3];
- float d, d1, d2, lambda;
+ float d1, d2, lambda;
float vert_tol, vert_tol_sq;
float line_tol, line_tol_sq;
float face_tol, face_tol_sq;
- int isect_kind;
uint tot;
int i;
- const bool use_hit_prev = true;
- const bool use_hit_curr = (kcd->is_drag_hold == false);
if (kcd->linehits) {
MEM_freeN(kcd->linehits);
@@ -1703,10 +1700,25 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
val_p = BLI_smallhash_iternext_p(&hiter, (uintptr_t *)&v)) {
KnifeEdge *kfe_hit = NULL;
- knife_project_v2(kcd, v->cageco, s);
- d = dist_squared_to_line_segment_v2(s, s1, s2);
- if ((d <= vert_tol_sq) &&
- (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit)))) {
+ bool kfv_is_in_cut = false;
+ if (ELEM(v, kcd->prev.vert, kcd->curr.vert)) {
+ /* This KnifeVert was captured by the snap system.
+ * Since the tolerance distance can be different, add this vertex directly.
+ * Otherwise, the cut may fail or a close cut on a connected edge can be performed. */
+ bm_elem_from_knife_vert(v, &kfe_hit);
+ copy_v2_v2(s, (v == kcd->prev.vert) ? kcd->prev.mval : kcd->curr.mval);
+ kfv_is_in_cut = true;
+ }
+ else {
+ knife_project_v2(kcd, v->cageco, s);
+ float d = dist_squared_to_line_segment_v2(s, s1, s2);
+ if ((d <= vert_tol_sq) &&
+ (point_is_visible(kcd, v->cageco, s, bm_elem_from_knife_vert(v, &kfe_hit)))) {
+ kfv_is_in_cut = true;
+ }
+ }
+
+ if (kfv_is_in_cut) {
memset(&hit, 0, sizeof(hit));
hit.v = v;
@@ -1724,7 +1736,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
BLI_array_append(linehits, hit);
}
else {
- /* note that these vertes aren't used */
+ /* This vertex isn't used so remove from `kfvs`.
+ * This is useful to detect KnifeEdges that can be skipped.
+ * And it optimizes smallhash_iternext a little bit. */
*val_p = NULL;
}
}
@@ -1732,30 +1746,38 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
/* now edge hits; don't add if a vertex at end of edge should have hit */
for (val = BLI_smallhash_iternew(&kfes, &hiter, (uintptr_t *)&kfe); val;
val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&kfe)) {
- int kfe_verts_in_cut;
- /* if we intersect both verts, don't attempt to intersect the edge */
-
- kfe_verts_in_cut = (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v1) != NULL) +
- (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v2) != NULL);
- if (kfe_verts_in_cut == 2) {
+ /* If we intersect any of the vertices, don't attempt to intersect the edge. */
+ if (BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v1) ||
+ BLI_smallhash_lookup(&kfvs, (intptr_t)kfe->v2)) {
continue;
}
knife_project_v2(kcd, kfe->v1->cageco, se1);
knife_project_v2(kcd, kfe->v2->cageco, se2);
- isect_kind = (kfe_verts_in_cut) ? -1 : isect_seg_seg_v2_point(s1, s2, se1, se2, sint);
- if (isect_kind == -1) {
- /* isect_seg_seg_v2_simple doesn't do tolerance test around ends of s1-s2 */
- closest_to_line_segment_v2(sint, s1, se1, se2);
- if (len_squared_v2v2(sint, s1) <= line_tol_sq) {
- isect_kind = 1;
- }
- else {
- closest_to_line_segment_v2(sint, s2, se1, se2);
- if (len_squared_v2v2(sint, s2) <= line_tol_sq) {
+ int isect_kind = 1;
+ if (kfe == kcd->prev.edge) {
+ /* This KnifeEdge was captured by the snap system. */
+ copy_v2_v2(sint, kcd->prev.mval);
+ }
+ else if (kfe == kcd->curr.edge) {
+ /* This KnifeEdge was captured by the snap system. */
+ copy_v2_v2(sint, kcd->curr.mval);
+ }
+ else {
+ isect_kind = isect_seg_seg_v2_point_ex(s1, s2, se1, se2, 0.0f, sint);
+ if (isect_kind == -1) {
+ /* isect_seg_seg_v2_point doesn't do tolerance test around ends of s1-s2 */
+ closest_to_line_segment_v2(sint, s1, se1, se2);
+ if (len_squared_v2v2(sint, s1) <= line_tol_sq) {
isect_kind = 1;
}
+ else {
+ closest_to_line_segment_v2(sint, s2, se1, se2);
+ if (len_squared_v2v2(sint, s2) <= line_tol_sq) {
+ isect_kind = 1;
+ }
+ }
}
}
if (isect_kind == 1) {
@@ -1790,32 +1812,38 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
}
}
}
+
/* now face hits; don't add if a vertex or edge in face should have hit */
- for (val = BLI_smallhash_iternew(&faces, &hiter, (uintptr_t *)&f); val;
- val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) {
- float p[3], p_cage[3];
-
- if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
- memset(&hit, 0, sizeof(hit));
- hit.f = f;
- copy_v3_v3(hit.hit, p);
- copy_v3_v3(hit.cagehit, p_cage);
- copy_v2_v2(hit.schit, s1);
- set_linehit_depth(kcd, &hit);
- BLI_array_append(linehits, hit);
+ const bool use_hit_prev = (kcd->prev.vert == NULL) && (kcd->prev.edge == NULL);
+ const bool use_hit_curr = (kcd->curr.vert == NULL) && (kcd->curr.edge == NULL) &&
+ !kcd->is_drag_hold;
+ if (use_hit_prev || use_hit_curr) {
+ for (val = BLI_smallhash_iternew(&faces, &hiter, (uintptr_t *)&f); val;
+ val = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) {
+ float p[3], p_cage[3];
+
+ if (use_hit_prev && knife_ray_intersect_face(kcd, s1, v1, v3, f, face_tol_sq, p, p_cage)) {
+ if (point_is_visible(kcd, p_cage, s1, (BMElem *)f)) {
+ memset(&hit, 0, sizeof(hit));
+ hit.f = f;
+ copy_v3_v3(hit.hit, p);
+ copy_v3_v3(hit.cagehit, p_cage);
+ copy_v2_v2(hit.schit, s1);
+ set_linehit_depth(kcd, &hit);
+ BLI_array_append(linehits, hit);
+ }
}
- }
- if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
- if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
- memset(&hit, 0, sizeof(hit));
- hit.f = f;
- copy_v3_v3(hit.hit, p);
- copy_v3_v3(hit.cagehit, p_cage);
- copy_v2_v2(hit.schit, s2);
- set_linehit_depth(kcd, &hit);
- BLI_array_append(linehits, hit);
+ if (use_hit_curr && knife_ray_intersect_face(kcd, s2, v2, v4, f, face_tol_sq, p, p_cage)) {
+ if (point_is_visible(kcd, p_cage, s2, (BMElem *)f)) {
+ memset(&hit, 0, sizeof(hit));
+ hit.f = f;
+ copy_v3_v3(hit.hit, p);
+ copy_v3_v3(hit.cagehit, p_cage);
+ copy_v2_v2(hit.schit, s2);
+ set_linehit_depth(kcd, &hit);
+ BLI_array_append(linehits, hit);
+ }
}
}
}
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index ff49e0a9c5a..aa9d6234d1f 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1395,7 +1395,7 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op)
/* Avoid dependency cycles. */
LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
- while (BKE_collection_find_cycle(active_lc->collection, collection)) {
+ while (BKE_collection_cycle_find(active_lc->collection, collection)) {
active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
}
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 6f254ea9400..4470269ec23 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -2796,12 +2796,16 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
cfra = scene->r.cfra;
/* precalculate time variable before baking */
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
for (f = omd->bakestart; f <= omd->bakeend; f++) {
/* For now only simple animation of time value is supported, nothing else.
* No drivers or other modifier parameters. */
/* TODO(sergey): This operates on an original data, so no flush is needed. However, baking
* usually should happen on an evaluated objects, so this seems to be deeper issue here. */
- BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, f, ADT_RECALC_ANIM, false);
+
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ f);
+ BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, false);
och->time[i] = omd->time;
i++;
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 185066b49ce..af8e0e9d9de 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -724,9 +724,10 @@ static void insert_action_keys(bAnimContext *ac, short mode)
flag = ANIM_get_keyframing_flags(scene, true);
/* insert keyframes */
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph,
+ (float)CFRA);
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
- float cfra = (float)CFRA;
/* Read value from property the F-Curve represents, or from the curve only?
* - ale->id != NULL:
@@ -745,7 +746,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -754,8 +755,9 @@ static void insert_action_keys(bAnimContext *ac, short mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
/* adjust current frame for NLA-scaling */
+ float cfra = anim_eval_context.eval_time;
if (adt) {
- cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
}
const float curval = evaluate_fcurve(fcu, cfra);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 1925a3847d6..68fdef54a53 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -681,9 +681,10 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
}
}
else {
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ ac->depsgraph, (float)CFRA);
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
- float cfra = (float)CFRA;
/* Read value from property the F-Curve represents, or from the curve only?
*
@@ -705,7 +706,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -714,6 +715,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
/* adjust current frame for NLA-mapping */
+ float cfra = (float)CFRA;
if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) {
cfra = sipo->cursorTime;
}
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 4b012934ab7..0964e0c753e 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -717,7 +717,7 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- while (BKE_collection_find_cycle(active_lc->collection, collection)) {
+ while (BKE_collection_cycle_find(active_lc->collection, collection)) {
active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
}
}
diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c
index f721ed0b866..9885c8fc3a6 100644
--- a/source/blender/editors/transform/transform_convert_armature.c
+++ b/source/blender/editors/transform/transform_convert_armature.c
@@ -115,7 +115,9 @@ static void autokeyframe_pose(
ToolSettings *ts = scene->toolsettings;
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
ListBase nla_cache = {NULL, NULL};
- float cfra = (float)CFRA;
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
eInsertKeyFlags flag = 0;
/* flag is initialized from UserPref keyframing settings
@@ -146,7 +148,8 @@ static void autokeyframe_pose(
/* only insert into active keyingset? */
if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) {
/* run the active Keying Set on the current datasource */
- ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* only insert into available channels? */
else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
@@ -169,7 +172,7 @@ static void autokeyframe_pose(
((fcu->grp) ? (fcu->grp->name) : (NULL)),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -220,21 +223,25 @@ static void autokeyframe_pose(
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* free temp info */
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index 92ed477eb25..2e92b4e5c09 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -794,7 +794,9 @@ static void autokeyframe_object(
ToolSettings *ts = scene->toolsettings;
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
ListBase dsources = {NULL, NULL};
- float cfra = (float)CFRA; // xxx this will do for now
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ (float)CFRA);
eInsertKeyFlags flag = 0;
/* Get flags used for inserting keyframes. */
@@ -808,7 +810,8 @@ static void autokeyframe_object(
* NOTE: we assume here that the active Keying Set
* does not need to have its iterator overridden.
*/
- ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
AnimData *adt = ob->adt;
@@ -824,7 +827,7 @@ static void autokeyframe_object(
(fcu->grp ? fcu->grp->name : NULL),
fcu->rna_path,
fcu->array_index,
- cfra,
+ &anim_eval_context,
ts->keyframe_type,
&nla_cache,
flag);
@@ -872,21 +875,25 @@ static void autokeyframe_object(
/* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
if (do_loc) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_rot) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
if (do_scale) {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(
+ C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
}
/* free temp info */
diff --git a/source/blender/functions/FN_array_spans.hh b/source/blender/functions/FN_array_spans.hh
index 3f71b36c49c..c362fef3630 100644
--- a/source/blender/functions/FN_array_spans.hh
+++ b/source/blender/functions/FN_array_spans.hh
@@ -39,17 +39,17 @@ enum class VArraySpanCategory {
template<typename T> class VArraySpanBase {
protected:
- uint virtual_size_;
+ int64_t virtual_size_;
VArraySpanCategory category_;
union {
struct {
const T *start;
- uint size;
+ int64_t size;
} single_array;
struct {
const T *const *starts;
- const uint *sizes;
+ const int64_t *sizes;
} starts_and_sizes;
} data_;
@@ -71,7 +71,7 @@ template<typename T> class VArraySpanBase {
return this->virtual_size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return this->virtual_size_;
}
@@ -99,15 +99,16 @@ template<typename T> class VArraySpan : public VArraySpanBase<T> {
this->data_.starts_and_sizes.sizes = nullptr;
}
- VArraySpan(Span<T> span, uint virtual_size)
+ VArraySpan(Span<T> span, int64_t virtual_size)
{
+ BLI_assert(virtual_size >= 0);
this->virtual_size_ = virtual_size;
this->category_ = VArraySpanCategory::SingleArray;
this->data_.single_array.start = span.data();
this->data_.single_array.size = span.size();
}
- VArraySpan(Span<const T *> starts, Span<uint> sizes)
+ VArraySpan(Span<const T *> starts, Span<int64_t> sizes)
{
BLI_assert(starts.size() == sizes.size());
this->virtual_size_ = starts.size();
@@ -116,8 +117,9 @@ template<typename T> class VArraySpan : public VArraySpanBase<T> {
this->data_.starts_and_sizes.sizes = sizes.begin();
}
- VSpan<T> operator[](uint index) const
+ VSpan<T> operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->virtual_size_);
switch (this->category_) {
case VArraySpanCategory::SingleArray:
@@ -151,7 +153,7 @@ class GVArraySpan : public VArraySpanBase<void> {
this->data_.starts_and_sizes.sizes = nullptr;
}
- GVArraySpan(GSpan array, uint virtual_size)
+ GVArraySpan(GSpan array, int64_t virtual_size)
{
this->type_ = &array.type();
this->virtual_size_ = virtual_size;
@@ -160,7 +162,7 @@ class GVArraySpan : public VArraySpanBase<void> {
this->data_.single_array.size = array.size();
}
- GVArraySpan(const CPPType &type, Span<const void *> starts, Span<uint> sizes)
+ GVArraySpan(const CPPType &type, Span<const void *> starts, Span<int64_t> sizes)
{
BLI_assert(starts.size() == sizes.size());
this->type_ = &type;
@@ -187,7 +189,7 @@ class GVArraySpan : public VArraySpanBase<void> {
return VArraySpan<T>(*this);
}
- GVSpan operator[](uint index) const
+ GVSpan operator[](int64_t index) const
{
BLI_assert(index < virtual_size_);
switch (category_) {
diff --git a/source/blender/functions/FN_attributes_ref.hh b/source/blender/functions/FN_attributes_ref.hh
index cf5ef2af8a6..ed14676731e 100644
--- a/source/blender/functions/FN_attributes_ref.hh
+++ b/source/blender/functions/FN_attributes_ref.hh
@@ -65,7 +65,7 @@ class AttributesInfoBuilder : NonCopyable, NonMovable {
class AttributesInfo : NonCopyable, NonMovable {
private:
LinearAllocator<> allocator_;
- Map<StringRefNull, uint> index_by_name_;
+ Map<StringRefNull, int> index_by_name_;
Vector<StringRefNull> name_by_index_;
Vector<const CPPType *> type_by_index_;
Vector<void *> defaults_;
@@ -75,7 +75,7 @@ class AttributesInfo : NonCopyable, NonMovable {
AttributesInfo(const AttributesInfoBuilder &builder);
~AttributesInfo();
- uint size() const
+ int size() const
{
return name_by_index_.size();
}
@@ -85,17 +85,17 @@ class AttributesInfo : NonCopyable, NonMovable {
return name_by_index_.index_range();
}
- StringRefNull name_of(uint index) const
+ StringRefNull name_of(int index) const
{
return name_by_index_[index];
}
- uint index_of(StringRef name) const
+ int index_of(StringRef name) const
{
return index_by_name_.lookup_as(name);
}
- const void *default_of(uint index) const
+ const void *default_of(int index) const
{
return defaults_[index];
}
@@ -105,7 +105,7 @@ class AttributesInfo : NonCopyable, NonMovable {
return this->default_of(this->index_of(name));
}
- template<typename T> const T &default_of(uint index) const
+ template<typename T> const T &default_of(int index) const
{
BLI_assert(type_by_index_[index]->is<T>());
return *(T *)defaults_[index];
@@ -116,7 +116,7 @@ class AttributesInfo : NonCopyable, NonMovable {
return this->default_of<T>(this->index_of(name));
}
- const CPPType &type_of(uint index) const
+ const CPPType &type_of(int index) const
{
return *type_by_index_[index];
}
@@ -133,7 +133,7 @@ class AttributesInfo : NonCopyable, NonMovable {
int try_index_of(StringRef name) const
{
- return (int)index_by_name_.lookup_default_as(name, -1);
+ return index_by_name_.lookup_default_as(name, -1);
}
int try_index_of(StringRef name, const CPPType &type) const
@@ -142,7 +142,7 @@ class AttributesInfo : NonCopyable, NonMovable {
if (index == -1) {
return -1;
}
- else if (this->type_of((uint)index) == type) {
+ else if (this->type_of(index) == type) {
return index;
}
else {
@@ -164,7 +164,7 @@ class MutableAttributesRef {
friend class AttributesRef;
public:
- MutableAttributesRef(const AttributesInfo &info, Span<void *> buffers, uint size)
+ MutableAttributesRef(const AttributesInfo &info, Span<void *> buffers, int64_t size)
: MutableAttributesRef(info, buffers, IndexRange(size))
{
}
@@ -174,17 +174,22 @@ class MutableAttributesRef {
{
}
- uint size() const
+ int64_t size() const
{
return range_.size();
}
+ IndexRange index_range() const
+ {
+ return IndexRange(this->size());
+ }
+
const AttributesInfo &info() const
{
return *info_;
}
- GMutableSpan get(uint index) const
+ GMutableSpan get(int index) const
{
const CPPType &type = info_->type_of(index);
void *ptr = POINTER_OFFSET(buffers_[index], type.size() * range_.start());
@@ -196,7 +201,7 @@ class MutableAttributesRef {
return this->get(info_->index_of(name));
}
- template<typename T> MutableSpan<T> get(uint index) const
+ template<typename T> MutableSpan<T> get(int index) const
{
BLI_assert(info_->type_of(index).is<T>());
return MutableSpan<T>((T *)buffers_[index] + range_.start(), range_.size());
@@ -214,7 +219,7 @@ class MutableAttributesRef {
return {};
}
else {
- return this->get((uint)index);
+ return this->get(index);
}
}
@@ -224,8 +229,8 @@ class MutableAttributesRef {
if (index == -1) {
return {};
}
- else if (info_->type_of((uint)index).is<T>()) {
- return this->get<T>((uint)index);
+ else if (info_->type_of(index).is<T>()) {
+ return this->get<T>(index);
}
else {
return {};
@@ -237,7 +242,7 @@ class MutableAttributesRef {
return this->slice(range.start(), range.size());
}
- MutableAttributesRef slice(uint start, uint size) const
+ MutableAttributesRef slice(int64_t start, int64_t size) const
{
return MutableAttributesRef(*info_, buffers_, range_.slice(start, size));
}
@@ -250,7 +255,7 @@ class AttributesRef {
IndexRange range_;
public:
- AttributesRef(const AttributesInfo &info, Span<const void *> buffers, uint size)
+ AttributesRef(const AttributesInfo &info, Span<const void *> buffers, int64_t size)
: AttributesRef(info, buffers, IndexRange(size))
{
}
@@ -265,7 +270,7 @@ class AttributesRef {
{
}
- uint size() const
+ int64_t size() const
{
return range_.size();
}
@@ -275,7 +280,7 @@ class AttributesRef {
return *info_;
}
- GSpan get(uint index) const
+ GSpan get(int index) const
{
const CPPType &type = info_->type_of(index);
const void *ptr = POINTER_OFFSET(buffers_[index], type.size() * range_.start());
@@ -287,7 +292,7 @@ class AttributesRef {
return this->get(info_->index_of(name));
}
- template<typename T> Span<T> get(uint index) const
+ template<typename T> Span<T> get(int index) const
{
BLI_assert(info_->type_of(index).is<T>());
return Span<T>((T *)buffers_[index] + range_.start(), range_.size());
@@ -300,12 +305,12 @@ class AttributesRef {
std::optional<GSpan> try_get(StringRef name, const CPPType &type) const
{
- int index = info_->try_index_of(name, type);
+ int64_t index = info_->try_index_of(name, type);
if (index == -1) {
return {};
}
else {
- return this->get((uint)index);
+ return this->get(index);
}
}
@@ -315,8 +320,8 @@ class AttributesRef {
if (index == -1) {
return {};
}
- else if (info_->type_of((uint)index).is<T>()) {
- return this->get<T>((uint)index);
+ else if (info_->type_of(index).is<T>()) {
+ return this->get<T>(index);
}
else {
return {};
@@ -328,7 +333,7 @@ class AttributesRef {
return this->slice(range.start(), range.size());
}
- AttributesRef slice(uint start, uint size) const
+ AttributesRef slice(int64_t start, int64_t size) const
{
return AttributesRef(*info_, buffers_, range_.slice(start, size));
}
diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh
index ce02bfd05be..594890e353a 100644
--- a/source/blender/functions/FN_cpp_type.hh
+++ b/source/blender/functions/FN_cpp_type.hh
@@ -38,7 +38,7 @@
* methods come in three variants. Using the construct-default methods as example:
* - construct_default(void *ptr):
* Constructs a single instance of that type at the given pointer.
- * - construct_default_n(void *ptr, uint n):
+ * - construct_default_n(void *ptr, int64_t n):
* Constructs n instances of that type in an array that starts at the given pointer.
* - construct_default_indices(void *ptr, IndexMask mask):
* Constructs multiple instances of that type in an array that starts at the given pointer.
@@ -77,42 +77,42 @@ namespace blender::fn {
class CPPType : NonCopyable, NonMovable {
public:
using ConstructDefaultF = void (*)(void *ptr);
- using ConstructDefaultNF = void (*)(void *ptr, uint n);
+ using ConstructDefaultNF = void (*)(void *ptr, int64_t n);
using ConstructDefaultIndicesF = void (*)(void *ptr, IndexMask mask);
using DestructF = void (*)(void *ptr);
- using DestructNF = void (*)(void *ptr, uint n);
+ using DestructNF = void (*)(void *ptr, int64_t n);
using DestructIndicesF = void (*)(void *ptr, IndexMask mask);
using CopyToInitializedF = void (*)(const void *src, void *dst);
- using CopyToInitializedNF = void (*)(const void *src, void *dst, uint n);
+ using CopyToInitializedNF = void (*)(const void *src, void *dst, int64_t n);
using CopyToInitializedIndicesF = void (*)(const void *src, void *dst, IndexMask mask);
using CopyToUninitializedF = void (*)(const void *src, void *dst);
- using CopyToUninitializedNF = void (*)(const void *src, void *dst, uint n);
+ using CopyToUninitializedNF = void (*)(const void *src, void *dst, int64_t n);
using CopyToUninitializedIndicesF = void (*)(const void *src, void *dst, IndexMask mask);
using RelocateToInitializedF = void (*)(void *src, void *dst);
- using RelocateToInitializedNF = void (*)(void *src, void *dst, uint n);
+ using RelocateToInitializedNF = void (*)(void *src, void *dst, int64_t n);
using RelocateToInitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
using RelocateToUninitializedF = void (*)(void *src, void *dst);
- using RelocateToUninitializedNF = void (*)(void *src, void *dst, uint n);
+ using RelocateToUninitializedNF = void (*)(void *src, void *dst, int64_t n);
using RelocateToUninitializedIndicesF = void (*)(void *src, void *dst, IndexMask mask);
- using FillInitializedF = void (*)(const void *value, void *dst, uint n);
+ using FillInitializedF = void (*)(const void *value, void *dst, int64_t n);
using FillInitializedIndicesF = void (*)(const void *value, void *dst, IndexMask mask);
- using FillUninitializedF = void (*)(const void *value, void *dst, uint n);
+ using FillUninitializedF = void (*)(const void *value, void *dst, int64_t n);
using FillUninitializedIndicesF = void (*)(const void *value, void *dst, IndexMask mask);
using DebugPrintF = void (*)(const void *value, std::stringstream &ss);
using IsEqualF = bool (*)(const void *a, const void *b);
- using HashF = uint32_t (*)(const void *value);
+ using HashF = uint64_t (*)(const void *value);
private:
- uint size_;
- uint alignment_;
+ int64_t size_;
+ int64_t alignment_;
uintptr_t alignment_mask_;
bool is_trivially_destructible_;
@@ -155,8 +155,8 @@ class CPPType : NonCopyable, NonMovable {
public:
CPPType(std::string name,
- uint size,
- uint alignment,
+ int64_t size,
+ int64_t alignment,
bool is_trivially_destructible,
ConstructDefaultF construct_default,
ConstructDefaultNF construct_default_n,
@@ -250,7 +250,7 @@ class CPPType : NonCopyable, NonMovable {
* C++ equivalent:
* sizeof(T);
*/
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -261,7 +261,7 @@ class CPPType : NonCopyable, NonMovable {
* C++ equivalent:
* alignof(T);
*/
- uint alignment() const
+ int64_t alignment() const
{
return alignment_;
}
@@ -306,7 +306,7 @@ class CPPType : NonCopyable, NonMovable {
construct_default_(ptr);
}
- void construct_default_n(void *ptr, uint n) const
+ void construct_default_n(void *ptr, int64_t n) const
{
BLI_assert(n == 0 || this->pointer_can_point_to_instance(ptr));
@@ -335,7 +335,7 @@ class CPPType : NonCopyable, NonMovable {
destruct_(ptr);
}
- void destruct_n(void *ptr, uint n) const
+ void destruct_n(void *ptr, int64_t n) const
{
BLI_assert(n == 0 || this->pointer_can_point_to_instance(ptr));
@@ -369,7 +369,7 @@ class CPPType : NonCopyable, NonMovable {
copy_to_initialized_(src, dst);
}
- void copy_to_initialized_n(const void *src, void *dst, uint n) const
+ void copy_to_initialized_n(const void *src, void *dst, int64_t n) const
{
BLI_assert(src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
@@ -404,7 +404,7 @@ class CPPType : NonCopyable, NonMovable {
copy_to_uninitialized_(src, dst);
}
- void copy_to_uninitialized_n(const void *src, void *dst, uint n) const
+ void copy_to_uninitialized_n(const void *src, void *dst, int64_t n) const
{
BLI_assert(src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
@@ -439,7 +439,7 @@ class CPPType : NonCopyable, NonMovable {
relocate_to_initialized_(src, dst);
}
- void relocate_to_initialized_n(void *src, void *dst, uint n) const
+ void relocate_to_initialized_n(void *src, void *dst, int64_t n) const
{
BLI_assert(src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
@@ -474,7 +474,7 @@ class CPPType : NonCopyable, NonMovable {
relocate_to_uninitialized_(src, dst);
}
- void relocate_to_uninitialized_n(void *src, void *dst, uint n) const
+ void relocate_to_uninitialized_n(void *src, void *dst, int64_t n) const
{
BLI_assert(src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
@@ -497,7 +497,7 @@ class CPPType : NonCopyable, NonMovable {
*
* Other instances of the same type should live in the array before this method is called.
*/
- void fill_initialized(const void *value, void *dst, uint n) const
+ void fill_initialized(const void *value, void *dst, int64_t n) const
{
BLI_assert(n == 0 || this->pointer_can_point_to_instance(value));
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
@@ -518,7 +518,7 @@ class CPPType : NonCopyable, NonMovable {
*
* The array should be uninitialized before this method is called.
*/
- void fill_uninitialized(const void *value, void *dst, uint n) const
+ void fill_uninitialized(const void *value, void *dst, int64_t n) const
{
BLI_assert(n == 0 || this->pointer_can_point_to_instance(value));
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
@@ -547,7 +547,7 @@ class CPPType : NonCopyable, NonMovable {
return is_equal_(a, b);
}
- uint32_t hash(const void *value) const
+ uint64_t hash(const void *value) const
{
BLI_assert(this->pointer_can_point_to_instance(value));
return hash_(value);
@@ -562,7 +562,7 @@ class CPPType : NonCopyable, NonMovable {
return default_value_;
}
- uint32_t hash() const
+ uint64_t hash() const
{
return DefaultHash<const CPPType *>{}(this);
}
@@ -583,39 +583,39 @@ template<typename T> void construct_default_cb(void *ptr)
{
new (ptr) T;
}
-template<typename T> void construct_default_n_cb(void *ptr, uint n)
+template<typename T> void construct_default_n_cb(void *ptr, int64_t n)
{
blender::default_construct_n((T *)ptr, n);
}
template<typename T> void construct_default_indices_cb(void *ptr, IndexMask mask)
{
- mask.foreach_index([&](uint i) { new ((T *)ptr + i) T; });
+ mask.foreach_index([&](int64_t i) { new ((T *)ptr + i) T; });
}
template<typename T> void destruct_cb(void *ptr)
{
((T *)ptr)->~T();
}
-template<typename T> void destruct_n_cb(void *ptr, uint n)
+template<typename T> void destruct_n_cb(void *ptr, int64_t n)
{
blender::destruct_n((T *)ptr, n);
}
template<typename T> void destruct_indices_cb(void *ptr, IndexMask mask)
{
T *ptr_ = (T *)ptr;
- mask.foreach_index([&](uint i) { ptr_[i].~T(); });
+ mask.foreach_index([&](int64_t i) { ptr_[i].~T(); });
}
template<typename T> void copy_to_initialized_cb(const void *src, void *dst)
{
*(T *)dst = *(T *)src;
}
-template<typename T> void copy_to_initialized_n_cb(const void *src, void *dst, uint n)
+template<typename T> void copy_to_initialized_n_cb(const void *src, void *dst, int64_t n)
{
const T *src_ = (const T *)src;
T *dst_ = (T *)dst;
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
dst_[i] = src_[i];
}
}
@@ -625,14 +625,14 @@ void copy_to_initialized_indices_cb(const void *src, void *dst, IndexMask mask)
const T *src_ = (const T *)src;
T *dst_ = (T *)dst;
- mask.foreach_index([&](uint i) { dst_[i] = src_[i]; });
+ mask.foreach_index([&](int64_t i) { dst_[i] = src_[i]; });
}
template<typename T> void copy_to_uninitialized_cb(const void *src, void *dst)
{
blender::uninitialized_copy_n((T *)src, 1, (T *)dst);
}
-template<typename T> void copy_to_uninitialized_n_cb(const void *src, void *dst, uint n)
+template<typename T> void copy_to_uninitialized_n_cb(const void *src, void *dst, int64_t n)
{
blender::uninitialized_copy_n((T *)src, n, (T *)dst);
}
@@ -642,7 +642,7 @@ void copy_to_uninitialized_indices_cb(const void *src, void *dst, IndexMask mask
const T *src_ = (const T *)src;
T *dst_ = (T *)dst;
- mask.foreach_index([&](uint i) { new (dst_ + i) T(src_[i]); });
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(src_[i]); });
}
template<typename T> void relocate_to_initialized_cb(void *src, void *dst)
@@ -653,7 +653,7 @@ template<typename T> void relocate_to_initialized_cb(void *src, void *dst)
*dst_ = std::move(*src_);
src_->~T();
}
-template<typename T> void relocate_to_initialized_n_cb(void *src, void *dst, uint n)
+template<typename T> void relocate_to_initialized_n_cb(void *src, void *dst, int64_t n)
{
blender::initialized_relocate_n((T *)src, n, (T *)dst);
}
@@ -662,7 +662,7 @@ template<typename T> void relocate_to_initialized_indices_cb(void *src, void *ds
T *src_ = (T *)src;
T *dst_ = (T *)dst;
- mask.foreach_index([&](uint i) {
+ mask.foreach_index([&](int64_t i) {
dst_[i] = std::move(src_[i]);
src_[i].~T();
});
@@ -676,7 +676,7 @@ template<typename T> void relocate_to_uninitialized_cb(void *src, void *dst)
new (dst_) T(std::move(*src_));
src_->~T();
}
-template<typename T> void relocate_to_uninitialized_n_cb(void *src, void *dst, uint n)
+template<typename T> void relocate_to_uninitialized_n_cb(void *src, void *dst, int64_t n)
{
blender::uninitialized_relocate_n((T *)src, n, (T *)dst);
}
@@ -686,18 +686,18 @@ void relocate_to_uninitialized_indices_cb(void *src, void *dst, IndexMask mask)
T *src_ = (T *)src;
T *dst_ = (T *)dst;
- mask.foreach_index([&](uint i) {
+ mask.foreach_index([&](int64_t i) {
new (dst_ + i) T(std::move(src_[i]));
src_[i].~T();
});
}
-template<typename T> void fill_initialized_cb(const void *value, void *dst, uint n)
+template<typename T> void fill_initialized_cb(const void *value, void *dst, int64_t n)
{
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
dst_[i] = value_;
}
}
@@ -706,15 +706,15 @@ template<typename T> void fill_initialized_indices_cb(const void *value, void *d
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- mask.foreach_index([&](uint i) { dst_[i] = value_; });
+ mask.foreach_index([&](int64_t i) { dst_[i] = value_; });
}
-template<typename T> void fill_uninitialized_cb(const void *value, void *dst, uint n)
+template<typename T> void fill_uninitialized_cb(const void *value, void *dst, int64_t n)
{
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- for (uint i = 0; i < n; i++) {
+ for (int64_t i = 0; i < n; i++) {
new (dst_ + i) T(value_);
}
}
@@ -724,7 +724,7 @@ void fill_uninitialized_indices_cb(const void *value, void *dst, IndexMask mask)
const T &value_ = *(const T *)value;
T *dst_ = (T *)dst;
- mask.foreach_index([&](uint i) { new (dst_ + i) T(value_); });
+ mask.foreach_index([&](int64_t i) { new (dst_ + i) T(value_); });
}
template<typename T> void debug_print_cb(const void *value, std::stringstream &ss)
@@ -740,7 +740,7 @@ template<typename T> bool is_equal_cb(const void *a, const void *b)
return a_ == b_;
}
-template<typename T> uint32_t hash_cb(const void *value)
+template<typename T> uint64_t hash_cb(const void *value)
{
const T &value_ = *(const T *)value;
return DefaultHash<T>{}(value_);
diff --git a/source/blender/functions/FN_generic_vector_array.hh b/source/blender/functions/FN_generic_vector_array.hh
index 2672484c184..ee67db000e5 100644
--- a/source/blender/functions/FN_generic_vector_array.hh
+++ b/source/blender/functions/FN_generic_vector_array.hh
@@ -42,10 +42,10 @@ template<typename T> class GVectorArrayRef;
class GVectorArray : NonCopyable, NonMovable {
private:
const CPPType &type_;
- uint element_size_;
+ int64_t element_size_;
Array<void *, 1> starts_;
- Array<uint, 1> lengths_;
- Array<uint, 1> capacities_;
+ Array<int64_t, 1> lengths_;
+ Array<int64_t, 1> capacities_;
LinearAllocator<> allocator_;
template<typename T> friend class GVectorArrayRef;
@@ -53,16 +53,16 @@ class GVectorArray : NonCopyable, NonMovable {
public:
GVectorArray() = delete;
- GVectorArray(const CPPType &type, uint array_size)
+ GVectorArray(const CPPType &type, int64_t array_size)
: type_(type),
element_size_(type.size()),
starts_(array_size),
lengths_(array_size),
capacities_(array_size)
{
- starts_.fill(nullptr);
- lengths_.fill(0);
- capacities_.fill(0);
+ starts_.as_mutable_span().fill(nullptr);
+ lengths_.as_mutable_span().fill(0);
+ capacities_.as_mutable_span().fill(0);
}
~GVectorArray()
@@ -71,7 +71,7 @@ class GVectorArray : NonCopyable, NonMovable {
return;
}
- for (uint i : starts_.index_range()) {
+ for (int64_t i : starts_.index_range()) {
type_.destruct_n(starts_[i], lengths_[i]);
}
}
@@ -86,7 +86,7 @@ class GVectorArray : NonCopyable, NonMovable {
return starts_.size() == 0;
}
- uint size() const
+ int64_t size() const
{
return starts_.size();
}
@@ -101,14 +101,14 @@ class GVectorArray : NonCopyable, NonMovable {
return starts_;
}
- Span<uint> lengths() const
+ Span<int64_t> lengths() const
{
return lengths_;
}
- void append(uint index, const void *src)
+ void append(int64_t index, const void *src)
{
- uint old_length = lengths_[index];
+ int64_t old_length = lengths_[index];
if (old_length == capacities_[index]) {
this->grow_at_least_one(index);
}
@@ -118,10 +118,10 @@ class GVectorArray : NonCopyable, NonMovable {
lengths_[index]++;
}
- void extend(uint index, GVSpan span)
+ void extend(int64_t index, GVSpan span)
{
BLI_assert(type_ == span.type());
- for (uint i = 0; i < span.size(); i++) {
+ for (int64_t i = 0; i < span.size(); i++) {
this->append(index, span[i]);
}
}
@@ -130,12 +130,12 @@ class GVectorArray : NonCopyable, NonMovable {
{
BLI_assert(type_ == array_span.type());
BLI_assert(mask.min_array_size() <= array_span.size());
- for (uint i : mask) {
+ for (int64_t i : mask) {
this->extend(i, array_span[i]);
}
}
- GMutableSpan operator[](uint index)
+ GMutableSpan operator[](int64_t index)
{
BLI_assert(index < starts_.size());
return GMutableSpan(type_, starts_[index], lengths_[index]);
@@ -146,10 +146,10 @@ class GVectorArray : NonCopyable, NonMovable {
}
private:
- void grow_at_least_one(uint index)
+ void grow_at_least_one(int64_t index)
{
BLI_assert(lengths_[index] == capacities_[index]);
- uint new_capacity = lengths_[index] * 2 + 1;
+ int64_t new_capacity = lengths_[index] * 2 + 1;
void *new_buffer = allocator_.allocate(element_size_ * new_capacity, type_.alignment());
type_.relocate_to_uninitialized_n(starts_[index], new_buffer, lengths_[index]);
@@ -169,28 +169,28 @@ template<typename T> class GVectorArrayRef {
BLI_assert(vector_array.type_.is<T>());
}
- void append(uint index, const T &value)
+ void append(int64_t index, const T &value)
{
vector_array_->append(index, &value);
}
- void extend(uint index, Span<T> values)
+ void extend(int64_t index, Span<T> values)
{
vector_array_->extend(index, values);
}
- void extend(uint index, VSpan<T> values)
+ void extend(int64_t index, VSpan<T> values)
{
vector_array_->extend(index, GVSpan(values));
}
- MutableSpan<T> operator[](uint index)
+ MutableSpan<T> operator[](int64_t index)
{
BLI_assert(index < vector_array_->starts_.size());
return MutableSpan<T>((T *)vector_array_->starts_[index], vector_array_->lengths_[index]);
}
- uint size() const
+ int64_t size() const
{
return vector_array_->size();
}
diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh
index 35f144368ac..77ab2749377 100644
--- a/source/blender/functions/FN_multi_function.hh
+++ b/source/blender/functions/FN_multi_function.hh
@@ -63,7 +63,7 @@ class MultiFunction {
virtual void call(IndexMask mask, MFParams params, MFContext context) const = 0;
- virtual uint32_t hash() const
+ virtual uint64_t hash() const
{
return DefaultHash<const MultiFunction *>{}(this);
}
@@ -73,7 +73,7 @@ class MultiFunction {
return false;
}
- uint param_amount() const
+ int param_amount() const
{
return signature_.param_types.size();
}
@@ -83,12 +83,12 @@ class MultiFunction {
return signature_.param_types.index_range();
}
- MFParamType param_type(uint param_index) const
+ MFParamType param_type(int param_index) const
{
return signature_.param_types[param_index];
}
- StringRefNull param_name(uint param_index) const
+ StringRefNull param_name(int param_index) const
{
return signature_.param_names[param_index];
}
@@ -111,7 +111,7 @@ class MultiFunction {
}
};
-inline MFParamsBuilder::MFParamsBuilder(const class MultiFunction &fn, uint min_array_size)
+inline MFParamsBuilder::MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size)
: MFParamsBuilder(fn.signature(), min_array_size)
{
}
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index c2c95f7c355..95e216558e7 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -59,7 +59,7 @@ template<typename In1, typename Out1> class CustomMF_SI_SO : public MultiFunctio
template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
{
return [=](IndexMask mask, VSpan<In1> in1, MutableSpan<Out1> out1) {
- mask.foreach_index([&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i])); });
+ mask.foreach_index([&](int i) { new ((void *)&out1[i]) Out1(element_fn(in1[i])); });
};
}
@@ -101,7 +101,7 @@ class CustomMF_SI_SI_SO : public MultiFunction {
template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
{
return [=](IndexMask mask, VSpan<In1> in1, VSpan<In2> in2, MutableSpan<Out1> out1) {
- mask.foreach_index([&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i])); });
+ mask.foreach_index([&](int i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i])); });
};
}
@@ -152,7 +152,7 @@ class CustomMF_SI_SI_SI_SO : public MultiFunction {
VSpan<In3> in3,
MutableSpan<Out1> out1) {
mask.foreach_index(
- [&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i], in3[i])); });
+ [&](int i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i], in3[i])); });
};
}
@@ -191,7 +191,7 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction {
template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
{
return [=](IndexMask mask, MutableSpan<Mut1> mut1) {
- mask.foreach_index([&](uint i) { element_fn(mut1[i]); });
+ mask.foreach_index([&](int i) { element_fn(mut1[i]); });
};
}
@@ -220,7 +220,7 @@ template<typename From, typename To> class CustomMF_Convert : public MultiFuncti
VSpan<From> inputs = params.readonly_single_input<From>(0);
MutableSpan<To> outputs = params.uninitialized_single_output<To>(1);
- for (uint i : mask) {
+ for (int64_t i : mask) {
new ((void *)&outputs[i]) To(inputs[i]);
}
}
@@ -240,7 +240,7 @@ class CustomMF_GenericConstant : public MultiFunction {
public:
CustomMF_GenericConstant(const CPPType &type, const void *value);
void call(IndexMask mask, MFParams params, MFContext context) const override;
- uint32_t hash() const override;
+ uint64_t hash() const override;
bool equals(const MultiFunction &other) const override;
};
@@ -276,10 +276,10 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
{
MutableSpan<T> output = params.uninitialized_single_output<T>(0);
- mask.foreach_index([&](uint i) { new (&output[i]) T(value_); });
+ mask.foreach_index([&](int i) { new (&output[i]) T(value_); });
}
- uint32_t hash() const override
+ uint64_t hash() const override
{
return DefaultHash<T>{}(value_);
}
@@ -304,7 +304,7 @@ template<typename T> class CustomMF_Constant : public MultiFunction {
class CustomMF_DefaultOutput : public MultiFunction {
private:
- uint output_amount_;
+ int output_amount_;
public:
CustomMF_DefaultOutput(StringRef name,
diff --git a/source/blender/functions/FN_multi_function_data_type.hh b/source/blender/functions/FN_multi_function_data_type.hh
index 57aea046006..23a1c0e5680 100644
--- a/source/blender/functions/FN_multi_function_data_type.hh
+++ b/source/blender/functions/FN_multi_function_data_type.hh
@@ -109,9 +109,9 @@ class MFDataType {
return "";
}
- uint hash() const
+ uint64_t hash() const
{
- return DefaultHash<CPPType>{}(*type_) + (uint32_t)category_;
+ return DefaultHash<CPPType>{}(*type_) + (uint64_t)category_;
}
};
diff --git a/source/blender/functions/FN_multi_function_network.hh b/source/blender/functions/FN_multi_function_network.hh
index 91eb5bb65dc..f6d6c7417e7 100644
--- a/source/blender/functions/FN_multi_function_network.hh
+++ b/source/blender/functions/FN_multi_function_network.hh
@@ -62,14 +62,14 @@ class MFNode : NonCopyable, NonMovable {
Span<MFInputSocket *> inputs_;
Span<MFOutputSocket *> outputs_;
bool is_dummy_;
- uint id_;
+ int id_;
friend MFNetwork;
public:
StringRefNull name() const;
- uint id() const;
+ int id() const;
MFNetwork &network();
const MFNetwork &network() const;
@@ -83,11 +83,11 @@ class MFNode : NonCopyable, NonMovable {
MFFunctionNode &as_function();
const MFFunctionNode &as_function() const;
- MFInputSocket &input(uint index);
- const MFInputSocket &input(uint index) const;
+ MFInputSocket &input(int index);
+ const MFInputSocket &input(int index) const;
- MFOutputSocket &output(uint index);
- const MFOutputSocket &output(uint index) const;
+ MFOutputSocket &output(int index);
+ const MFOutputSocket &output(int index) const;
Span<MFInputSocket *> inputs();
Span<const MFInputSocket *> inputs() const;
@@ -104,8 +104,8 @@ class MFNode : NonCopyable, NonMovable {
class MFFunctionNode : public MFNode {
private:
const MultiFunction *function_;
- Span<uint> input_param_indices_;
- Span<uint> output_param_indices_;
+ Span<int> input_param_indices_;
+ Span<int> output_param_indices_;
friend MFNetwork;
@@ -114,8 +114,8 @@ class MFFunctionNode : public MFNode {
const MultiFunction &function() const;
- const MFInputSocket &input_for_param(uint param_index) const;
- const MFOutputSocket &output_for_param(uint param_index) const;
+ const MFInputSocket &input_for_param(int param_index) const;
+ const MFOutputSocket &output_for_param(int param_index) const;
};
class MFDummyNode : public MFNode {
@@ -137,9 +137,9 @@ class MFSocket : NonCopyable, NonMovable {
protected:
MFNode *node_;
bool is_output_;
- uint index_;
+ int index_;
MFDataType data_type_;
- uint id_;
+ int id_;
StringRefNull name_;
friend MFNetwork;
@@ -147,8 +147,8 @@ class MFSocket : NonCopyable, NonMovable {
public:
StringRefNull name() const;
- uint id() const;
- uint index() const;
+ int id() const;
+ int index() const;
const MFDataType &data_type() const;
@@ -217,17 +217,17 @@ class MFNetwork : NonCopyable, NonMovable {
void remove(MFNode &node);
void remove(Span<MFNode *> nodes);
- uint socket_id_amount() const;
- uint node_id_amount() const;
+ int socket_id_amount() const;
+ int node_id_amount() const;
Span<MFDummyNode *> dummy_nodes();
Span<MFFunctionNode *> function_nodes();
- MFNode *node_or_null_by_id(uint id);
- const MFNode *node_or_null_by_id(uint id) const;
+ MFNode *node_or_null_by_id(int id);
+ const MFNode *node_or_null_by_id(int id) const;
- MFSocket *socket_or_null_by_id(uint id);
- const MFSocket *socket_or_null_by_id(uint id) const;
+ MFSocket *socket_or_null_by_id(int id);
+ const MFSocket *socket_or_null_by_id(int id) const;
void find_dependencies(Span<const MFInputSocket *> sockets,
VectorSet<const MFOutputSocket *> &r_dummy_sockets,
@@ -252,7 +252,7 @@ inline StringRefNull MFNode::name() const
}
}
-inline uint MFNode::id() const
+inline int MFNode::id() const
{
return id_;
}
@@ -301,22 +301,22 @@ inline const MFFunctionNode &MFNode::as_function() const
return *(const MFFunctionNode *)this;
}
-inline MFInputSocket &MFNode::input(uint index)
+inline MFInputSocket &MFNode::input(int index)
{
return *inputs_[index];
}
-inline const MFInputSocket &MFNode::input(uint index) const
+inline const MFInputSocket &MFNode::input(int index) const
{
return *inputs_[index];
}
-inline MFOutputSocket &MFNode::output(uint index)
+inline MFOutputSocket &MFNode::output(int index)
{
return *outputs_[index];
}
-inline const MFOutputSocket &MFNode::output(uint index) const
+inline const MFOutputSocket &MFNode::output(int index) const
{
return *outputs_[index];
}
@@ -365,12 +365,12 @@ inline const MultiFunction &MFFunctionNode::function() const
return *function_;
}
-inline const MFInputSocket &MFFunctionNode::input_for_param(uint param_index) const
+inline const MFInputSocket &MFFunctionNode::input_for_param(int param_index) const
{
return this->input(input_param_indices_.first_index(param_index));
}
-inline const MFOutputSocket &MFFunctionNode::output_for_param(uint param_index) const
+inline const MFOutputSocket &MFFunctionNode::output_for_param(int param_index) const
{
return this->output(output_param_indices_.first_index(param_index));
}
@@ -403,12 +403,12 @@ inline StringRefNull MFSocket::name() const
return name_;
}
-inline uint MFSocket::id() const
+inline int MFSocket::id() const
{
return id_;
}
-inline uint MFSocket::index() const
+inline int MFSocket::index() const
{
return index_;
}
@@ -504,32 +504,32 @@ inline Span<MFFunctionNode *> MFNetwork::function_nodes()
return function_nodes_;
}
-inline MFNode *MFNetwork::node_or_null_by_id(uint id)
+inline MFNode *MFNetwork::node_or_null_by_id(int id)
{
return node_or_null_by_id_[id];
}
-inline const MFNode *MFNetwork::node_or_null_by_id(uint id) const
+inline const MFNode *MFNetwork::node_or_null_by_id(int id) const
{
return node_or_null_by_id_[id];
}
-inline MFSocket *MFNetwork::socket_or_null_by_id(uint id)
+inline MFSocket *MFNetwork::socket_or_null_by_id(int id)
{
return socket_or_null_by_id_[id];
}
-inline const MFSocket *MFNetwork::socket_or_null_by_id(uint id) const
+inline const MFSocket *MFNetwork::socket_or_null_by_id(int id) const
{
return socket_or_null_by_id_[id];
}
-inline uint MFNetwork::socket_id_amount() const
+inline int MFNetwork::socket_id_amount() const
{
return socket_or_null_by_id_.size();
}
-inline uint MFNetwork::node_id_amount() const
+inline int MFNetwork::node_id_amount() const
{
return node_or_null_by_id_.size();
}
diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh
index e6683693a0a..9cce8bb7401 100644
--- a/source/blender/functions/FN_multi_function_params.hh
+++ b/source/blender/functions/FN_multi_function_params.hh
@@ -34,7 +34,7 @@ namespace blender::fn {
class MFParamsBuilder {
private:
const MFSignature *signature_;
- uint min_array_size_;
+ int64_t min_array_size_;
Vector<GVSpan> virtual_spans_;
Vector<GMutableSpan> mutable_spans_;
Vector<GVArraySpan> virtual_array_spans_;
@@ -43,12 +43,12 @@ class MFParamsBuilder {
friend class MFParams;
public:
- MFParamsBuilder(const MFSignature &signature, uint min_array_size)
+ MFParamsBuilder(const MFSignature &signature, int64_t min_array_size)
: signature_(&signature), min_array_size_(min_array_size)
{
}
- MFParamsBuilder(const class MultiFunction &fn, uint min_array_size);
+ MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size);
template<typename T> void add_readonly_single_input(const T *value)
{
@@ -96,21 +96,21 @@ class MFParamsBuilder {
vector_arrays_.append(&vector_array);
}
- GMutableSpan computed_array(uint param_index)
+ GMutableSpan computed_array(int param_index)
{
BLI_assert(ELEM(signature_->param_types[param_index].category(),
MFParamType::SingleOutput,
MFParamType::SingleMutable));
- uint data_index = signature_->data_index(param_index);
+ int data_index = signature_->data_index(param_index);
return mutable_spans_[data_index];
}
- GVectorArray &computed_vector_array(uint param_index)
+ GVectorArray &computed_vector_array(int param_index)
{
BLI_assert(ELEM(signature_->param_types[param_index].category(),
MFParamType::VectorOutput,
MFParamType::VectorMutable));
- uint data_index = signature_->data_index(param_index);
+ int data_index = signature_->data_index(param_index);
return *vector_arrays_[data_index];
}
@@ -119,13 +119,13 @@ class MFParamsBuilder {
{
UNUSED_VARS_NDEBUG(param_type);
#ifdef DEBUG
- uint param_index = this->current_param_index();
+ int param_index = this->current_param_index();
MFParamType expected_type = signature_->param_types[param_index];
BLI_assert(expected_type == param_type);
#endif
}
- uint current_param_index() const
+ int current_param_index() const
{
return virtual_spans_.size() + mutable_spans_.size() + virtual_array_spans_.size() +
vector_arrays_.size();
@@ -141,75 +141,75 @@ class MFParams {
{
}
- template<typename T> VSpan<T> readonly_single_input(uint param_index, StringRef name = "")
+ template<typename T> VSpan<T> readonly_single_input(int param_index, StringRef name = "")
{
return this->readonly_single_input(param_index, name).typed<T>();
}
- GVSpan readonly_single_input(uint param_index, StringRef name = "")
+ GVSpan readonly_single_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::SingleInput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->virtual_spans_[data_index];
}
template<typename T>
- MutableSpan<T> uninitialized_single_output(uint param_index, StringRef name = "")
+ MutableSpan<T> uninitialized_single_output(int param_index, StringRef name = "")
{
return this->uninitialized_single_output(param_index, name).typed<T>();
}
- GMutableSpan uninitialized_single_output(uint param_index, StringRef name = "")
+ GMutableSpan uninitialized_single_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::SingleOutput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->mutable_spans_[data_index];
}
- template<typename T> VArraySpan<T> readonly_vector_input(uint param_index, StringRef name = "")
+ template<typename T> VArraySpan<T> readonly_vector_input(int param_index, StringRef name = "")
{
return this->readonly_vector_input(param_index, name).typed<T>();
}
- GVArraySpan readonly_vector_input(uint param_index, StringRef name = "")
+ GVArraySpan readonly_vector_input(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::VectorInput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->virtual_array_spans_[data_index];
}
- template<typename T> GVectorArrayRef<T> vector_output(uint param_index, StringRef name = "")
+ template<typename T> GVectorArrayRef<T> vector_output(int param_index, StringRef name = "")
{
return this->vector_output(param_index, name).typed<T>();
}
- GVectorArray &vector_output(uint param_index, StringRef name = "")
+ GVectorArray &vector_output(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::VectorOutput);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return *builder_->vector_arrays_[data_index];
}
- template<typename T> MutableSpan<T> single_mutable(uint param_index, StringRef name = "")
+ template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "")
{
return this->single_mutable(param_index, name).typed<T>();
}
- GMutableSpan single_mutable(uint param_index, StringRef name = "")
+ GMutableSpan single_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::SingleMutable);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return builder_->mutable_spans_[data_index];
}
- template<typename T> GVectorArrayRef<T> vector_mutable(uint param_index, StringRef name = "")
+ template<typename T> GVectorArrayRef<T> vector_mutable(int param_index, StringRef name = "")
{
return this->vector_mutable(param_index, name).typed<T>();
}
- GVectorArray &vector_mutable(uint param_index, StringRef name = "")
+ GVectorArray &vector_mutable(int param_index, StringRef name = "")
{
this->assert_correct_param(param_index, name, MFParamType::VectorMutable);
- uint data_index = builder_->signature_->data_index(param_index);
+ int data_index = builder_->signature_->data_index(param_index);
return *builder_->vector_arrays_[data_index];
}
private:
- void assert_correct_param(uint param_index, StringRef name, MFParamType param_type)
+ void assert_correct_param(int param_index, StringRef name, MFParamType param_type)
{
UNUSED_VARS_NDEBUG(param_index, name, param_type);
#ifdef DEBUG
@@ -220,7 +220,7 @@ class MFParams {
#endif
}
- void assert_correct_param(uint param_index, StringRef name, MFParamType::Category category)
+ void assert_correct_param(int param_index, StringRef name, MFParamType::Category category)
{
UNUSED_VARS_NDEBUG(param_index, name, category);
#ifdef DEBUG
diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh
index e2cf783753e..af5f61fe2ee 100644
--- a/source/blender/functions/FN_multi_function_signature.hh
+++ b/source/blender/functions/FN_multi_function_signature.hh
@@ -33,11 +33,11 @@ namespace blender::fn {
struct MFSignature {
std::string function_name;
/* Use RawAllocator so that a MultiFunction can have static storage duration. */
- Vector<std::string, 4, RawAllocator> param_names;
- Vector<MFParamType, 4, RawAllocator> param_types;
- Vector<uint, 4, RawAllocator> param_data_indices;
+ RawVector<std::string> param_names;
+ RawVector<MFParamType> param_types;
+ RawVector<int> param_data_indices;
- uint data_index(uint param_index) const
+ int data_index(int param_index) const
{
return param_data_indices[param_index];
}
@@ -46,10 +46,10 @@ struct MFSignature {
class MFSignatureBuilder {
private:
MFSignature &data_;
- uint span_count_ = 0;
- uint virtual_span_count_ = 0;
- uint virtual_array_span_count_ = 0;
- uint vector_array_count_ = 0;
+ int span_count_ = 0;
+ int virtual_span_count_ = 0;
+ int virtual_array_span_count_ = 0;
+ int vector_array_count_ = 0;
public:
MFSignatureBuilder(MFSignature &data) : data_(data)
diff --git a/source/blender/functions/FN_spans.hh b/source/blender/functions/FN_spans.hh
index c8c98d66628..d8b381199cc 100644
--- a/source/blender/functions/FN_spans.hh
+++ b/source/blender/functions/FN_spans.hh
@@ -52,12 +52,13 @@ class GSpan {
private:
const CPPType *type_;
const void *buffer_;
- uint size_;
+ int64_t size_;
public:
- GSpan(const CPPType &type, const void *buffer, uint size)
+ GSpan(const CPPType &type, const void *buffer, int64_t size)
: type_(&type), buffer_(buffer), size_(size)
{
+ BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
BLI_assert(type.pointer_has_valid_alignment(buffer));
}
@@ -81,7 +82,7 @@ class GSpan {
return size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -91,7 +92,7 @@ class GSpan {
return buffer_;
}
- const void *operator[](uint index) const
+ const void *operator[](int64_t index) const
{
BLI_assert(index < size_);
return POINTER_OFFSET(buffer_, type_->size() * index);
@@ -112,12 +113,13 @@ class GMutableSpan {
private:
const CPPType *type_;
void *buffer_;
- uint size_;
+ int64_t size_;
public:
- GMutableSpan(const CPPType &type, void *buffer, uint size)
+ GMutableSpan(const CPPType &type, void *buffer, int64_t size)
: type_(&type), buffer_(buffer), size_(size)
{
+ BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
BLI_assert(type.pointer_has_valid_alignment(buffer));
}
@@ -147,7 +149,7 @@ class GMutableSpan {
return size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return size_;
}
@@ -157,7 +159,7 @@ class GMutableSpan {
return buffer_;
}
- void *operator[](uint index)
+ void *operator[](int64_t index)
{
BLI_assert(index < size_);
return POINTER_OFFSET(buffer_, type_->size() * index);
@@ -178,7 +180,7 @@ enum class VSpanCategory {
template<typename T> struct VSpanBase {
protected:
- uint virtual_size_;
+ int64_t virtual_size_;
VSpanCategory category_;
union {
struct {
@@ -212,7 +214,7 @@ template<typename T> struct VSpanBase {
return this->virtual_size_ == 0;
}
- uint size() const
+ int64_t size() const
{
return this->virtual_size_;
}
@@ -259,7 +261,7 @@ template<typename T> class VSpan : public VSpanBase<T> {
this->data_.full_pointer_array.data = values.begin();
}
- static VSpan FromSingle(const T *value, uint virtual_size)
+ static VSpan FromSingle(const T *value, int64_t virtual_size)
{
VSpan ref;
ref.virtual_size_ = virtual_size;
@@ -268,8 +270,9 @@ template<typename T> class VSpan : public VSpanBase<T> {
return ref;
}
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->virtual_size_);
switch (this->category_) {
case VSpanCategory::Single:
@@ -329,7 +332,7 @@ class GVSpan : public VSpanBase<void> {
{
}
- static GVSpan FromSingle(const CPPType &type, const void *value, uint virtual_size)
+ static GVSpan FromSingle(const CPPType &type, const void *value, int64_t virtual_size)
{
GVSpan ref;
ref.type_ = &type;
@@ -341,7 +344,7 @@ class GVSpan : public VSpanBase<void> {
static GVSpan FromSingleWithMaxSize(const CPPType &type, const void *value)
{
- return GVSpan::FromSingle(type, value, UINT32_MAX);
+ return GVSpan::FromSingle(type, value, INT64_MAX);
}
static GVSpan FromDefault(const CPPType &type)
@@ -349,7 +352,7 @@ class GVSpan : public VSpanBase<void> {
return GVSpan::FromSingleWithMaxSize(type, type.default_value());
}
- static GVSpan FromFullPointerArray(const CPPType &type, const void *const *values, uint size)
+ static GVSpan FromFullPointerArray(const CPPType &type, const void *const *values, int64_t size)
{
GVSpan ref;
ref.type_ = &type;
@@ -364,8 +367,9 @@ class GVSpan : public VSpanBase<void> {
return *this->type_;
}
- const void *operator[](uint index) const
+ const void *operator[](int64_t index) const
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->virtual_size_);
switch (this->category_) {
case VSpanCategory::Single:
@@ -400,8 +404,8 @@ class GVSpan : public VSpanBase<void> {
{
BLI_assert(this->size() >= mask.min_array_size());
- uint element_size = type_->size();
- for (uint i : mask) {
+ int64_t element_size = type_->size();
+ for (int64_t i : mask) {
type_->copy_to_uninitialized((*this)[i], POINTER_OFFSET(dst, element_size * i));
}
}
diff --git a/source/blender/functions/intern/attributes_ref.cc b/source/blender/functions/intern/attributes_ref.cc
index f61a9165c47..7bfcc69671a 100644
--- a/source/blender/functions/intern/attributes_ref.cc
+++ b/source/blender/functions/intern/attributes_ref.cc
@@ -20,7 +20,7 @@ namespace blender::fn {
AttributesInfoBuilder::~AttributesInfoBuilder()
{
- for (uint i : defaults_.index_range()) {
+ for (int i : defaults_.index_range()) {
types_[i]->destruct(defaults_[i]);
}
}
@@ -45,7 +45,7 @@ void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void
AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder)
{
- for (uint i : builder.types_.index_range()) {
+ for (int i : builder.types_.index_range()) {
StringRefNull name = allocator_.copy_string(builder.names_[i]);
const CPPType &type = *builder.types_[i];
const void *default_value = builder.defaults_[i];
@@ -62,7 +62,7 @@ AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder)
AttributesInfo::~AttributesInfo()
{
- for (uint i : defaults_.index_range()) {
+ for (int i : defaults_.index_range()) {
type_by_index_[i]->destruct(defaults_[i]);
}
}
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 7797c19d563..06084247e66 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -37,7 +37,7 @@ void CustomMF_GenericConstant::call(IndexMask mask,
type_.fill_uninitialized_indices(value_, output.buffer(), mask);
}
-uint CustomMF_GenericConstant::hash() const
+uint64_t CustomMF_GenericConstant::hash() const
{
return type_.hash(value_);
}
@@ -58,8 +58,8 @@ static std::string gspan_to_string(GSpan array)
{
std::stringstream ss;
ss << "[";
- uint max_amount = 5;
- for (uint i : IndexRange(std::min(max_amount, array.size()))) {
+ const int64_t max_amount = 5;
+ for (int64_t i : IndexRange(std::min(max_amount, array.size()))) {
array.type().debug_print(array[i], ss);
ss << ", ";
}
@@ -82,7 +82,7 @@ void CustomMF_GenericConstantArray::call(IndexMask mask,
MFContext UNUSED(context)) const
{
GVectorArray &vectors = params.vector_output(0);
- for (uint i : mask) {
+ for (int64_t i : mask) {
vectors.extend(i, array_);
}
}
@@ -102,7 +102,7 @@ CustomMF_DefaultOutput::CustomMF_DefaultOutput(StringRef name,
}
void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const
{
- for (uint param_index : this->param_indices()) {
+ for (int param_index : this->param_indices()) {
MFParamType param_type = this->param_type(param_index);
if (!param_type.is_output()) {
continue;
diff --git a/source/blender/functions/intern/multi_function_network.cc b/source/blender/functions/intern/multi_function_network.cc
index 1d3d3a8b5f2..cd3c38dd09f 100644
--- a/source/blender/functions/intern/multi_function_network.cc
+++ b/source/blender/functions/intern/multi_function_network.cc
@@ -50,9 +50,9 @@ void MFNode::destruct_sockets()
*/
MFFunctionNode &MFNetwork::add_function(const MultiFunction &function)
{
- Vector<uint, 16> input_param_indices, output_param_indices;
+ Vector<int, 16> input_param_indices, output_param_indices;
- for (uint param_index : function.param_indices()) {
+ for (int param_index : function.param_indices()) {
switch (function.param_type(param_index).interface_type()) {
case MFParamType::Input: {
input_param_indices.append(param_index);
@@ -77,16 +77,16 @@ MFFunctionNode &MFNetwork::add_function(const MultiFunction &function)
node.is_dummy_ = false;
node.id_ = node_or_null_by_id_.append_and_get_index(&node);
node.function_ = &function;
- node.input_param_indices_ = allocator_.construct_array_copy<uint>(input_param_indices);
- node.output_param_indices_ = allocator_.construct_array_copy<uint>(output_param_indices);
+ node.input_param_indices_ = allocator_.construct_array_copy<int>(input_param_indices);
+ node.output_param_indices_ = allocator_.construct_array_copy<int>(output_param_indices);
node.inputs_ = allocator_.construct_elements_and_pointer_array<MFInputSocket>(
input_param_indices.size());
node.outputs_ = allocator_.construct_elements_and_pointer_array<MFOutputSocket>(
output_param_indices.size());
- for (uint i : input_param_indices.index_range()) {
- uint param_index = input_param_indices[i];
+ for (int i : input_param_indices.index_range()) {
+ int param_index = input_param_indices[i];
MFParamType param = function.param_type(param_index);
BLI_assert(param.is_input_or_mutable());
@@ -100,8 +100,8 @@ MFFunctionNode &MFNetwork::add_function(const MultiFunction &function)
socket.id_ = socket_or_null_by_id_.append_and_get_index(&socket);
}
- for (uint i : output_param_indices.index_range()) {
- uint param_index = output_param_indices[i];
+ for (int i : output_param_indices.index_range()) {
+ int param_index = output_param_indices[i];
MFParamType param = function.param_type(param_index);
BLI_assert(param.is_output_or_mutable());
@@ -145,7 +145,7 @@ MFDummyNode &MFNetwork::add_dummy(StringRef name,
node.input_names_ = allocator_.allocate_array<StringRefNull>(input_types.size());
node.output_names_ = allocator_.allocate_array<StringRefNull>(output_types.size());
- for (uint i : input_types.index_range()) {
+ for (int i : input_types.index_range()) {
MFInputSocket &socket = *node.inputs_[i];
socket.data_type_ = input_types[i];
socket.node_ = &node;
@@ -156,7 +156,7 @@ MFDummyNode &MFNetwork::add_dummy(StringRef name,
node.input_names_[i] = socket.name_;
}
- for (uint i : output_types.index_range()) {
+ for (int i : output_types.index_range()) {
MFOutputSocket &socket = *node.outputs_[i];
socket.data_type_ = output_types[i];
socket.node_ = &node;
diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc
index b59cbc6a1a2..a7e1a2f42af 100644
--- a/source/blender/functions/intern/multi_function_network_evaluation.cc
+++ b/source/blender/functions/intern/multi_function_network_evaluation.cc
@@ -55,10 +55,10 @@ class MFNetworkEvaluationStorage {
LinearAllocator<> allocator_;
IndexMask mask_;
Array<Value *> value_per_output_id_;
- uint min_array_size_;
+ int64_t min_array_size_;
public:
- MFNetworkEvaluationStorage(IndexMask mask, uint socket_id_amount);
+ MFNetworkEvaluationStorage(IndexMask mask, int socket_id_amount);
~MFNetworkEvaluationStorage();
/* Add the values that have been provided by the caller of the multi-function network. */
@@ -155,8 +155,8 @@ void MFNetworkEvaluator::call(IndexMask mask, MFParams params, MFContext context
BLI_NOINLINE void MFNetworkEvaluator::copy_inputs_to_storage(MFParams params,
Storage &storage) const
{
- for (uint input_index : inputs_.index_range()) {
- uint param_index = input_index + 0;
+ for (int input_index : inputs_.index_range()) {
+ int param_index = input_index + 0;
const MFOutputSocket &socket = *inputs_[input_index];
switch (socket.data_type().category()) {
case MFDataType::Single: {
@@ -178,8 +178,8 @@ BLI_NOINLINE void MFNetworkEvaluator::copy_outputs_to_storage(
Storage &storage,
Vector<const MFInputSocket *> &outputs_to_initialize_in_the_end) const
{
- for (uint output_index : outputs_.index_range()) {
- uint param_index = output_index + inputs_.size();
+ for (int output_index : outputs_.index_range()) {
+ int param_index = output_index + inputs_.size();
const MFInputSocket &socket = *outputs_[output_index];
const MFOutputSocket &origin = *socket.origin();
@@ -263,7 +263,7 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_function(MFContext &global_contex
* function only on a single element. This can avoid many duplicate computations. */
MFParamsBuilder params{function, 1};
- for (uint param_index : function.param_indices()) {
+ for (int param_index : function.param_indices()) {
MFParamType param_type = function.param_type(param_index);
switch (param_type.category()) {
case MFParamType::SingleInput: {
@@ -312,7 +312,7 @@ BLI_NOINLINE void MFNetworkEvaluator::evaluate_function(MFContext &global_contex
else {
MFParamsBuilder params{function, storage.mask().min_array_size()};
- for (uint param_index : function.param_indices()) {
+ for (int param_index : function.param_indices()) {
MFParamType param_type = function.param_type(param_index);
switch (param_type.category()) {
case MFParamType::SingleInput: {
@@ -384,7 +384,7 @@ BLI_NOINLINE void MFNetworkEvaluator::initialize_remaining_outputs(
MFParams params, Storage &storage, Span<const MFInputSocket *> remaining_outputs) const
{
for (const MFInputSocket *socket : remaining_outputs) {
- uint param_index = inputs_.size() + outputs_.first_index_of(socket);
+ int param_index = inputs_.size() + outputs_.first_index_of(socket);
switch (socket->data_type().category()) {
case MFDataType::Single: {
@@ -506,7 +506,7 @@ struct OwnVectorValue : public Value {
/** \name Storage methods
* \{ */
-MFNetworkEvaluationStorage::MFNetworkEvaluationStorage(IndexMask mask, uint socket_id_amount)
+MFNetworkEvaluationStorage::MFNetworkEvaluationStorage(IndexMask mask, int socket_id_amount)
: mask_(mask),
value_per_output_id_(socket_id_amount, nullptr),
min_array_size_(mask.min_array_size())
diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc
index 849b24a318f..e76b2f51a15 100644
--- a/source/blender/functions/intern/multi_function_network_optimization.cc
+++ b/source/blender/functions/intern/multi_function_network_optimization.cc
@@ -107,7 +107,7 @@ static Vector<MFNode *> find_nodes_based_on_mask(MFNetwork &network,
bool mask_value)
{
Vector<MFNode *> nodes;
- for (uint id : id_mask.index_range()) {
+ for (int id : id_mask.index_range()) {
if (id_mask[id] == mask_value) {
MFNode *node = network.node_or_null_by_id(id);
if (node != nullptr) {
@@ -212,7 +212,7 @@ static void prepare_params_for_constant_folding(const MultiFunction &network_fn,
MFParamsBuilder &params,
ResourceCollector &resources)
{
- for (uint param_index : network_fn.param_indices()) {
+ for (int param_index : network_fn.param_indices()) {
MFParamType param_type = network_fn.param_type(param_index);
MFDataType data_type = param_type.data_type();
@@ -244,7 +244,7 @@ static Array<MFOutputSocket *> add_constant_folded_sockets(const MultiFunction &
{
Array<MFOutputSocket *> folded_sockets{network_fn.param_indices().size(), nullptr};
- for (uint param_index : network_fn.param_indices()) {
+ for (int param_index : network_fn.param_indices()) {
MFParamType param_type = network_fn.param_type(param_index);
MFDataType data_type = param_type.data_type();
@@ -302,7 +302,7 @@ void constant_folding(MFNetwork &network, ResourceCollector &resources)
Array<MFOutputSocket *> folded_sockets = compute_constant_sockets_and_add_folded_nodes(
network, inputs_to_fold, resources);
- for (uint i : inputs_to_fold.index_range()) {
+ for (int i : inputs_to_fold.index_range()) {
MFOutputSocket &original_socket = *inputs_to_fold[i]->origin();
network.relink(original_socket, *folded_sockets[i]);
}
@@ -317,12 +317,12 @@ void constant_folding(MFNetwork &network, ResourceCollector &resources)
*
* \{ */
-static uint32_t compute_node_hash(MFFunctionNode &node, RNG *rng, Span<uint32_t> node_hashes)
+static uint64_t compute_node_hash(MFFunctionNode &node, RNG *rng, Span<uint64_t> node_hashes)
{
- uint32_t combined_inputs_hash = 394659347u;
+ uint64_t combined_inputs_hash = 394659347u;
for (MFInputSocket *input_socket : node.inputs()) {
MFOutputSocket *origin_socket = input_socket->origin();
- uint32_t input_hash;
+ uint64_t input_hash;
if (origin_socket == nullptr) {
input_hash = BLI_rng_get_uint(rng);
}
@@ -333,8 +333,8 @@ static uint32_t compute_node_hash(MFFunctionNode &node, RNG *rng, Span<uint32_t>
combined_inputs_hash = BLI_ghashutil_combine_hash(combined_inputs_hash, input_hash);
}
- uint32_t function_hash = node.function().hash();
- uint32_t node_hash = BLI_ghashutil_combine_hash(combined_inputs_hash, function_hash);
+ uint64_t function_hash = node.function().hash();
+ uint64_t node_hash = BLI_ghashutil_combine_hash(combined_inputs_hash, function_hash);
return node_hash;
}
@@ -342,15 +342,15 @@ static uint32_t compute_node_hash(MFFunctionNode &node, RNG *rng, Span<uint32_t>
* Produces a hash for every node. Two nodes with the same hash should have a high probability of
* outputting the same values.
*/
-static Array<uint32_t> compute_node_hashes(MFNetwork &network)
+static Array<uint64_t> compute_node_hashes(MFNetwork &network)
{
RNG *rng = BLI_rng_new(0);
- Array<uint32_t> node_hashes(network.node_id_amount());
+ Array<uint64_t> node_hashes(network.node_id_amount());
Array<bool> node_is_hashed(network.node_id_amount(), false);
/* No dummy nodes are not assumed to output the same values. */
for (MFDummyNode *node : network.dummy_nodes()) {
- uint32_t node_hash = BLI_rng_get_uint(rng);
+ uint64_t node_hash = BLI_rng_get_uint(rng);
node_hashes[node->id()] = node_hash;
node_is_hashed[node->id()] = true;
}
@@ -381,7 +381,7 @@ static Array<uint32_t> compute_node_hashes(MFNetwork &network)
continue;
}
- uint32_t node_hash = compute_node_hash(node, rng, node_hashes);
+ uint64_t node_hash = compute_node_hash(node, rng, node_hashes);
node_hashes[node.id()] = node_hash;
node_is_hashed[node.id()] = true;
nodes_to_check.pop();
@@ -391,14 +391,14 @@ static Array<uint32_t> compute_node_hashes(MFNetwork &network)
return node_hashes;
}
-static Map<uint32_t, Vector<MFNode *, 1>> group_nodes_by_hash(MFNetwork &network,
- Span<uint32_t> node_hashes)
+static Map<uint64_t, Vector<MFNode *, 1>> group_nodes_by_hash(MFNetwork &network,
+ Span<uint64_t> node_hashes)
{
- Map<uint32_t, Vector<MFNode *, 1>> nodes_by_hash;
- for (uint id : IndexRange(network.node_id_amount())) {
+ Map<uint64_t, Vector<MFNode *, 1>> nodes_by_hash;
+ for (int id : IndexRange(network.node_id_amount())) {
MFNode *node = network.node_or_null_by_id(id);
if (node != nullptr) {
- uint32_t node_hash = node_hashes[id];
+ uint64_t node_hash = node_hashes[id];
nodes_by_hash.lookup_or_add_default(node_hash).append(node);
}
}
@@ -428,7 +428,7 @@ static bool nodes_output_same_values(DisjointSet &cache, const MFNode &a, const
if (!functions_are_equal(a.as_function().function(), b.as_function().function())) {
return false;
}
- for (uint i : a.inputs().index_range()) {
+ for (int i : a.inputs().index_range()) {
const MFOutputSocket *origin_a = a.input(i).origin();
const MFOutputSocket *origin_b = b.input(i).origin();
if (origin_a == nullptr || origin_b == nullptr) {
@@ -444,7 +444,7 @@ static bool nodes_output_same_values(DisjointSet &cache, const MFNode &a, const
}
static void relink_duplicate_nodes(MFNetwork &network,
- Map<uint32_t, Vector<MFNode *, 1>> &nodes_by_hash)
+ Map<uint64_t, Vector<MFNode *, 1>> &nodes_by_hash)
{
DisjointSet same_node_cache{network.node_id_amount()};
@@ -462,7 +462,7 @@ static void relink_duplicate_nodes(MFNetwork &network,
/* This is true with fairly high probability, but hash collisions can happen. So we have to
* check if the node actually output the same values. */
if (nodes_output_same_values(same_node_cache, deduplicated_node, *node)) {
- for (uint i : deduplicated_node.outputs().index_range()) {
+ for (int i : deduplicated_node.outputs().index_range()) {
network.relink(node->output(i), deduplicated_node.output(i));
}
}
@@ -481,8 +481,8 @@ static void relink_duplicate_nodes(MFNetwork &network,
*/
void common_subnetwork_elimination(MFNetwork &network)
{
- Array<uint32_t> node_hashes = compute_node_hashes(network);
- Map<uint32_t, Vector<MFNode *, 1>> nodes_by_hash = group_nodes_by_hash(network, node_hashes);
+ Array<uint64_t> node_hashes = compute_node_hashes(network);
+ Map<uint64_t, Vector<MFNode *, 1>> nodes_by_hash = group_nodes_by_hash(network, node_hashes);
relink_duplicate_nodes(network, nodes_by_hash);
}
diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/gpu/intern/gpu_draw_smoke.c
index 89261afaebd..e0b94e20574 100644
--- a/source/blender/gpu/intern/gpu_draw_smoke.c
+++ b/source/blender/gpu/intern/gpu_draw_smoke.c
@@ -196,7 +196,7 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
float *data;
if (highres) {
- data = manta_smoke_turbulence_get_density(fds->fluid);
+ data = manta_noise_get_density(fds->fluid);
}
else {
data = manta_smoke_get_density(fds->fluid);
@@ -212,14 +212,14 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
{
- const bool has_color = (highres) ? manta_smoke_turbulence_has_colors(fds->fluid) :
+ const bool has_color = (highres) ? manta_noise_has_colors(fds->fluid) :
manta_smoke_has_colors(fds->fluid);
if (!has_color) {
return NULL;
}
- int cell_count = (highres) ? manta_smoke_turbulence_get_cells(fds->fluid) : fds->total_cells;
+ int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
int *dim = (highres) ? fds->res_noise : fds->res;
float *data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
@@ -228,7 +228,7 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
}
if (highres) {
- manta_smoke_turbulence_get_rgba(fds->fluid, data, 0);
+ manta_noise_get_rgba(fds->fluid, data, 0);
}
else {
manta_smoke_get_rgba(fds->fluid, data, 0);
@@ -245,7 +245,7 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
{
float *source = NULL;
- const bool has_fuel = (highres) ? manta_smoke_turbulence_has_fuel(fds->fluid) :
+ const bool has_fuel = (highres) ? manta_noise_has_fuel(fds->fluid) :
manta_smoke_has_fuel(fds->fluid);
int *dim = (highres) ? fds->res_noise : fds->res;
@@ -254,7 +254,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
}
if (highres) {
- source = manta_smoke_turbulence_get_flame(fds->fluid);
+ source = manta_noise_get_flame(fds->fluid);
}
else {
source = manta_smoke_get_flame(fds->fluid);
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index 3387958c2f6..71b8eee9d50 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -718,10 +718,10 @@ static int rna_FluidModifier_grid_get_length(PointerRNA *ptr, int length[RNA_MAX
/* high resolution smoke */
int res[3];
- manta_smoke_turbulence_get_res(fds->fluid, res);
+ manta_noise_get_res(fds->fluid, res);
size = res[0] * res[1] * res[2];
- density = manta_smoke_turbulence_get_density(fds->fluid);
+ density = manta_noise_get_density(fds->fluid);
}
else if (fds->fluid) {
/* regular resolution */
@@ -790,7 +790,7 @@ static void rna_FluidModifier_density_grid_get(PointerRNA *ptr, float *values)
BLI_rw_mutex_lock(fds->fluid_mutex, THREAD_LOCK_READ);
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- density = manta_smoke_turbulence_get_density(fds->fluid);
+ density = manta_noise_get_density(fds->fluid);
}
else {
density = manta_smoke_get_density(fds->fluid);
@@ -837,11 +837,11 @@ static void rna_FluidModifier_color_grid_get(PointerRNA *ptr, float *values)
}
else {
if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- if (manta_smoke_turbulence_has_colors(fds->fluid)) {
- manta_smoke_turbulence_get_rgba(fds->fluid, values, 0);
+ if (manta_noise_has_colors(fds->fluid)) {
+ manta_noise_get_rgba(fds->fluid, values, 0);
}
else {
- manta_smoke_turbulence_get_rgba_fixed_color(fds->fluid, fds->active_color, values, 0);
+ manta_noise_get_rgba_fixed_color(fds->fluid, fds->active_color, values, 0);
}
}
else {
@@ -867,7 +867,7 @@ static void rna_FluidModifier_flame_grid_get(PointerRNA *ptr, float *values)
BLI_rw_mutex_lock(fds->fluid_mutex, THREAD_LOCK_READ);
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- flame = manta_smoke_turbulence_get_flame(fds->fluid);
+ flame = manta_noise_get_flame(fds->fluid);
}
else {
flame = manta_smoke_get_flame(fds->fluid);
@@ -917,7 +917,7 @@ static void rna_FluidModifier_temperature_grid_get(PointerRNA *ptr, float *value
BLI_rw_mutex_lock(fds->fluid_mutex, THREAD_LOCK_READ);
if (fds->flags & FLUID_DOMAIN_USE_NOISE && fds->fluid) {
- flame = manta_smoke_turbulence_get_flame(fds->fluid);
+ flame = manta_noise_get_flame(fds->fluid);
}
else {
flame = manta_smoke_get_flame(fds->fluid);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 332108facb3..6f0192bb810 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -4448,7 +4448,7 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_ShaderNode_socket_update");
prop = RNA_def_property(srna, "sun_size", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_ui_text(prop, "Sun Size", "Size of sun disc (angular diameter)");
+ RNA_def_property_ui_text(prop, "Sun Size", "Size of sun disc");
RNA_def_property_range(prop, 0.0f, M_PI_2);
RNA_def_property_float_default(prop, DEG2RADF(0.545));
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -4460,7 +4460,7 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "sun_elevation", PROP_FLOAT, PROP_ANGLE);
- RNA_def_property_ui_text(prop, "Sun Elevation", "Angle between sun and horizon");
+ RNA_def_property_ui_text(prop, "Sun Elevation", "Sun angle from horizon");
RNA_def_property_range(prop, -M_PI_2, M_PI_2);
RNA_def_property_float_default(prop, M_PI_2);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
@@ -4471,25 +4471,25 @@ static void def_sh_tex_sky(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "altitude", PROP_FLOAT, PROP_NONE);
- RNA_def_property_ui_text(prop, "Altitude", "Height from sea level in km");
+ RNA_def_property_ui_text(prop, "Altitude", "Height from sea level");
RNA_def_property_range(prop, 0.0f, 60.0f);
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "air_density", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_ui_text(prop, "Air", "Density of air molecules (Rayleigh scattering)");
+ RNA_def_property_ui_text(prop, "Air", "Density of air molecules");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "dust_density", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_ui_text(prop, "Dust", "Density of dust and water molecules (Mie scattering)");
+ RNA_def_property_ui_text(prop, "Dust", "Density of dust molecules and water droplets");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "ozone_density", PROP_FLOAT, PROP_FACTOR);
- RNA_def_property_ui_text(prop, "Ozone", "Density of Ozone layer (Ozone absorption)");
+ RNA_def_property_ui_text(prop, "Ozone", "Density of Ozone layer");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index a41abb1a1dd..5b77632be79 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -27,6 +27,8 @@
#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BPY_extern.h"
+
#include "DEG_depsgraph.h"
#include "BKE_image.h"
@@ -408,6 +410,19 @@ static PointerRNA rna_RenderEngine_camera_override_get(PointerRNA *ptr)
}
}
+static void rna_RenderEngine_engine_frame_set(RenderEngine *engine, int frame, float subframe)
+{
+# ifdef WITH_PYTHON
+ BPy_BEGIN_ALLOW_THREADS;
+# endif
+
+ RE_engine_frame_set(engine, frame, subframe);
+
+# ifdef WITH_PYTHON
+ BPy_END_ALLOW_THREADS;
+# endif
+}
+
static void rna_RenderResult_views_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
RenderResult *rr = (RenderResult *)ptr->data;
@@ -673,7 +688,7 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_string(func, "info", NULL, 0, "Info", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
- func = RNA_def_function(srna, "frame_set", "RE_engine_frame_set");
+ func = RNA_def_function(srna, "frame_set", "rna_RenderEngine_engine_frame_set");
RNA_def_function_ui_description(func, "Evaluate scene at a different frame (for motion blur)");
parm = RNA_def_int(func, "frame", 0, INT_MIN, INT_MAX, "Frame", "", INT_MIN, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
@@ -830,6 +845,14 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use Eevee Viewport", "Uses Eevee for viewport shading in LookDev shading mode");
+ prop = RNA_def_property(srna, "bl_use_gpu_context", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_GPU_CONTEXT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(
+ prop,
+ "Use GPU Context",
+ "Enable OpenGL context for the render method, for engines that render using OpenGL");
+
prop = RNA_def_property(srna, "bl_use_shading_nodes_custom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SHADING_NODES_CUSTOM);
RNA_def_property_boolean_default(prop, true);
diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh
index 84370dcd399..d79bd9031b8 100644
--- a/source/blender/nodes/NOD_derived_node_tree.hh
+++ b/source/blender/nodes/NOD_derived_node_tree.hh
@@ -46,15 +46,15 @@ class DSocket : NonCopyable, NonMovable {
protected:
DNode *node_;
const SocketRef *socket_ref_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
public:
const DNode &node() const;
- uint id() const;
- uint index() const;
+ int id() const;
+ int index() const;
bool is_input() const;
bool is_output() const;
@@ -105,7 +105,7 @@ class DGroupInput : NonCopyable, NonMovable {
const InputSocketRef *socket_ref_;
DParentNode *parent_;
Vector<DInputSocket *> linked_sockets_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
@@ -114,7 +114,7 @@ class DGroupInput : NonCopyable, NonMovable {
bNodeSocket *bsocket() const;
const DParentNode *parent() const;
Span<const DInputSocket *> linked_sockets() const;
- uint id() const;
+ int id() const;
StringRefNull name() const;
};
@@ -126,7 +126,7 @@ class DNode : NonCopyable, NonMovable {
Span<DInputSocket *> inputs_;
Span<DOutputSocket *> outputs_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
@@ -137,13 +137,13 @@ class DNode : NonCopyable, NonMovable {
Span<const DInputSocket *> inputs() const;
Span<const DOutputSocket *> outputs() const;
- const DInputSocket &input(uint index) const;
- const DOutputSocket &output(uint index) const;
+ const DInputSocket &input(int index) const;
+ const DOutputSocket &output(int index) const;
- const DInputSocket &input(uint index, StringRef expected_name) const;
- const DOutputSocket &output(uint index, StringRef expected_name) const;
+ const DInputSocket &input(int index, StringRef expected_name) const;
+ const DOutputSocket &output(int index, StringRef expected_name) const;
- uint id() const;
+ int id() const;
PointerRNA *rna() const;
StringRefNull idname() const;
@@ -157,14 +157,14 @@ class DParentNode : NonCopyable, NonMovable {
private:
const NodeRef *node_ref_;
DParentNode *parent_;
- uint id_;
+ int id_;
friend DerivedNodeTree;
public:
const DParentNode *parent() const;
const NodeRef &node_ref() const;
- uint id() const;
+ int id() const;
};
using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
@@ -240,12 +240,12 @@ inline const DNode &DSocket::node() const
return *node_;
}
-inline uint DSocket::id() const
+inline int DSocket::id() const
{
return id_;
}
-inline uint DSocket::index() const
+inline int DSocket::index() const
{
return socket_ref_->index();
}
@@ -367,7 +367,7 @@ inline Span<const DInputSocket *> DGroupInput::linked_sockets() const
return linked_sockets_;
}
-inline uint DGroupInput::id() const
+inline int DGroupInput::id() const
{
return id_;
}
@@ -401,17 +401,17 @@ inline Span<const DOutputSocket *> DNode::outputs() const
return outputs_;
}
-inline const DInputSocket &DNode::input(uint index) const
+inline const DInputSocket &DNode::input(int index) const
{
return *inputs_[index];
}
-inline const DOutputSocket &DNode::output(uint index) const
+inline const DOutputSocket &DNode::output(int index) const
{
return *outputs_[index];
}
-inline const DInputSocket &DNode::input(uint index, StringRef expected_name) const
+inline const DInputSocket &DNode::input(int index, StringRef expected_name) const
{
const DInputSocket &socket = *inputs_[index];
BLI_assert(socket.name() == expected_name);
@@ -419,7 +419,7 @@ inline const DInputSocket &DNode::input(uint index, StringRef expected_name) con
return socket;
}
-inline const DOutputSocket &DNode::output(uint index, StringRef expected_name) const
+inline const DOutputSocket &DNode::output(int index, StringRef expected_name) const
{
const DOutputSocket &socket = *outputs_[index];
BLI_assert(socket.name() == expected_name);
@@ -427,7 +427,7 @@ inline const DOutputSocket &DNode::output(uint index, StringRef expected_name) c
return socket;
}
-inline uint DNode::id() const
+inline int DNode::id() const
{
return id_;
}
@@ -461,7 +461,7 @@ inline const NodeRef &DParentNode::node_ref() const
return *node_ref_;
}
-inline uint DParentNode::id() const
+inline int DParentNode::id() const
{
return id_;
}
diff --git a/source/blender/nodes/NOD_node_tree_multi_function.hh b/source/blender/nodes/NOD_node_tree_multi_function.hh
index f7a1fbb114d..79c2b3c7ce8 100644
--- a/source/blender/nodes/NOD_node_tree_multi_function.hh
+++ b/source/blender/nodes/NOD_node_tree_multi_function.hh
@@ -106,7 +106,7 @@ class MFNetworkTreeMap {
void add(Span<const DInputSocket *> dsockets, Span<fn::MFInputSocket *> sockets)
{
assert_same_size(dsockets, sockets);
- for (uint i : dsockets.index_range()) {
+ for (int i : dsockets.index_range()) {
this->add(*dsockets[i], *sockets[i]);
}
}
@@ -114,7 +114,7 @@ class MFNetworkTreeMap {
void add(Span<const DOutputSocket *> dsockets, Span<fn::MFOutputSocket *> sockets)
{
assert_same_size(dsockets, sockets);
- for (uint i : dsockets.index_range()) {
+ for (int i : dsockets.index_range()) {
this->add(*dsockets[i], *sockets[i]);
}
}
@@ -133,7 +133,7 @@ class MFNetworkTreeMap {
void add_try_match(Span<const DSocket *> dsockets, Span<fn::MFSocket *> sockets)
{
- uint used_sockets = 0;
+ int used_sockets = 0;
for (const DSocket *dsocket : dsockets) {
if (!dsocket->is_available()) {
continue;
diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index 907184125b8..ebf5709ef50 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -71,8 +71,8 @@ class SocketRef : NonCopyable, NonMovable {
NodeRef *node_;
bNodeSocket *bsocket_;
bool is_input_;
- uint id_;
- uint index_;
+ int id_;
+ int index_;
PointerRNA rna_;
Vector<SocketRef *> linked_sockets_;
Vector<SocketRef *> directly_linked_sockets_;
@@ -87,8 +87,8 @@ class SocketRef : NonCopyable, NonMovable {
const NodeRef &node() const;
const NodeTreeRef &tree() const;
- uint id() const;
- uint index() const;
+ int id() const;
+ int index() const;
bool is_input() const;
bool is_output() const;
@@ -124,7 +124,7 @@ class NodeRef : NonCopyable, NonMovable {
NodeTreeRef *tree_;
bNode *bnode_;
PointerRNA rna_;
- uint id_;
+ int id_;
Vector<InputSocketRef *> inputs_;
Vector<OutputSocketRef *> outputs_;
@@ -136,8 +136,8 @@ class NodeRef : NonCopyable, NonMovable {
Span<const InputSocketRef *> inputs() const;
Span<const OutputSocketRef *> outputs() const;
- const InputSocketRef &input(uint index) const;
- const OutputSocketRef &output(uint index) const;
+ const InputSocketRef &input(int index) const;
+ const OutputSocketRef &output(int index) const;
bNode *bnode() const;
bNodeTree *btree() const;
@@ -146,7 +146,7 @@ class NodeRef : NonCopyable, NonMovable {
StringRefNull idname() const;
StringRefNull name() const;
- uint id() const;
+ int id() const;
bool is_reroute_node() const;
bool is_group_node() const;
@@ -220,12 +220,12 @@ inline const NodeTreeRef &SocketRef::tree() const
return node_->tree();
}
-inline uint SocketRef::id() const
+inline int SocketRef::id() const
{
return id_;
}
-inline uint SocketRef::index() const
+inline int SocketRef::index() const
{
return index_;
}
@@ -334,12 +334,12 @@ inline Span<const OutputSocketRef *> NodeRef::outputs() const
return outputs_;
}
-inline const InputSocketRef &NodeRef::input(uint index) const
+inline const InputSocketRef &NodeRef::input(int index) const
{
return *inputs_[index];
}
-inline const OutputSocketRef &NodeRef::output(uint index) const
+inline const OutputSocketRef &NodeRef::output(int index) const
{
return *outputs_[index];
}
@@ -369,7 +369,7 @@ inline StringRefNull NodeRef::name() const
return bnode_->name;
}
-inline uint NodeRef::id() const
+inline int NodeRef::id() const
{
return id_;
}
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc
index daec67b53a9..b7c78cb1499 100644
--- a/source/blender/nodes/intern/derived_node_tree.cc
+++ b/source/blender/nodes/intern/derived_node_tree.cc
@@ -83,7 +83,7 @@ DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
node.outputs_ = allocator_.construct_elements_and_pointer_array<DOutputSocket>(
node_ref.outputs().size());
- for (uint i : node.inputs_.index_range()) {
+ for (int i : node.inputs_.index_range()) {
const InputSocketRef &socket_ref = node_ref.input(i);
DInputSocket &socket = *node.inputs_[i];
@@ -94,7 +94,7 @@ DNode &DerivedNodeTree::create_node(const NodeRef &node_ref,
r_sockets_map[socket_ref.id()] = &socket;
}
- for (uint i : node.outputs_.index_range()) {
+ for (int i : node.outputs_.index_range()) {
const OutputSocketRef &socket_ref = node_ref.output(i);
DOutputSocket &socket = *node.outputs_[i];
@@ -113,7 +113,7 @@ BLI_NOINLINE void DerivedNodeTree::expand_groups(Vector<DNode *> &all_nodes,
Vector<DParentNode *> &all_parent_nodes,
NodeTreeRefMap &node_tree_refs)
{
- for (uint i = 0; i < all_nodes.size(); i++) {
+ for (int i = 0; i < all_nodes.size(); i++) {
DNode &node = *all_nodes[i];
if (node.node_ref_->is_group_node()) {
this->expand_group_node(node, all_nodes, all_group_inputs, all_parent_nodes, node_tree_refs);
@@ -181,10 +181,10 @@ BLI_NOINLINE void DerivedNodeTree::relink_group_inputs(const NodeTreeRef &group_
const NodeRef &input_node_ref = *node_refs[0];
DNode &input_node = *nodes_by_id[input_node_ref.id()];
- uint input_amount = group_node.inputs().size();
+ int input_amount = group_node.inputs().size();
BLI_assert(input_amount == input_node_ref.outputs().size() - 1);
- for (uint input_index : IndexRange(input_amount)) {
+ for (int input_index : IndexRange(input_amount)) {
DInputSocket *outside_group = group_node.inputs_[input_index];
DOutputSocket *inside_group = input_node.outputs_[input_index];
@@ -228,10 +228,10 @@ BLI_NOINLINE void DerivedNodeTree::relink_group_outputs(const NodeTreeRef &group
const NodeRef &output_node_ref = *node_refs[0];
DNode &output_node = *nodes_by_id[output_node_ref.id()];
- uint output_amount = group_node.outputs().size();
+ int output_amount = group_node.outputs().size();
BLI_assert(output_amount == output_node_ref.inputs().size() - 1);
- for (uint output_index : IndexRange(output_amount)) {
+ for (int output_index : IndexRange(output_amount)) {
DOutputSocket *outside_group = group_node.outputs_[output_index];
DInputSocket *inside_group = output_node.inputs_[output_index];
@@ -316,7 +316,7 @@ BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
group_inputs_ = std::move(all_group_inputs);
parent_nodes_ = std::move(all_parent_nodes);
- for (uint node_index : nodes_by_id_.index_range()) {
+ for (int node_index : nodes_by_id_.index_range()) {
DNode *node = nodes_by_id_[node_index];
node->id_ = node_index;
@@ -333,7 +333,7 @@ BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
}
}
- for (uint i : group_inputs_.index_range()) {
+ for (int i : group_inputs_.index_range()) {
group_inputs_[i]->id_ = i;
}
}
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index f77b19354a4..82842c4ef32 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -62,7 +62,7 @@ const fn::MultiFunction &NodeMFNetworkBuilder::get_default_fn(StringRef name)
static void insert_dummy_node(CommonMFNetworkBuilderData &common, const DNode &dnode)
{
- constexpr uint stack_capacity = 10;
+ constexpr int stack_capacity = 10;
Vector<fn::MFDataType, stack_capacity> input_types;
Vector<StringRef, stack_capacity> input_names;
@@ -159,7 +159,7 @@ static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
{
Span<const DOutputSocket *> from_dsockets = to_dsocket.linked_sockets();
Span<const DGroupInput *> from_group_inputs = to_dsocket.linked_group_inputs();
- uint total_linked_amount = from_dsockets.size() + from_group_inputs.size();
+ int total_linked_amount = from_dsockets.size() + from_group_inputs.size();
BLI_assert(total_linked_amount <= 1);
if (total_linked_amount == 0) {
diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
index b026499ec4b..4a6c9ec9a4d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc
@@ -115,13 +115,13 @@ class MapRangeFunction : public blender::fn::MultiFunction {
blender::fn::VSpan<float> to_max = params.readonly_single_input<float>(4, "To Max");
blender::MutableSpan<float> results = params.uninitialized_single_output<float>(5, "Result");
- for (uint i : mask) {
+ for (int64_t i : mask) {
float factor = safe_divide(values[i] - from_min[i], from_max[i] - from_min[i]);
results[i] = to_min[i] + factor * (to_max[i] - to_min[i]);
}
if (clamp_) {
- for (uint i : mask) {
+ for (int64_t i : mask) {
CLAMP(results[i], 0.0f, 1.0f);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
index 4b4b80ea1ad..c1543f791f1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.cc
@@ -80,7 +80,7 @@ class SeparateRGBFunction : public blender::fn::MultiFunction {
blender::MutableSpan<float> gs = params.uninitialized_single_output<float>(2, "G");
blender::MutableSpan<float> bs = params.uninitialized_single_output<float>(3, "B");
- for (uint i : mask) {
+ for (int64_t i : mask) {
blender::Color4f color = colors[i];
rs[i] = color.r;
gs[i] = color.g;
diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
index 03e18acc245..8b23327460f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_sepcombXYZ.cc
@@ -65,7 +65,7 @@ class MF_SeparateXYZ : public blender::fn::MultiFunction {
blender::MutableSpan<float> ys = params.uninitialized_single_output<float>(2, "Y");
blender::MutableSpan<float> zs = params.uninitialized_single_output<float>(3, "Z");
- for (uint i : mask) {
+ for (int64_t i : mask) {
blender::float3 xyz = vectors[i];
xs[i] = xyz.x;
ys[i] = xyz.y;
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index d2c4413b862..94ffbbe0c55 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -43,9 +43,9 @@ static void node_shader_init_tex_sky(bNodeTree *UNUSED(ntree), bNode *node)
tex->turbidity = 2.2f;
tex->ground_albedo = 0.3f;
tex->sun_disc = true;
- tex->sun_size = DEG2RADF(0.545);
+ tex->sun_size = DEG2RADF(0.545f);
tex->sun_intensity = 1.0f;
- tex->sun_elevation = M_PI_2;
+ tex->sun_elevation = DEG2RADF(15.0f);
tex->sun_rotation = 0.0f;
tex->altitude = 0.0f;
tex->air_density = 1.0f;
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
index 21f15bcf6f4..7f712b0db40 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
@@ -148,7 +148,7 @@ class ColorBandFunction : public blender::fn::MultiFunction {
params.uninitialized_single_output<blender::Color4f>(1, "Color");
blender::MutableSpan<float> alphas = params.uninitialized_single_output<float>(2, "Alpha");
- for (uint i : mask) {
+ for (int64_t i : mask) {
blender::Color4f color;
BKE_colorband_evaluate(&color_band_, values[i], color);
colors[i] = color;
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 18d4c7da534..5c6e0b0a308 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -21,6 +21,7 @@
#ifndef __BPY_EXTERN_H__
#define __BPY_EXTERN_H__
+struct AnimationEvalContext;
struct ChannelDriver; /* DNA_anim_types.h */
struct ID; /* DNA_ID.h */
struct ListBase; /* DNA_listBase.h */
@@ -117,7 +118,7 @@ void BPY_driver_reset(void);
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
struct ChannelDriver *driver,
struct ChannelDriver *driver_orig,
- const float evaltime);
+ const struct AnimationEvalContext *anim_eval_context);
void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr);
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 9b191ee5698..3d83eb90da6 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -33,19 +33,22 @@
#include "BLI_math_base.h"
#include "BLI_string.h"
+#include "BKE_animsys.h"
#include "BKE_fcurve_driver.h"
#include "BKE_global.h"
+#include "RNA_access.h"
+#include "RNA_types.h"
+
#include "bpy_rna_driver.h" /* for pyrna_driver_get_variable_value */
#include "bpy_intern_string.h"
#include "bpy_driver.h"
+#include "bpy_rna.h"
#include "BPY_extern.h"
-extern void BPY_update_rna_module(void);
-
#define USE_RNA_AS_PYOBJECT
#define USE_BYTECODE_WHITELIST
@@ -377,6 +380,37 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d
#endif /* USE_BYTECODE_WHITELIST */
+static PyObject *bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph)
+{
+ /* This should never happen, but it's probably better to have None in Python
+ * than a NULL-wrapping Depsgraph py struct. */
+ BLI_assert(depsgraph != NULL);
+ if (depsgraph == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ struct PointerRNA depsgraph_ptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr);
+ return pyrna_struct_CreatePyObject(&depsgraph_ptr);
+}
+
+/* Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated
+ * datablocks, and the current view layer and scene. See T75553. */
+static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars,
+ struct Depsgraph *depsgraph)
+{
+ PyObject *py_depsgraph = bpy_pydriver_depsgraph_as_pyobject(depsgraph);
+ const char *depsgraph_variable_name = "depsgraph";
+
+ if (PyDict_SetItemString(driver_vars, depsgraph_variable_name, py_depsgraph) == -1) {
+ fprintf(stderr,
+ "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n",
+ depsgraph_variable_name);
+ PyErr_Print();
+ PyErr_Clear();
+ }
+}
+
/* This evals py driver expressions, 'expr' is a Python expression that
* should evaluate to a float number, which is returned.
*
@@ -396,7 +430,7 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d
float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
- const float evaltime)
+ const AnimationEvalContext *anim_eval_context)
{
PyObject *driver_vars = NULL;
PyObject *retval = NULL;
@@ -456,7 +490,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
}
/* update global namespace */
- bpy_pydriver_namespace_update_frame(evaltime);
+ bpy_pydriver_namespace_update_frame(anim_eval_context->eval_time);
if (driver_orig->flag & DRIVER_FLAG_USE_SELF) {
bpy_pydriver_namespace_update_self(anim_rna);
@@ -589,6 +623,8 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
}
#endif /* USE_BYTECODE_WHITELIST */
+ bpy_pydriver_namespace_add_depsgraph(driver_vars, anim_eval_context->depsgraph);
+
#if 0 /* slow, with this can avoid all Py_CompileString above. */
/* execute expression to get a value */
retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars);
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 1c84e95672f..8aba2ae8598 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -36,6 +36,7 @@
#include "ED_keyframing.h"
#include "BKE_anim_data.h"
+#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
@@ -332,7 +333,20 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
&options) == -1) {
return NULL;
}
- else if (self->ptr.type == &RNA_NlaStrip) {
+
+ /* This assumes that keyframes are only added on original data & using the active depsgraph. If
+ * it turns out to be necessary for some reason to insert keyframes on evaluated objects, we can
+ * revisit this and add an explicit `depsgraph` keyword argument to the function call.
+ *
+ * It is unlikely that driver code (which is the reason this depsgraph pointer is obtained) will
+ * be executed from this function call, as this only happens when `options` has
+ * `INSERTKEY_DRIVER`, which is not exposed to Python. */
+ bContext *C = BPy_GetContext();
+ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
+ cfra);
+
+ if (self->ptr.type == &RNA_NlaStrip) {
/* Handle special properties for NLA Strips, whose F-Curves are stored on the
* strips themselves. These are stored separately or else the properties will
* not have any effect.
@@ -355,8 +369,8 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
if (prop) {
NlaStrip *strip = ptr.data;
FCurve *fcu = BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), index);
-
- result = insert_keyframe_direct(&reports, ptr, prop, fcu, cfra, keytype, NULL, options);
+ result = insert_keyframe_direct(
+ &reports, ptr, prop, fcu, &anim_eval_context, keytype, NULL, options);
}
else {
BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
@@ -384,7 +398,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
group_name,
path_full,
index,
- cfra,
+ &anim_eval_context,
keytype,
NULL,
options) != 0);
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 77a60854616..51eb290b0b8 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -60,6 +60,7 @@ struct bNodeTree;
#define RE_USE_SHADING_NODES_CUSTOM 64
#define RE_USE_SPHERICAL_STEREO 128
#define RE_USE_STEREO_VIEWPORT 256
+#define RE_USE_GPU_CONTEXT 512
/* RenderEngine.flag */
#define RE_ENGINE_ANIMATION 1
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 5391775cab8..633b9324d9f 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -624,10 +624,6 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
return;
}
-#ifdef WITH_PYTHON
- BPy_BEGIN_ALLOW_THREADS;
-#endif
-
Render *re = engine->re;
double cfra = (double)frame + (double)subframe;
@@ -636,10 +632,6 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
BKE_scene_graph_update_for_newframe(engine->depsgraph, re->main);
BKE_scene_camera_switch_update(re->scene);
-
-#ifdef WITH_PYTHON
- BPy_END_ALLOW_THREADS;
-#endif
}
/* Bake */
@@ -871,8 +863,16 @@ int RE_engine_render(Render *re, int do_all)
re->draw_lock(re->dlh, 0);
}
+ if (engine->type->flag & RE_USE_GPU_CONTEXT) {
+ DRW_render_context_enable(engine->re);
+ }
+
type->render(engine, engine->depsgraph);
+ if (engine->type->flag & RE_USE_GPU_CONTEXT) {
+ DRW_render_context_disable(engine->re);
+ }
+
/* Grease pencil render over previous render result.
*
* NOTE: External engine might have been requested to free its
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index b335862abe0..ade80898131 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2493,7 +2493,9 @@ void RE_RenderAnim(Render *re,
{
float ctime = BKE_scene_frame_get(scene);
AnimData *adt = BKE_animdata_from_id(&scene->id);
- BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, ADT_RECALC_ALL, false);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ re->pipeline_depsgraph, ctime);
+ BKE_animsys_evaluate_animdata(&scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false);
}
render_update_depsgraph(re);
diff --git a/source/blender/simulation/intern/particle_allocator.cc b/source/blender/simulation/intern/particle_allocator.cc
index b65c0197c76..eb1e998e63a 100644
--- a/source/blender/simulation/intern/particle_allocator.cc
+++ b/source/blender/simulation/intern/particle_allocator.cc
@@ -21,7 +21,7 @@ namespace blender::sim {
AttributesAllocator::~AttributesAllocator()
{
for (std::unique_ptr<AttributesBlock> &block : allocated_blocks_) {
- for (uint i : attributes_info_.index_range()) {
+ for (int i : attributes_info_.index_range()) {
const fn::CPPType &type = attributes_info_.type_of(i);
type.destruct_n(block->buffers[i], block->size);
MEM_freeN(block->buffers[i]);
@@ -29,13 +29,13 @@ AttributesAllocator::~AttributesAllocator()
}
}
-fn::MutableAttributesRef AttributesAllocator::allocate_uninitialized(uint size)
+fn::MutableAttributesRef AttributesAllocator::allocate_uninitialized(int size)
{
std::unique_ptr<AttributesBlock> block = std::make_unique<AttributesBlock>();
block->buffers = Array<void *>(attributes_info_.size(), nullptr);
block->size = size;
- for (uint i : attributes_info_.index_range()) {
+ for (int i : attributes_info_.index_range()) {
const fn::CPPType &type = attributes_info_.type_of(i);
void *buffer = MEM_mallocN_aligned(size * type.size(), type.alignment(), AT);
block->buffers[i] = buffer;
@@ -53,17 +53,17 @@ fn::MutableAttributesRef AttributesAllocator::allocate_uninitialized(uint size)
return attributes;
}
-fn::MutableAttributesRef ParticleAllocator::allocate(uint size)
+fn::MutableAttributesRef ParticleAllocator::allocate(int size)
{
const fn::AttributesInfo &info = attributes_allocator_.attributes_info();
fn::MutableAttributesRef attributes = attributes_allocator_.allocate_uninitialized(size);
- for (uint i : info.index_range()) {
+ for (int i : info.index_range()) {
const fn::CPPType &type = info.type_of(i);
StringRef name = info.name_of(i);
if (name == "ID") {
- uint start_id = next_id_.fetch_add(size);
+ int start_id = next_id_.fetch_add(size);
MutableSpan<int> ids = attributes.get<int>("ID");
- for (uint pindex : IndexRange(size)) {
+ for (int pindex : IndexRange(size)) {
ids[pindex] = start_id + pindex;
}
}
diff --git a/source/blender/simulation/intern/particle_allocator.hh b/source/blender/simulation/intern/particle_allocator.hh
index f854413c9aa..1e7578a75ed 100644
--- a/source/blender/simulation/intern/particle_allocator.hh
+++ b/source/blender/simulation/intern/particle_allocator.hh
@@ -31,13 +31,13 @@ class AttributesAllocator : NonCopyable, NonMovable {
private:
struct AttributesBlock {
Array<void *> buffers;
- uint size;
+ int size;
};
const fn::AttributesInfo &attributes_info_;
Vector<std::unique_ptr<AttributesBlock>> allocated_blocks_;
Vector<fn::MutableAttributesRef> allocated_attributes_;
- uint total_allocated_ = 0;
+ int total_allocated_ = 0;
std::mutex mutex_;
public:
@@ -53,7 +53,7 @@ class AttributesAllocator : NonCopyable, NonMovable {
return allocated_attributes_;
}
- uint total_allocated() const
+ int total_allocated() const
{
return total_allocated_;
}
@@ -63,31 +63,36 @@ class AttributesAllocator : NonCopyable, NonMovable {
return attributes_info_;
}
- fn::MutableAttributesRef allocate_uninitialized(uint size);
+ fn::MutableAttributesRef allocate_uninitialized(int size);
};
class ParticleAllocator : NonCopyable, NonMovable {
private:
AttributesAllocator attributes_allocator_;
- std::atomic<uint> next_id_;
+ std::atomic<int> next_id_;
public:
- ParticleAllocator(const fn::AttributesInfo &attributes_info, uint next_id)
+ ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id)
: attributes_allocator_(attributes_info), next_id_(next_id)
{
}
+ const fn::AttributesInfo &attributes_info() const
+ {
+ return attributes_allocator_.attributes_info();
+ }
+
Span<fn::MutableAttributesRef> get_allocations() const
{
return attributes_allocator_.get_allocations();
}
- uint total_allocated() const
+ int total_allocated() const
{
return attributes_allocator_.total_allocated();
}
- fn::MutableAttributesRef allocate(uint size);
+ fn::MutableAttributesRef allocate(int size);
};
} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc
index 3788fd17e36..e0de68d9b29 100644
--- a/source/blender/simulation/intern/particle_function.cc
+++ b/source/blender/simulation/intern/particle_function.cc
@@ -29,9 +29,9 @@ ParticleFunction::ParticleFunction(const fn::MultiFunction *global_fn,
per_particle_inputs_(per_particle_inputs),
output_is_global_(output_is_global)
{
- for (uint i : output_is_global_.index_range()) {
+ for (int i : output_is_global_.index_range()) {
if (output_is_global_[i]) {
- uint param_index = global_inputs_.size() + global_output_indices_.size();
+ int param_index = global_inputs_.size() + global_output_indices_.size();
fn::MFParamType param_type = global_fn_->param_type(param_index);
BLI_assert(param_type.is_output());
output_types_.append(param_type.data_type());
@@ -39,7 +39,7 @@ ParticleFunction::ParticleFunction(const fn::MultiFunction *global_fn,
global_output_indices_.append(i);
}
else {
- uint param_index = per_particle_inputs_.size() + per_particle_output_indices_.size();
+ int param_index = per_particle_inputs_.size() + per_particle_output_indices_.size();
fn::MFParamType param_type = per_particle_fn_->param_type(param_index);
BLI_assert(param_type.is_output());
output_types_.append(param_type.data_type());
@@ -60,7 +60,7 @@ ParticleFunctionEvaluator::ParticleFunctionEvaluator(
ParticleFunctionEvaluator::~ParticleFunctionEvaluator()
{
- for (uint output_index : outputs_.index_range()) {
+ for (int output_index : outputs_.index_range()) {
void *buffer = outputs_[output_index];
fn::MFDataType data_type = particle_fn_.output_types_[output_index];
BLI_assert(data_type.is_single()); /* For now. */
@@ -83,7 +83,7 @@ void ParticleFunctionEvaluator::compute()
is_computed_ = true;
}
-fn::GVSpan ParticleFunctionEvaluator::get(uint output_index, StringRef expected_name) const
+fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_name) const
{
#ifdef DEBUG
StringRef real_name = particle_fn_.output_names_[output_index];
@@ -115,7 +115,7 @@ void ParticleFunctionEvaluator::compute_globals()
}
/* Add output parameters. */
- for (uint output_index : particle_fn_.global_output_indices_) {
+ for (int output_index : particle_fn_.global_output_indices_) {
fn::MFDataType data_type = particle_fn_.output_types_[output_index];
BLI_assert(data_type.is_single()); /* For now. */
@@ -142,7 +142,7 @@ void ParticleFunctionEvaluator::compute_per_particle()
}
/* Add output parameters. */
- for (uint output_index : particle_fn_.per_particle_output_indices_) {
+ for (int output_index : particle_fn_.per_particle_output_indices_) {
fn::MFDataType data_type = particle_fn_.output_types_[output_index];
BLI_assert(data_type.is_single()); /* For now. */
diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh
index abed9063bae..bbb40efb388 100644
--- a/source/blender/simulation/intern/particle_function.hh
+++ b/source/blender/simulation/intern/particle_function.hh
@@ -41,8 +41,8 @@ class ParticleFunction {
Array<const ParticleFunctionInput *> global_inputs_;
Array<const ParticleFunctionInput *> per_particle_inputs_;
Array<bool> output_is_global_;
- Vector<uint> global_output_indices_;
- Vector<uint> per_particle_output_indices_;
+ Vector<int> global_output_indices_;
+ Vector<int> per_particle_output_indices_;
Vector<fn::MFDataType> output_types_;
Vector<StringRefNull> output_names_;
@@ -73,9 +73,9 @@ class ParticleFunctionEvaluator {
~ParticleFunctionEvaluator();
void compute();
- fn::GVSpan get(uint output_index, StringRef expected_name) const;
+ fn::GVSpan get(int output_index, StringRef expected_name) const;
- template<typename T> fn::VSpan<T> get(uint output_index, StringRef expected_name) const
+ template<typename T> fn::VSpan<T> get(int output_index, StringRef expected_name) const
{
return this->get(output_index, expected_name).typed<T>();
}
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc
index 98b055802c9..d4161b06a00 100644
--- a/source/blender/simulation/intern/simulation_collect_influences.cc
+++ b/source/blender/simulation/intern/simulation_collect_influences.cc
@@ -53,7 +53,7 @@ static Span<const nodes::DNode *> get_particle_simulation_nodes(const nodes::Der
static std::optional<Array<std::string>> compute_global_string_inputs(
nodes::MFNetworkTreeMap &network_map, Span<const fn::MFInputSocket *> sockets)
{
- uint amount = sockets.size();
+ int amount = sockets.size();
if (amount == 0) {
return Array<std::string>();
}
@@ -67,7 +67,7 @@ static std::optional<Array<std::string>> compute_global_string_inputs(
fn::MFParamsBuilder params{network_fn, 1};
Array<std::string> strings(amount, NoInitialization());
- for (uint i : IndexRange(amount)) {
+ for (int i : IndexRange(amount)) {
params.add_uninitialized_single_output(
fn::GMutableSpan(fn::CPPType::get<std::string>(), strings.data() + i, 1));
}
@@ -101,7 +101,7 @@ static void find_and_deduplicate_particle_attribute_nodes(nodes::MFNetworkTreeMa
Map<std::pair<std::string, fn::MFDataType>, Vector<fn::MFNode *>>
attribute_nodes_by_name_and_type;
- for (uint i : attribute_names->index_range()) {
+ for (int i : attribute_names->index_range()) {
attribute_nodes_by_name_and_type
.lookup_or_add_default(
{(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()})
@@ -207,7 +207,7 @@ class ParticleFunctionForce : public ParticleForce {
evaluator.compute();
fn::VSpan<float3> forces = evaluator.get<float3>(0, "Force");
- for (uint i : mask) {
+ for (int64_t i : mask) {
r_combined_force[i] += forces[i];
}
}
@@ -273,15 +273,17 @@ class MyBasicEmitter : public ParticleEmitter {
}
fn::MutableAttributesRef attributes = allocator->allocate(10);
- RandomNumberGenerator rng{(uint)context.simulation_time_interval().start() ^
- DefaultHash<std::string>{}(name_)};
+ RandomNumberGenerator rng{(uint32_t)context.simulation_time_interval().start() ^
+ (uint32_t)DefaultHash<std::string>{}(name_)};
MutableSpan<float3> positions = attributes.get<float3>("Position");
MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+ MutableSpan<float> birth_times = attributes.get<float>("Birth Time");
- for (uint i : IndexRange(attributes.size())) {
+ for (int i : IndexRange(attributes.size())) {
positions[i] = rng.get_unit_float3();
velocities[i] = rng.get_unit_float3();
+ birth_times[i] = context.simulation_time_interval().start();
}
}
};
@@ -307,6 +309,9 @@ static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network
builder.add<float3>("Position", {0, 0, 0});
builder.add<float3>("Velocity", {0, 0, 0});
builder.add<int>("ID", 0);
+ /* TODO: Use bool property, but need to add CD_PROP_BOOL first. */
+ builder.add<int>("Dead", 0);
+ builder.add<float>("Birth Time", 0.0f);
r_influences.particle_attributes_builder.add_new(std::move(name), &builder);
}
}
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc
index 310261f6c95..f542d6ab2c8 100644
--- a/source/blender/simulation/intern/simulation_solver.cc
+++ b/source/blender/simulation/intern/simulation_solver.cc
@@ -63,14 +63,14 @@ static const fn::CPPType &custom_to_cpp_data_type(CustomDataType type)
class CustomDataAttributesRef {
private:
Array<void *> buffers_;
- uint size_;
+ int64_t size_;
const fn::AttributesInfo &info_;
public:
- CustomDataAttributesRef(CustomData &custom_data, uint size, const fn::AttributesInfo &info)
+ CustomDataAttributesRef(CustomData &custom_data, int64_t size, const fn::AttributesInfo &info)
: buffers_(info.size(), nullptr), size_(size), info_(info)
{
- for (uint attribute_index : info.index_range()) {
+ for (int attribute_index : info.index_range()) {
StringRefNull name = info.name_of(attribute_index);
const fn::CPPType &cpp_type = info.type_of(attribute_index);
CustomDataType custom_type = cpp_to_custom_data_type(cpp_type);
@@ -108,7 +108,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At
}
} while (found_layer_to_remove);
- for (uint attribute_index : info.index_range()) {
+ for (int attribute_index : info.index_range()) {
StringRefNull attribute_name = info.name_of(attribute_index);
const fn::CPPType &cpp_type = info.type_of(attribute_index);
CustomDataType custom_type = cpp_to_custom_data_type(cpp_type);
@@ -120,12 +120,129 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At
nullptr,
state->tot_particles,
attribute_name.c_str());
- cpp_type.fill_uninitialized(
- info.default_of(attribute_index), data, (uint)state->tot_particles);
+ cpp_type.fill_uninitialized(info.default_of(attribute_index), data, state->tot_particles);
}
}
}
+BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ const fn::AttributesInfo &attributes_info)
+{
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, attributes_info};
+ fn::MutableAttributesRef attributes = custom_data_attributes;
+
+ Array<float3> force_vectors{state.tot_particles, {0, 0, 0}};
+ const Vector<const ParticleForce *> *forces =
+ solve_context.influences().particle_forces.lookup_ptr(state.head.name);
+
+ if (forces != nullptr) {
+ ParticleChunkContext particle_chunk_context{IndexMask(state.tot_particles), attributes};
+ ParticleForceContext particle_force_context{
+ solve_context, particle_chunk_context, force_vectors};
+
+ for (const ParticleForce *force : *forces) {
+ force->add_force(particle_force_context);
+ }
+ }
+
+ MutableSpan<float3> positions = attributes.get<float3>("Position");
+ MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+ MutableSpan<float> birth_times = attributes.get<float>("Birth Time");
+ MutableSpan<int> dead_states = attributes.get<int>("Dead");
+ float end_time = solve_context.solve_interval().end();
+ float time_step = solve_context.solve_interval().duration();
+ for (int i : positions.index_range()) {
+ velocities[i] += force_vectors[i] * time_step;
+ positions[i] += velocities[i] * time_step;
+
+ if (end_time - birth_times[i] > 2) {
+ dead_states[i] = true;
+ }
+ }
+}
+
+BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context,
+ ParticleAllocators &particle_allocators)
+{
+ for (const ParticleEmitter *emitter : solve_context.influences().particle_emitters) {
+ ParticleEmitterContext emitter_context{
+ solve_context, particle_allocators, solve_context.solve_interval()};
+ emitter->emit(emitter_context);
+ }
+}
+
+BLI_NOINLINE static int count_particles_after_time_step(ParticleSimulationState &state,
+ ParticleAllocator &allocator)
+{
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, allocator.attributes_info()};
+ fn::MutableAttributesRef attributes = custom_data_attributes;
+ int new_particle_amount = attributes.get<int>("Dead").count(0);
+
+ for (fn::MutableAttributesRef emitted_attributes : allocator.get_allocations()) {
+ new_particle_amount += emitted_attributes.get<int>("Dead").count(0);
+ }
+
+ return new_particle_amount;
+}
+
+BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationState &state,
+ ParticleAllocator &allocator)
+{
+ const int new_particle_amount = count_particles_after_time_step(state, allocator);
+
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, allocator.attributes_info()};
+
+ Vector<fn::MutableAttributesRef> particle_sources;
+ particle_sources.append(custom_data_attributes);
+ particle_sources.extend(allocator.get_allocations());
+
+ CustomDataLayer *dead_layer = nullptr;
+
+ for (CustomDataLayer &layer : MutableSpan(state.attributes.layers, state.attributes.totlayer)) {
+ StringRefNull name = layer.name;
+ if (name == "Dead") {
+ dead_layer = &layer;
+ continue;
+ }
+ const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type);
+ fn::GMutableSpan new_buffer{
+ cpp_type,
+ MEM_mallocN_aligned(new_particle_amount * cpp_type.size(), cpp_type.alignment(), AT),
+ new_particle_amount};
+
+ int current = 0;
+ for (fn::MutableAttributesRef attributes : particle_sources) {
+ Span<int> dead_states = attributes.get<int>("Dead");
+ fn::GSpan source_buffer = attributes.get(name);
+ BLI_assert(source_buffer.type() == cpp_type);
+ for (int i : attributes.index_range()) {
+ if (dead_states[i] == 0) {
+ cpp_type.copy_to_uninitialized(source_buffer[i], new_buffer[current]);
+ current++;
+ }
+ }
+ }
+
+ if (layer.data != nullptr) {
+ MEM_freeN(layer.data);
+ }
+ layer.data = new_buffer.buffer();
+ }
+
+ BLI_assert(dead_layer != nullptr);
+ if (dead_layer->data != nullptr) {
+ MEM_freeN(dead_layer->data);
+ }
+ dead_layer->data = MEM_callocN(sizeof(int) * new_particle_amount, AT);
+
+ state.tot_particles = new_particle_amount;
+ state.next_particle_id += allocator.total_allocated();
+}
+
void initialize_simulation_states(Simulation &simulation,
Depsgraph &UNUSED(depsgraph),
const SimulationInfluences &UNUSED(influences))
@@ -138,89 +255,47 @@ void solve_simulation_time_step(Simulation &simulation,
const SimulationInfluences &influences,
float time_step)
{
- SimulationSolveContext solve_context{simulation, depsgraph, influences};
+ SimulationSolveContext solve_context{
+ simulation,
+ depsgraph,
+ influences,
+ TimeInterval(simulation.current_simulation_time, time_step)};
TimeInterval simulation_time_interval{simulation.current_simulation_time, time_step};
+ Vector<SimulationState *> simulation_states{simulation.states};
+ Vector<ParticleSimulationState *> particle_simulation_states;
+ for (SimulationState *state : simulation_states) {
+ if (state->type == SIM_STATE_TYPE_PARTICLES) {
+ particle_simulation_states.append((ParticleSimulationState *)state);
+ }
+ }
+
Map<std::string, std::unique_ptr<fn::AttributesInfo>> attribute_infos;
- Map<std::string, std::unique_ptr<ParticleAllocator>> particle_allocators;
- LISTBASE_FOREACH (ParticleSimulationState *, state, &simulation.states) {
+ Map<std::string, std::unique_ptr<ParticleAllocator>> particle_allocators_map;
+ for (ParticleSimulationState *state : particle_simulation_states) {
const fn::AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as(
state->head.name);
auto info = std::make_unique<fn::AttributesInfo>(builder);
ensure_attributes_exist(state, *info);
- particle_allocators.add_new(
+ particle_allocators_map.add_new(
state->head.name, std::make_unique<ParticleAllocator>(*info, state->next_particle_id));
attribute_infos.add_new(state->head.name, std::move(info));
}
- LISTBASE_FOREACH (ParticleSimulationState *, state, &simulation.states) {
- const fn::AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name);
- CustomDataAttributesRef custom_data_attributes{
- state->attributes, (uint)state->tot_particles, attributes_info};
- fn::MutableAttributesRef attributes = custom_data_attributes;
-
- MutableSpan<float3> positions = attributes.get<float3>("Position");
- MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+ ParticleAllocators particle_allocators{particle_allocators_map};
- Array<float3> force_vectors{(uint)state->tot_particles, {0, 0, 0}};
- const Vector<const ParticleForce *> *forces = influences.particle_forces.lookup_ptr(
- state->head.name);
-
- if (forces != nullptr) {
- ParticleChunkContext particle_chunk_context{IndexMask((uint)state->tot_particles),
- attributes};
- ParticleForceContext particle_force_context{
- solve_context, particle_chunk_context, force_vectors};
-
- for (const ParticleForce *force : *forces) {
- force->add_force(particle_force_context);
- }
- }
-
- for (uint i : positions.index_range()) {
- velocities[i] += force_vectors[i] * time_step;
- positions[i] += velocities[i] * time_step;
- }
- }
-
- for (const ParticleEmitter *emitter : influences.particle_emitters) {
- ParticleEmitterContext emitter_context{
- solve_context, particle_allocators, simulation_time_interval};
- emitter->emit(emitter_context);
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ const fn::AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name);
+ simulate_existing_particles(solve_context, *state, attributes_info);
}
- LISTBASE_FOREACH (ParticleSimulationState *, state, &simulation.states) {
- const fn::AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name);
- ParticleAllocator &allocator = *particle_allocators.lookup_as(state->head.name);
-
- const uint emitted_particle_amount = allocator.total_allocated();
- const uint old_particle_amount = state->tot_particles;
- const uint new_particle_amount = old_particle_amount + emitted_particle_amount;
-
- CustomData_realloc(&state->attributes, new_particle_amount);
-
- CustomDataAttributesRef custom_data_attributes{
- state->attributes, new_particle_amount, attributes_info};
- fn::MutableAttributesRef attributes = custom_data_attributes;
-
- uint offset = old_particle_amount;
- for (fn::MutableAttributesRef emitted_attributes : allocator.get_allocations()) {
- fn::MutableAttributesRef dst_attributes = attributes.slice(
- IndexRange(offset, emitted_attributes.size()));
- for (uint attribute_index : attributes.info().index_range()) {
- fn::GMutableSpan emitted_data = emitted_attributes.get(attribute_index);
- fn::GMutableSpan dst = dst_attributes.get(attribute_index);
- const fn::CPPType &type = dst.type();
- type.copy_to_uninitialized_n(
- emitted_data.buffer(), dst.buffer(), emitted_attributes.size());
- }
- offset += emitted_attributes.size();
- }
+ run_emitters(solve_context, particle_allocators);
- state->tot_particles = new_particle_amount;
- state->next_particle_id += emitted_particle_amount;
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name);
+ remove_dead_and_add_new_particles(*state, allocator);
}
simulation.current_simulation_time = simulation_time_interval.end();
diff --git a/source/blender/simulation/intern/simulation_solver.hh b/source/blender/simulation/intern/simulation_solver.hh
index 7b37ed0583d..b5e42b53846 100644
--- a/source/blender/simulation/intern/simulation_solver.hh
+++ b/source/blender/simulation/intern/simulation_solver.hh
@@ -57,14 +57,51 @@ class SimulationSolveContext {
Simulation &simulation_;
Depsgraph &depsgraph_;
const SimulationInfluences &influences_;
+ TimeInterval solve_interval_;
public:
SimulationSolveContext(Simulation &simulation,
Depsgraph &depsgraph,
- const SimulationInfluences &influences)
- : simulation_(simulation), depsgraph_(depsgraph), influences_(influences)
+ const SimulationInfluences &influences,
+ TimeInterval solve_interval)
+ : simulation_(simulation),
+ depsgraph_(depsgraph),
+ influences_(influences),
+ solve_interval_(solve_interval)
{
}
+
+ TimeInterval solve_interval() const
+ {
+ return solve_interval_;
+ }
+
+ const SimulationInfluences &influences() const
+ {
+ return influences_;
+ }
+};
+
+class ParticleAllocators {
+ private:
+ Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators_;
+
+ public:
+ ParticleAllocators(Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators)
+ : allocators_(allocators)
+ {
+ }
+
+ ParticleAllocator *try_get_allocator(StringRef particle_simulation_name)
+ {
+ auto *ptr = allocators_.lookup_ptr_as(particle_simulation_name);
+ if (ptr != nullptr) {
+ return ptr->get();
+ }
+ else {
+ return nullptr;
+ }
+ }
};
class ParticleChunkContext {
@@ -97,12 +134,12 @@ class ParticleChunkContext {
class ParticleEmitterContext {
private:
SimulationSolveContext &solve_context_;
- Map<std::string, std::unique_ptr<ParticleAllocator>> &particle_allocators_;
+ ParticleAllocators &particle_allocators_;
TimeInterval simulation_time_interval_;
public:
ParticleEmitterContext(SimulationSolveContext &solve_context,
- Map<std::string, std::unique_ptr<ParticleAllocator>> &particle_allocators,
+ ParticleAllocators &particle_allocators,
TimeInterval simulation_time_interval)
: solve_context_(solve_context),
particle_allocators_(particle_allocators),
@@ -112,13 +149,7 @@ class ParticleEmitterContext {
ParticleAllocator *try_get_particle_allocator(StringRef particle_simulation_name)
{
- auto *ptr = particle_allocators_.lookup_ptr_as(particle_simulation_name);
- if (ptr != nullptr) {
- return ptr->get();
- }
- else {
- return nullptr;
- }
+ return particle_allocators_.try_get_allocator(particle_simulation_name);
}
TimeInterval simulation_time_interval() const
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index f0cd1add48b..d1f65b6271b 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2799,7 +2799,9 @@ static void radial_control_cancel(bContext *C, wmOperator *op)
* new value is displayed in sliders/numfields */
WM_event_add_notifier(C, NC_WINDOW, NULL);
- GPU_texture_free(rc->texture);
+ if (rc->texture != NULL) {
+ GPU_texture_free(rc->texture);
+ }
MEM_freeN(rc);
}
diff --git a/tests/gtests/blenlib/BLI_array_test.cc b/tests/gtests/blenlib/BLI_array_test.cc
index 3ff5baf1d94..c01ba26ffd7 100644
--- a/tests/gtests/blenlib/BLI_array_test.cc
+++ b/tests/gtests/blenlib/BLI_array_test.cc
@@ -9,21 +9,21 @@ namespace blender {
TEST(array, DefaultConstructor)
{
Array<int> array;
- EXPECT_EQ(array.size(), 0u);
+ EXPECT_EQ(array.size(), 0);
EXPECT_TRUE(array.is_empty());
}
TEST(array, SizeConstructor)
{
Array<int> array(5);
- EXPECT_EQ(array.size(), 5u);
+ EXPECT_EQ(array.size(), 5);
EXPECT_FALSE(array.is_empty());
}
TEST(array, FillConstructor)
{
Array<int> array(5, 8);
- EXPECT_EQ(array.size(), 5u);
+ EXPECT_EQ(array.size(), 5);
EXPECT_EQ(array[0], 8);
EXPECT_EQ(array[1], 8);
EXPECT_EQ(array[2], 8);
@@ -34,7 +34,7 @@ TEST(array, FillConstructor)
TEST(array, InitializerListConstructor)
{
Array<int> array = {4, 5, 6, 7};
- EXPECT_EQ(array.size(), 4u);
+ EXPECT_EQ(array.size(), 4);
EXPECT_EQ(array[0], 4);
EXPECT_EQ(array[1], 5);
EXPECT_EQ(array[2], 6);
@@ -46,7 +46,7 @@ TEST(array, SpanConstructor)
int stackarray[4] = {6, 7, 8, 9};
Span<int> span(stackarray, ARRAY_SIZE(stackarray));
Array<int> array(span);
- EXPECT_EQ(array.size(), 4u);
+ EXPECT_EQ(array.size(), 4);
EXPECT_EQ(array[0], 6);
EXPECT_EQ(array[1], 7);
EXPECT_EQ(array[2], 8);
@@ -58,8 +58,8 @@ TEST(array, CopyConstructor)
Array<int> array = {5, 6, 7, 8};
Array<int> new_array(array);
- EXPECT_EQ(array.size(), 4u);
- EXPECT_EQ(new_array.size(), 4u);
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(new_array.size(), 4);
EXPECT_NE(array.data(), new_array.data());
EXPECT_EQ(new_array[0], 5);
EXPECT_EQ(new_array[1], 6);
@@ -72,8 +72,8 @@ TEST(array, MoveConstructor)
Array<int> array = {5, 6, 7, 8};
Array<int> new_array(std::move(array));
- EXPECT_EQ(array.size(), 0u);
- EXPECT_EQ(new_array.size(), 4u);
+ EXPECT_EQ(array.size(), 0);
+ EXPECT_EQ(new_array.size(), 4);
EXPECT_EQ(new_array[0], 5);
EXPECT_EQ(new_array[1], 6);
EXPECT_EQ(new_array[2], 7);
@@ -84,10 +84,10 @@ TEST(array, CopyAssignment)
{
Array<int> array = {1, 2, 3};
Array<int> new_array = {4};
- EXPECT_EQ(new_array.size(), 1u);
+ EXPECT_EQ(new_array.size(), 1);
new_array = array;
- EXPECT_EQ(new_array.size(), 3u);
- EXPECT_EQ(array.size(), 3u);
+ EXPECT_EQ(new_array.size(), 3);
+ EXPECT_EQ(array.size(), 3);
EXPECT_NE(array.data(), new_array.data());
EXPECT_EQ(new_array[0], 1);
EXPECT_EQ(new_array[1], 2);
@@ -98,10 +98,10 @@ TEST(array, MoveAssignment)
{
Array<int> array = {1, 2, 3};
Array<int> new_array = {4};
- EXPECT_EQ(new_array.size(), 1u);
+ EXPECT_EQ(new_array.size(), 1);
new_array = std::move(array);
- EXPECT_EQ(new_array.size(), 3u);
- EXPECT_EQ(array.size(), 0u);
+ EXPECT_EQ(new_array.size(), 3);
+ EXPECT_EQ(array.size(), 0);
EXPECT_EQ(new_array[0], 1);
EXPECT_EQ(new_array[1], 2);
EXPECT_EQ(new_array[2], 3);
@@ -144,7 +144,7 @@ TEST(array, NoInitializationSizeConstructor)
memset(buffer, 100, sizeof(MyArray));
/* Doing this to avoid some compiler optimization. */
- for (uint i : IndexRange(sizeof(MyArray))) {
+ for (int64_t i : IndexRange(sizeof(MyArray))) {
EXPECT_EQ(((char *)buffer.ptr())[i], 100);
}
@@ -161,4 +161,16 @@ TEST(array, NoInitializationSizeConstructor)
}
}
+TEST(array, Fill)
+{
+ Array<int> array(5);
+ array.fill(3);
+ EXPECT_EQ(array.size(), 5u);
+ EXPECT_EQ(array[0], 3);
+ EXPECT_EQ(array[1], 3);
+ EXPECT_EQ(array[2], 3);
+ EXPECT_EQ(array[3], 3);
+ EXPECT_EQ(array[4], 3);
+}
+
} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_disjoint_set_test.cc b/tests/gtests/blenlib/BLI_disjoint_set_test.cc
index 30503954c62..22663b936d9 100644
--- a/tests/gtests/blenlib/BLI_disjoint_set_test.cc
+++ b/tests/gtests/blenlib/BLI_disjoint_set_test.cc
@@ -13,7 +13,7 @@ TEST(disjoint_set, Test)
EXPECT_FALSE(disjoint_set.in_same_set(1, 2));
EXPECT_FALSE(disjoint_set.in_same_set(5, 3));
EXPECT_TRUE(disjoint_set.in_same_set(2, 2));
- EXPECT_EQ(disjoint_set.find_root(3), 3u);
+ EXPECT_EQ(disjoint_set.find_root(3), 3);
disjoint_set.join(1, 2);
diff --git a/tests/gtests/blenlib/BLI_index_mask_test.cc b/tests/gtests/blenlib/BLI_index_mask_test.cc
index 6d9b7c70ab2..bce467cadd9 100644
--- a/tests/gtests/blenlib/BLI_index_mask_test.cc
+++ b/tests/gtests/blenlib/BLI_index_mask_test.cc
@@ -34,7 +34,7 @@ TEST(index_mask, RangeConstructor)
EXPECT_TRUE(mask.is_range());
EXPECT_EQ(mask.as_range().first(), 3);
EXPECT_EQ(mask.as_range().last(), 7);
- Span<uint> indices = mask.indices();
+ Span<int64_t> indices = mask.indices();
EXPECT_EQ(indices[0], 3);
EXPECT_EQ(indices[1], 4);
EXPECT_EQ(indices[2], 5);
diff --git a/tests/gtests/blenlib/BLI_index_range_test.cc b/tests/gtests/blenlib/BLI_index_range_test.cc
index 0f4fb7ef03b..1c4d4a1a1f3 100644
--- a/tests/gtests/blenlib/BLI_index_range_test.cc
+++ b/tests/gtests/blenlib/BLI_index_range_test.cc
@@ -10,42 +10,42 @@ namespace blender {
TEST(index_range, DefaultConstructor)
{
IndexRange range;
- EXPECT_EQ(range.size(), 0u);
+ EXPECT_EQ(range.size(), 0);
- Vector<uint> vector;
- for (uint value : range) {
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
vector.append(value);
}
- EXPECT_EQ(vector.size(), 0u);
+ EXPECT_EQ(vector.size(), 0);
}
TEST(index_range, SingleElementRange)
{
IndexRange range(4, 1);
- EXPECT_EQ(range.size(), 1u);
- EXPECT_EQ(*range.begin(), 4u);
+ EXPECT_EQ(range.size(), 1);
+ EXPECT_EQ(*range.begin(), 4);
- Vector<uint> vector;
- for (uint value : range) {
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
vector.append(value);
}
- EXPECT_EQ(vector.size(), 1u);
- EXPECT_EQ(vector[0], 4u);
+ EXPECT_EQ(vector.size(), 1);
+ EXPECT_EQ(vector[0], 4);
}
TEST(index_range, MultipleElementRange)
{
IndexRange range(6, 4);
- EXPECT_EQ(range.size(), 4u);
+ EXPECT_EQ(range.size(), 4);
- Vector<uint> vector;
- for (uint value : range) {
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
vector.append(value);
}
- EXPECT_EQ(vector.size(), 4u);
- for (uint i = 0; i < 4; i++) {
+ EXPECT_EQ(vector.size(), 4);
+ for (int i = 0; i < 4; i++) {
EXPECT_EQ(vector[i], i + 6);
}
}
@@ -53,28 +53,28 @@ TEST(index_range, MultipleElementRange)
TEST(index_range, SubscriptOperator)
{
IndexRange range(5, 5);
- EXPECT_EQ(range[0], 5u);
- EXPECT_EQ(range[1], 6u);
- EXPECT_EQ(range[2], 7u);
+ EXPECT_EQ(range[0], 5);
+ EXPECT_EQ(range[1], 6);
+ EXPECT_EQ(range[2], 7);
}
TEST(index_range, Before)
{
IndexRange range = IndexRange(5, 5).before(3);
- EXPECT_EQ(range[0], 2u);
- EXPECT_EQ(range[1], 3u);
- EXPECT_EQ(range[2], 4u);
- EXPECT_EQ(range.size(), 3u);
+ EXPECT_EQ(range[0], 2);
+ EXPECT_EQ(range[1], 3);
+ EXPECT_EQ(range[2], 4);
+ EXPECT_EQ(range.size(), 3);
}
TEST(index_range, After)
{
IndexRange range = IndexRange(5, 5).after(4);
- EXPECT_EQ(range[0], 10u);
- EXPECT_EQ(range[1], 11u);
- EXPECT_EQ(range[2], 12u);
- EXPECT_EQ(range[3], 13u);
- EXPECT_EQ(range.size(), 4u);
+ EXPECT_EQ(range[0], 10);
+ EXPECT_EQ(range[1], 11);
+ EXPECT_EQ(range[2], 12);
+ EXPECT_EQ(range[3], 13);
+ EXPECT_EQ(range.size(), 4);
}
TEST(index_range, Contains)
@@ -90,54 +90,54 @@ TEST(index_range, Contains)
TEST(index_range, First)
{
IndexRange range = IndexRange(5, 3);
- EXPECT_EQ(range.first(), 5u);
+ EXPECT_EQ(range.first(), 5);
}
TEST(index_range, Last)
{
IndexRange range = IndexRange(5, 3);
- EXPECT_EQ(range.last(), 7u);
+ EXPECT_EQ(range.last(), 7);
}
TEST(index_range, OneAfterEnd)
{
IndexRange range = IndexRange(5, 3);
- EXPECT_EQ(range.one_after_last(), 8u);
+ EXPECT_EQ(range.one_after_last(), 8);
}
TEST(index_range, Start)
{
IndexRange range = IndexRange(6, 2);
- EXPECT_EQ(range.start(), 6u);
+ EXPECT_EQ(range.start(), 6);
}
TEST(index_range, Slice)
{
IndexRange range = IndexRange(5, 15);
IndexRange slice = range.slice(2, 6);
- EXPECT_EQ(slice.size(), 6u);
- EXPECT_EQ(slice.first(), 7u);
- EXPECT_EQ(slice.last(), 12u);
+ EXPECT_EQ(slice.size(), 6);
+ EXPECT_EQ(slice.first(), 7);
+ EXPECT_EQ(slice.last(), 12);
}
TEST(index_range, SliceRange)
{
IndexRange range = IndexRange(5, 15);
IndexRange slice = range.slice(IndexRange(3, 5));
- EXPECT_EQ(slice.size(), 5u);
- EXPECT_EQ(slice.first(), 8u);
- EXPECT_EQ(slice.last(), 12u);
+ EXPECT_EQ(slice.size(), 5);
+ EXPECT_EQ(slice.first(), 8);
+ EXPECT_EQ(slice.last(), 12);
}
TEST(index_range, AsSpan)
{
IndexRange range = IndexRange(4, 6);
- Span<uint> span = range.as_span();
- EXPECT_EQ(span.size(), 6u);
- EXPECT_EQ(span[0], 4u);
- EXPECT_EQ(span[1], 5u);
- EXPECT_EQ(span[2], 6u);
- EXPECT_EQ(span[3], 7u);
+ Span<int64_t> span = range.as_span();
+ EXPECT_EQ(span.size(), 6);
+ EXPECT_EQ(span[0], 4);
+ EXPECT_EQ(span[1], 5);
+ EXPECT_EQ(span[2], 6);
+ EXPECT_EQ(span[3], 7);
}
} // namespace blender
diff --git a/tests/gtests/blenlib/BLI_linear_allocator_test.cc b/tests/gtests/blenlib/BLI_linear_allocator_test.cc
index 7ef9d433a4d..9c2dcdc7457 100644
--- a/tests/gtests/blenlib/BLI_linear_allocator_test.cc
+++ b/tests/gtests/blenlib/BLI_linear_allocator_test.cc
@@ -70,7 +70,7 @@ TEST(linear_allocator, AllocateArray)
LinearAllocator<> allocator;
MutableSpan<int> span = allocator.allocate_array<int>(5);
- EXPECT_EQ(span.size(), 5u);
+ EXPECT_EQ(span.size(), 5);
}
TEST(linear_allocator, Construct)
@@ -79,7 +79,7 @@ TEST(linear_allocator, Construct)
std::array<int, 5> values = {1, 2, 3, 4, 5};
Vector<int> *vector = allocator.construct<Vector<int>>(values);
- EXPECT_EQ(vector->size(), 5u);
+ EXPECT_EQ(vector->size(), 5);
EXPECT_EQ((*vector)[3], 4);
vector->~Vector();
}
@@ -92,8 +92,8 @@ TEST(linear_allocator, ConstructElementsAndPointerArray)
Span<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>(
5, values);
- EXPECT_EQ(vectors.size(), 5u);
- EXPECT_EQ(vectors[3]->size(), 7u);
+ EXPECT_EQ(vectors.size(), 5);
+ EXPECT_EQ(vectors[3]->size(), 7);
EXPECT_EQ((*vectors[2])[5], 6);
for (Vector<int> *vector : vectors) {
@@ -109,8 +109,8 @@ TEST(linear_allocator, ConstructArrayCopy)
MutableSpan<int> span1 = allocator.construct_array_copy(values.as_span());
MutableSpan<int> span2 = allocator.construct_array_copy(values.as_span());
EXPECT_NE(span1.data(), span2.data());
- EXPECT_EQ(span1.size(), 3u);
- EXPECT_EQ(span2.size(), 3u);
+ EXPECT_EQ(span1.size(), 3);
+ EXPECT_EQ(span2.size(), 3);
EXPECT_EQ(span1[1], 2);
EXPECT_EQ(span2[2], 3);
}
diff --git a/tests/gtests/blenlib/BLI_map_test.cc b/tests/gtests/blenlib/BLI_map_test.cc
index 4fb97c40e86..cebce218112 100644
--- a/tests/gtests/blenlib/BLI_map_test.cc
+++ b/tests/gtests/blenlib/BLI_map_test.cc
@@ -13,20 +13,20 @@ namespace blender {
TEST(map, DefaultConstructor)
{
Map<int, float> map;
- EXPECT_EQ(map.size(), 0u);
+ EXPECT_EQ(map.size(), 0);
EXPECT_TRUE(map.is_empty());
}
TEST(map, AddIncreasesSize)
{
Map<int, float> map;
- EXPECT_EQ(map.size(), 0u);
+ EXPECT_EQ(map.size(), 0);
EXPECT_TRUE(map.is_empty());
map.add(2, 5.0f);
- EXPECT_EQ(map.size(), 1u);
+ EXPECT_EQ(map.size(), 1);
EXPECT_FALSE(map.is_empty());
map.add(6, 2.0f);
- EXPECT_EQ(map.size(), 2u);
+ EXPECT_EQ(map.size(), 2);
EXPECT_FALSE(map.is_empty());
}
@@ -89,16 +89,16 @@ TEST(map, PopTry)
Map<int, int> map;
map.add(1, 5);
map.add(2, 7);
- EXPECT_EQ(map.size(), 2u);
+ EXPECT_EQ(map.size(), 2);
std::optional<int> value = map.pop_try(4);
- EXPECT_EQ(map.size(), 2u);
+ EXPECT_EQ(map.size(), 2);
EXPECT_FALSE(value.has_value());
value = map.pop_try(2);
- EXPECT_EQ(map.size(), 1u);
+ EXPECT_EQ(map.size(), 1);
EXPECT_TRUE(value.has_value());
EXPECT_EQ(*value, 7);
EXPECT_EQ(*map.pop_try(1), 5);
- EXPECT_EQ(map.size(), 0u);
+ EXPECT_EQ(map.size(), 0);
}
TEST(map, PopDefault)
@@ -107,17 +107,17 @@ TEST(map, PopDefault)
map.add(1, 4);
map.add(2, 7);
map.add(3, 8);
- EXPECT_EQ(map.size(), 3u);
+ EXPECT_EQ(map.size(), 3);
EXPECT_EQ(map.pop_default(4, 10), 10);
- EXPECT_EQ(map.size(), 3u);
+ EXPECT_EQ(map.size(), 3);
EXPECT_EQ(map.pop_default(1, 10), 4);
- EXPECT_EQ(map.size(), 2u);
+ EXPECT_EQ(map.size(), 2);
EXPECT_EQ(map.pop_default(2, 20), 7);
- EXPECT_EQ(map.size(), 1u);
+ EXPECT_EQ(map.size(), 1);
EXPECT_EQ(map.pop_default(2, 20), 20);
- EXPECT_EQ(map.size(), 1u);
+ EXPECT_EQ(map.size(), 1);
EXPECT_EQ(map.pop_default(3, 0), 8);
- EXPECT_EQ(map.size(), 0u);
+ EXPECT_EQ(map.size(), 0);
}
TEST(map, PopItemMany)
@@ -143,13 +143,13 @@ TEST(map, ValueIterator)
blender::Set<float> values;
- uint iterations = 0;
+ int iterations = 0;
for (float value : map.values()) {
values.add(value);
iterations++;
}
- EXPECT_EQ(iterations, 3u);
+ EXPECT_EQ(iterations, 3);
EXPECT_TRUE(values.contains(5.0f));
EXPECT_TRUE(values.contains(-2.0f));
EXPECT_TRUE(values.contains(2.0f));
@@ -164,13 +164,13 @@ TEST(map, KeyIterator)
blender::Set<int> keys;
- uint iterations = 0;
+ int iterations = 0;
for (int key : map.keys()) {
keys.add(key);
iterations++;
}
- EXPECT_EQ(iterations, 3u);
+ EXPECT_EQ(iterations, 3);
EXPECT_TRUE(keys.contains(1));
EXPECT_TRUE(keys.contains(2));
EXPECT_TRUE(keys.contains(6));
@@ -186,7 +186,7 @@ TEST(map, ItemIterator)
blender::Set<int> keys;
blender::Set<float> values;
- uint iterations = 0;
+ int iterations = 0;
const Map<int, float> &const_map = map;
for (auto item : const_map.items()) {
keys.add(item.key);
@@ -194,7 +194,7 @@ TEST(map, ItemIterator)
iterations++;
}
- EXPECT_EQ(iterations, 3u);
+ EXPECT_EQ(iterations, 3);
EXPECT_TRUE(keys.contains(5));
EXPECT_TRUE(keys.contains(2));
EXPECT_TRUE(keys.contains(1));
@@ -243,8 +243,8 @@ TEST(map, MutableItemToItemConversion)
values.append(item.value);
}
- EXPECT_EQ(keys.size(), 2u);
- EXPECT_EQ(values.size(), 2u);
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_EQ(values.size(), 2);
EXPECT_TRUE(keys.contains(3));
EXPECT_TRUE(keys.contains(2));
EXPECT_TRUE(values.contains(6));
@@ -332,10 +332,10 @@ TEST(map, MoveConstructorSmall)
map1.add(1, 2.0f);
map1.add(4, 1.0f);
Map<int, float> map2(std::move(map1));
- EXPECT_EQ(map2.size(), 2u);
+ EXPECT_EQ(map2.size(), 2);
EXPECT_EQ(map2.lookup(1), 2.0f);
EXPECT_EQ(map2.lookup(4), 1.0f);
- EXPECT_EQ(map1.size(), 0u);
+ EXPECT_EQ(map1.size(), 0);
EXPECT_EQ(map1.lookup_ptr(4), nullptr);
}
@@ -346,10 +346,10 @@ TEST(map, MoveConstructorLarge)
map1.add_new(i, i);
}
Map<int, int> map2(std::move(map1));
- EXPECT_EQ(map2.size(), 100u);
+ EXPECT_EQ(map2.size(), 100);
EXPECT_EQ(map2.lookup(1), 1);
EXPECT_EQ(map2.lookup(4), 4);
- EXPECT_EQ(map1.size(), 0u);
+ EXPECT_EQ(map1.size(), 0);
EXPECT_EQ(map1.lookup_ptr(4), nullptr);
}
@@ -360,10 +360,10 @@ TEST(map, MoveAssignment)
map1.add(4, 1.0f);
Map<int, float> map2;
map2 = std::move(map1);
- EXPECT_EQ(map2.size(), 2u);
+ EXPECT_EQ(map2.size(), 2);
EXPECT_EQ(map2.lookup(1), 2.0f);
EXPECT_EQ(map2.lookup(4), 1.0f);
- EXPECT_EQ(map1.size(), 0u);
+ EXPECT_EQ(map1.size(), 0);
EXPECT_EQ(map1.lookup_ptr(4), nullptr);
}
@@ -374,10 +374,10 @@ TEST(map, CopyAssignment)
map1.add(4, 1.0f);
Map<int, float> map2;
map2 = map1;
- EXPECT_EQ(map2.size(), 2u);
+ EXPECT_EQ(map2.size(), 2);
EXPECT_EQ(map2.lookup(1), 2.0f);
EXPECT_EQ(map2.lookup(4), 1.0f);
- EXPECT_EQ(map1.size(), 2u);
+ EXPECT_EQ(map1.size(), 2);
EXPECT_EQ(*map1.lookup_ptr(4), 1.0f);
}
@@ -387,13 +387,13 @@ TEST(map, Clear)
map.add(1, 1.0f);
map.add(2, 5.0f);
- EXPECT_EQ(map.size(), 2u);
+ EXPECT_EQ(map.size(), 2);
EXPECT_TRUE(map.contains(1));
EXPECT_TRUE(map.contains(2));
map.clear();
- EXPECT_EQ(map.size(), 0u);
+ EXPECT_EQ(map.size(), 0);
EXPECT_FALSE(map.contains(1));
EXPECT_FALSE(map.contains(2));
}
@@ -425,11 +425,11 @@ TEST(map, Remove)
{
Map<int, int> map;
map.add(2, 4);
- EXPECT_EQ(map.size(), 1u);
+ EXPECT_EQ(map.size(), 1);
EXPECT_FALSE(map.remove(3));
- EXPECT_EQ(map.size(), 1u);
+ EXPECT_EQ(map.size(), 1);
EXPECT_TRUE(map.remove(2));
- EXPECT_EQ(map.size(), 0u);
+ EXPECT_EQ(map.size(), 0);
}
TEST(map, PointerKeys)
@@ -441,7 +441,7 @@ TEST(map, PointerKeys)
EXPECT_FALSE(map.add(&a, 4));
map.add_new(&b, 1);
map.add_new(&c, 1);
- EXPECT_EQ(map.size(), 3u);
+ EXPECT_EQ(map.size(), 3);
EXPECT_TRUE(map.remove(&b));
EXPECT_TRUE(map.add(&b, 8));
EXPECT_FALSE(map.remove(&d));
@@ -473,8 +473,8 @@ TEST(map, ForeachItem)
values.append(value);
});
- EXPECT_EQ(keys.size(), 2u);
- EXPECT_EQ(values.size(), 2u);
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_EQ(values.size(), 2);
EXPECT_EQ(keys.first_index_of(3), values.first_index_of(4));
EXPECT_EQ(keys.first_index_of(1), values.first_index_of(8));
}
@@ -484,11 +484,11 @@ TEST(map, ForeachItem)
*/
#if 0
template<typename MapT>
-BLI_NOINLINE void benchmark_random_ints(StringRef name, uint amount, uint factor)
+BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
{
RNG *rng = BLI_rng_new(0);
Vector<int> values;
- for (uint i = 0; i < amount; i++) {
+ for (int i = 0; i < amount; i++) {
values.append(BLI_rng_get_int(rng) * factor);
}
BLI_rng_free(rng);
@@ -520,12 +520,12 @@ BLI_NOINLINE void benchmark_random_ints(StringRef name, uint amount, uint factor
TEST(map, Benchmark)
{
- for (uint i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, 1);
benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>("std::unordered_map", 1000000, 1);
}
std::cout << "\n";
- for (uint i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
uint32_t factor = (3 << 10);
benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, factor);
benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>(
diff --git a/tests/gtests/blenlib/BLI_set_test.cc b/tests/gtests/blenlib/BLI_set_test.cc
index 189f0c1b134..fcd958dc2f1 100644
--- a/tests/gtests/blenlib/BLI_set_test.cc
+++ b/tests/gtests/blenlib/BLI_set_test.cc
@@ -16,7 +16,7 @@ namespace blender {
TEST(set, DefaultConstructor)
{
Set<int> set;
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
EXPECT_TRUE(set.is_empty());
}
@@ -54,7 +54,7 @@ TEST(set, AddMany)
TEST(set, InitializerListConstructor)
{
Set<int> set = {4, 5, 6};
- EXPECT_EQ(set.size(), 3u);
+ EXPECT_EQ(set.size(), 3);
EXPECT_TRUE(set.contains(4));
EXPECT_TRUE(set.contains(5));
EXPECT_TRUE(set.contains(6));
@@ -79,10 +79,10 @@ TEST(set, CopyConstructor)
TEST(set, MoveConstructor)
{
Set<int> set = {1, 2, 3};
- EXPECT_EQ(set.size(), 3u);
+ EXPECT_EQ(set.size(), 3);
Set<int> set2(std::move(set));
- EXPECT_EQ(set.size(), 0u);
- EXPECT_EQ(set2.size(), 3u);
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set2.size(), 3);
}
TEST(set, CopyAssignment)
@@ -103,11 +103,11 @@ TEST(set, CopyAssignment)
TEST(set, MoveAssignment)
{
Set<int> set = {1, 2, 3};
- EXPECT_EQ(set.size(), 3u);
+ EXPECT_EQ(set.size(), 3);
Set<int> set2;
set2 = std::move(set);
- EXPECT_EQ(set.size(), 0u);
- EXPECT_EQ(set2.size(), 3u);
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_EQ(set2.size(), 3);
}
TEST(set, RemoveContained)
@@ -179,7 +179,7 @@ TEST(set, AddMultiple)
a.add_multiple({2, 4, 7});
EXPECT_TRUE(a.contains(4));
EXPECT_TRUE(a.contains(2));
- EXPECT_EQ(a.size(), 4u);
+ EXPECT_EQ(a.size(), 4);
}
TEST(set, AddMultipleNew)
@@ -197,7 +197,7 @@ TEST(set, Iterator)
for (int value : set) {
vec.append(value);
}
- EXPECT_EQ(vec.size(), 5u);
+ EXPECT_EQ(vec.size(), 5);
EXPECT_TRUE(vec.contains(1));
EXPECT_TRUE(vec.contains(3));
EXPECT_TRUE(vec.contains(2));
@@ -210,9 +210,9 @@ TEST(set, OftenAddRemoveContained)
Set<int> set;
for (int i = 0; i < 100; i++) {
set.add(42);
- EXPECT_EQ(set.size(), 1u);
+ EXPECT_EQ(set.size(), 1);
set.remove_contained(42);
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
}
}
@@ -224,15 +224,15 @@ TEST(set, UniquePtrValues)
set.add_new(std::move(value1));
set.add(std::unique_ptr<int>(new int()));
- EXPECT_EQ(set.size(), 3u);
+ EXPECT_EQ(set.size(), 3);
}
TEST(set, Clear)
{
Set<int> set = {3, 4, 6, 7};
- EXPECT_EQ(set.size(), 4u);
+ EXPECT_EQ(set.size(), 4);
set.clear();
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
}
TEST(set, StringSet)
@@ -240,7 +240,7 @@ TEST(set, StringSet)
Set<std::string> set;
set.add("hello");
set.add("world");
- EXPECT_EQ(set.size(), 2u);
+ EXPECT_EQ(set.size(), 2);
EXPECT_TRUE(set.contains("hello"));
EXPECT_TRUE(set.contains("world"));
EXPECT_FALSE(set.contains("world2"));
@@ -252,7 +252,7 @@ TEST(set, PointerSet)
Set<int *> set;
set.add(&a);
set.add(&b);
- EXPECT_EQ(set.size(), 2u);
+ EXPECT_EQ(set.size(), 2);
EXPECT_TRUE(set.contains(&a));
EXPECT_TRUE(set.contains(&b));
EXPECT_FALSE(set.contains(&c));
@@ -261,14 +261,14 @@ TEST(set, PointerSet)
TEST(set, Remove)
{
Set<int> set = {1, 2, 3, 4, 5, 6};
- EXPECT_EQ(set.size(), 6u);
+ EXPECT_EQ(set.size(), 6);
EXPECT_TRUE(set.remove(2));
- EXPECT_EQ(set.size(), 5u);
+ EXPECT_EQ(set.size(), 5);
EXPECT_FALSE(set.contains(2));
EXPECT_FALSE(set.remove(2));
- EXPECT_EQ(set.size(), 5u);
+ EXPECT_EQ(set.size(), 5);
EXPECT_TRUE(set.remove(5));
- EXPECT_EQ(set.size(), 4u);
+ EXPECT_EQ(set.size(), 4);
}
struct Type1 {
@@ -363,7 +363,7 @@ template<uint N> struct EqualityIntModN {
};
template<uint N> struct HashIntModN {
- uint32_t operator()(uint value) const
+ uint64_t operator()(uint value) const
{
return value % N;
}
@@ -409,7 +409,7 @@ struct MyKeyType {
uint32_t key;
int32_t attached_data;
- uint32_t hash() const
+ uint64_t hash() const
{
return key;
}
@@ -455,11 +455,11 @@ TEST(set, LookupKeyPtr)
*/
#if 0
template<typename SetT>
-BLI_NOINLINE void benchmark_random_ints(StringRef name, uint amount, uint factor)
+BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
{
RNG *rng = BLI_rng_new(0);
Vector<int> values;
- for (uint i = 0; i < amount; i++) {
+ for (int i = 0; i < amount; i++) {
values.append(BLI_rng_get_int(rng) * factor);
}
BLI_rng_free(rng);
@@ -491,12 +491,12 @@ BLI_NOINLINE void benchmark_random_ints(StringRef name, uint amount, uint factor
TEST(set, Benchmark)
{
- for (uint i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, 1);
benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, 1);
}
std::cout << "\n";
- for (uint i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
uint32_t factor = (3 << 10);
benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, factor);
benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, factor);
diff --git a/tests/gtests/blenlib/BLI_span_test.cc b/tests/gtests/blenlib/BLI_span_test.cc
index ccc63fd80eb..9c2e7cf26fb 100644
--- a/tests/gtests/blenlib/BLI_span_test.cc
+++ b/tests/gtests/blenlib/BLI_span_test.cc
@@ -11,7 +11,7 @@ TEST(span, FromSmallVector)
{
Vector<int> a = {1, 2, 3};
Span<int> a_span = a;
- EXPECT_EQ(a_span.size(), 3u);
+ EXPECT_EQ(a_span.size(), 3);
EXPECT_EQ(a_span[0], 1);
EXPECT_EQ(a_span[1], 2);
EXPECT_EQ(a_span[2], 3);
@@ -23,14 +23,14 @@ TEST(span, AddConstToPointer)
std::vector<int *> vec = {&a};
Span<int *> span = vec;
Span<const int *> const_span = span;
- EXPECT_EQ(const_span.size(), 1u);
+ EXPECT_EQ(const_span.size(), 1);
}
TEST(span, IsReferencing)
{
int array[] = {3, 5, 8};
MutableSpan<int> span(array, ARRAY_SIZE(array));
- EXPECT_EQ(span.size(), 3u);
+ EXPECT_EQ(span.size(), 3);
EXPECT_EQ(span[1], 5);
array[1] = 10;
EXPECT_EQ(span[1], 10);
@@ -40,7 +40,7 @@ TEST(span, DropBack)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_back(2);
- EXPECT_EQ(slice.size(), 2u);
+ EXPECT_EQ(slice.size(), 2);
EXPECT_EQ(slice[0], 4);
EXPECT_EQ(slice[1], 5);
}
@@ -49,14 +49,14 @@ TEST(span, DropBackAll)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_back(a.size());
- EXPECT_EQ(slice.size(), 0u);
+ EXPECT_EQ(slice.size(), 0);
}
TEST(span, DropFront)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_front(1);
- EXPECT_EQ(slice.size(), 3u);
+ EXPECT_EQ(slice.size(), 3);
EXPECT_EQ(slice[0], 5);
EXPECT_EQ(slice[1], 6);
EXPECT_EQ(slice[2], 7);
@@ -66,14 +66,14 @@ TEST(span, DropFrontAll)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).drop_front(a.size());
- EXPECT_EQ(slice.size(), 0u);
+ EXPECT_EQ(slice.size(), 0);
}
TEST(span, TakeFront)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).take_front(2);
- EXPECT_EQ(slice.size(), 2u);
+ EXPECT_EQ(slice.size(), 2);
EXPECT_EQ(slice[0], 4);
EXPECT_EQ(slice[1], 5);
}
@@ -82,7 +82,7 @@ TEST(span, TakeBack)
{
Vector<int> a = {5, 6, 7, 8};
auto slice = Span<int>(a).take_back(2);
- EXPECT_EQ(slice.size(), 2u);
+ EXPECT_EQ(slice.size(), 2);
EXPECT_EQ(slice[0], 7);
EXPECT_EQ(slice[1], 8);
}
@@ -91,7 +91,7 @@ TEST(span, Slice)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).slice(1, 2);
- EXPECT_EQ(slice.size(), 2u);
+ EXPECT_EQ(slice.size(), 2);
EXPECT_EQ(slice[0], 5);
EXPECT_EQ(slice[1], 6);
}
@@ -100,14 +100,14 @@ TEST(span, SliceEmpty)
{
Vector<int> a = {4, 5, 6, 7};
auto slice = Span<int>(a).slice(2, 0);
- EXPECT_EQ(slice.size(), 0u);
+ EXPECT_EQ(slice.size(), 0);
}
TEST(span, SliceRange)
{
Vector<int> a = {1, 2, 3, 4, 5};
auto slice = Span<int>(a).slice(IndexRange(2, 2));
- EXPECT_EQ(slice.size(), 2u);
+ EXPECT_EQ(slice.size(), 2);
EXPECT_EQ(slice[0], 3);
EXPECT_EQ(slice[1], 4);
}
@@ -128,16 +128,16 @@ TEST(span, Count)
{
Vector<int> a = {2, 3, 4, 3, 3, 2, 2, 2, 2};
Span<int> a_span = a;
- EXPECT_EQ(a_span.count(1), 0u);
- EXPECT_EQ(a_span.count(2), 5u);
- EXPECT_EQ(a_span.count(3), 3u);
- EXPECT_EQ(a_span.count(4), 1u);
- EXPECT_EQ(a_span.count(5), 0u);
+ EXPECT_EQ(a_span.count(1), 0);
+ EXPECT_EQ(a_span.count(2), 5);
+ EXPECT_EQ(a_span.count(3), 3);
+ EXPECT_EQ(a_span.count(4), 1);
+ EXPECT_EQ(a_span.count(5), 0);
}
static void test_ref_from_initializer_list(Span<int> span)
{
- EXPECT_EQ(span.size(), 4u);
+ EXPECT_EQ(span.size(), 4);
EXPECT_EQ(span[0], 3);
EXPECT_EQ(span[1], 6);
EXPECT_EQ(span[2], 8);
@@ -153,7 +153,7 @@ TEST(span, FromVector)
{
std::vector<int> a = {1, 2, 3, 4};
Span<int> a_span(a);
- EXPECT_EQ(a_span.size(), 4u);
+ EXPECT_EQ(a_span.size(), 4);
EXPECT_EQ(a_span[0], 1);
EXPECT_EQ(a_span[1], 2);
EXPECT_EQ(a_span[2], 3);
@@ -164,7 +164,7 @@ TEST(span, FromArray)
{
std::array<int, 2> a = {5, 6};
Span<int> a_span(a);
- EXPECT_EQ(a_span.size(), 2u);
+ EXPECT_EQ(a_span.size(), 2);
EXPECT_EQ(a_span[0], 5);
EXPECT_EQ(a_span[1], 6);
}
@@ -197,8 +197,8 @@ TEST(span, SizeInBytes)
{
std::array<int, 10> a;
Span<int> a_span(a);
- EXPECT_EQ(a_span.size_in_bytes(), sizeof(a));
- EXPECT_EQ(a_span.size_in_bytes(), 40u);
+ EXPECT_EQ(a_span.size_in_bytes(), (int64_t)sizeof(a));
+ EXPECT_EQ(a_span.size_in_bytes(), 40);
}
TEST(span, FirstLast)
@@ -246,9 +246,9 @@ TEST(span, FirstIndex)
std::array<int, 5> a = {4, 5, 4, 2, 5};
Span<int> a_span(a);
- EXPECT_EQ(a_span.first_index(4), 0u);
- EXPECT_EQ(a_span.first_index(5), 1u);
- EXPECT_EQ(a_span.first_index(2), 3u);
+ EXPECT_EQ(a_span.first_index(4), 0);
+ EXPECT_EQ(a_span.first_index(5), 1);
+ EXPECT_EQ(a_span.first_index(2), 3);
}
TEST(span, CastSameSize)
@@ -258,8 +258,8 @@ TEST(span, CastSameSize)
Span<int *> a_span = a;
Span<float *> new_a_span = a_span.cast<float *>();
- EXPECT_EQ(a_span.size(), 4u);
- EXPECT_EQ(new_a_span.size(), 4u);
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 4);
EXPECT_EQ(a_span[0], &value);
EXPECT_EQ(new_a_span[0], (float *)&value);
@@ -271,8 +271,8 @@ TEST(span, CastSmallerSize)
Span<uint32_t> a_span = a;
Span<uint16_t> new_a_span = a_span.cast<uint16_t>();
- EXPECT_EQ(a_span.size(), 4u);
- EXPECT_EQ(new_a_span.size(), 8u);
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 8);
}
TEST(span, CastLargerSize)
@@ -281,8 +281,8 @@ TEST(span, CastLargerSize)
Span<uint16_t> a_span = a;
Span<uint32_t> new_a_span = a_span.cast<uint32_t>();
- EXPECT_EQ(a_span.size(), 4u);
- EXPECT_EQ(new_a_span.size(), 2u);
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 2);
}
TEST(span, VoidPointerSpan)
@@ -291,7 +291,7 @@ TEST(span, VoidPointerSpan)
float b;
double c;
- auto func1 = [](Span<void *> span) { EXPECT_EQ(span.size(), 3u); };
+ auto func1 = [](Span<void *> span) { EXPECT_EQ(span.size(), 3); };
func1({&a, &b, &c});
}
diff --git a/tests/gtests/blenlib/BLI_stack_cxx_test.cc b/tests/gtests/blenlib/BLI_stack_cxx_test.cc
index c8433b4fd87..43b3dd8b3ae 100644
--- a/tests/gtests/blenlib/BLI_stack_cxx_test.cc
+++ b/tests/gtests/blenlib/BLI_stack_cxx_test.cc
@@ -10,7 +10,7 @@ namespace blender {
TEST(stack, DefaultConstructor)
{
Stack<int> stack;
- EXPECT_EQ(stack.size(), 0u);
+ EXPECT_EQ(stack.size(), 0);
EXPECT_TRUE(stack.is_empty());
}
@@ -18,7 +18,7 @@ TEST(stack, SpanConstructor)
{
std::array<int, 3> array = {4, 7, 2};
Stack<int> stack(array);
- EXPECT_EQ(stack.size(), 3u);
+ EXPECT_EQ(stack.size(), 3);
EXPECT_EQ(stack.pop(), 2);
EXPECT_EQ(stack.pop(), 7);
EXPECT_EQ(stack.pop(), 4);
@@ -29,8 +29,8 @@ TEST(stack, CopyConstructor)
{
Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
Stack<int> stack2 = stack1;
- EXPECT_EQ(stack1.size(), 7u);
- EXPECT_EQ(stack2.size(), 7u);
+ EXPECT_EQ(stack1.size(), 7);
+ EXPECT_EQ(stack2.size(), 7);
for (int i = 7; i >= 1; i--) {
EXPECT_FALSE(stack1.is_empty());
EXPECT_FALSE(stack2.is_empty());
@@ -45,8 +45,8 @@ TEST(stack, MoveConstructor)
{
Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
Stack<int> stack2 = std::move(stack1);
- EXPECT_EQ(stack1.size(), 0u);
- EXPECT_EQ(stack2.size(), 7u);
+ EXPECT_EQ(stack1.size(), 0);
+ EXPECT_EQ(stack2.size(), 7);
for (int i = 7; i >= 1; i--) {
EXPECT_EQ(stack2.pop(), i);
}
@@ -58,8 +58,8 @@ TEST(stack, CopyAssignment)
Stack<int> stack2 = {2, 3, 4, 5, 6, 7};
stack2 = stack1;
- EXPECT_EQ(stack1.size(), 7u);
- EXPECT_EQ(stack2.size(), 7u);
+ EXPECT_EQ(stack1.size(), 7);
+ EXPECT_EQ(stack2.size(), 7);
for (int i = 7; i >= 1; i--) {
EXPECT_FALSE(stack1.is_empty());
EXPECT_FALSE(stack2.is_empty());
@@ -75,8 +75,8 @@ TEST(stack, MoveAssignment)
Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
Stack<int> stack2 = {5, 3, 7, 2, 2};
stack2 = std::move(stack1);
- EXPECT_EQ(stack1.size(), 0u);
- EXPECT_EQ(stack2.size(), 7u);
+ EXPECT_EQ(stack1.size(), 0);
+ EXPECT_EQ(stack2.size(), 7);
for (int i = 7; i >= 1; i--) {
EXPECT_EQ(stack2.pop(), i);
}
@@ -85,19 +85,19 @@ TEST(stack, MoveAssignment)
TEST(stack, Push)
{
Stack<int> stack;
- EXPECT_EQ(stack.size(), 0u);
+ EXPECT_EQ(stack.size(), 0);
stack.push(3);
- EXPECT_EQ(stack.size(), 1u);
+ EXPECT_EQ(stack.size(), 1);
stack.push(5);
- EXPECT_EQ(stack.size(), 2u);
+ EXPECT_EQ(stack.size(), 2);
}
TEST(stack, PushMultiple)
{
Stack<int> stack;
- EXPECT_EQ(stack.size(), 0u);
+ EXPECT_EQ(stack.size(), 0);
stack.push_multiple({1, 2, 3});
- EXPECT_EQ(stack.size(), 3u);
+ EXPECT_EQ(stack.size(), 3);
EXPECT_EQ(stack.pop(), 3);
EXPECT_EQ(stack.pop(), 2);
EXPECT_EQ(stack.pop(), 1);
@@ -139,7 +139,7 @@ TEST(stack, PushMultipleAfterPop)
values.append(i);
}
stack.push_multiple(values);
- EXPECT_EQ(stack.size(), 5000u);
+ EXPECT_EQ(stack.size(), 5000);
for (int i = 4999; i >= 0; i--) {
EXPECT_EQ(stack.pop(), i);
diff --git a/tests/gtests/blenlib/BLI_string_ref_test.cc b/tests/gtests/blenlib/BLI_string_ref_test.cc
index 0d1880229c7..83099741c29 100644
--- a/tests/gtests/blenlib/BLI_string_ref_test.cc
+++ b/tests/gtests/blenlib/BLI_string_ref_test.cc
@@ -10,7 +10,7 @@ namespace blender {
TEST(string_ref_null, DefaultConstructor)
{
StringRefNull ref;
- EXPECT_EQ(ref.size(), 0u);
+ EXPECT_EQ(ref.size(), 0);
EXPECT_EQ(ref[0], '\0');
}
@@ -18,7 +18,7 @@ TEST(string_ref_null, CStringConstructor)
{
const char *str = "Hello";
StringRefNull ref(str);
- EXPECT_EQ(ref.size(), 5u);
+ EXPECT_EQ(ref.size(), 5);
EXPECT_EQ(ref.data(), str);
}
@@ -26,21 +26,21 @@ TEST(string_ref_null, CStringLengthConstructor)
{
const char *str = "Hello";
StringRefNull ref(str, 5);
- EXPECT_EQ(ref.size(), 5u);
+ EXPECT_EQ(ref.size(), 5);
EXPECT_EQ(ref.data(), str);
}
TEST(string_ref, DefaultConstructor)
{
StringRef ref;
- EXPECT_EQ(ref.size(), 0u);
+ EXPECT_EQ(ref.size(), 0);
}
TEST(string_ref, StartEndConstructor)
{
const char *text = "hello world";
StringRef ref(text, text + 5);
- EXPECT_EQ(ref.size(), 5u);
+ EXPECT_EQ(ref.size(), 5);
EXPECT_TRUE(ref == "hello");
EXPECT_FALSE(ref == "hello ");
}
@@ -48,7 +48,7 @@ TEST(string_ref, StartEndConstructor)
TEST(string_ref, StartEndConstructorNullptr)
{
StringRef ref(nullptr, nullptr);
- EXPECT_EQ(ref.size(), 0u);
+ EXPECT_EQ(ref.size(), 0);
EXPECT_TRUE(ref == "");
}
@@ -56,7 +56,7 @@ TEST(string_ref, StartEndConstructorSame)
{
const char *text = "hello world";
StringRef ref(text, text);
- EXPECT_EQ(ref.size(), 0u);
+ EXPECT_EQ(ref.size(), 0);
EXPECT_TRUE(ref == "");
}
@@ -64,7 +64,7 @@ TEST(string_ref, CStringConstructor)
{
const char *str = "Test";
StringRef ref(str);
- EXPECT_EQ(ref.size(), 4u);
+ EXPECT_EQ(ref.size(), 4);
EXPECT_EQ(ref.data(), str);
}
@@ -72,7 +72,7 @@ TEST(string_ref, PointerWithLengthConstructor)
{
const char *str = "Test";
StringRef ref(str, 2);
- EXPECT_EQ(ref.size(), 2u);
+ EXPECT_EQ(ref.size(), 2);
EXPECT_EQ(ref.data(), str);
}
@@ -80,14 +80,14 @@ TEST(string_ref, StdStringConstructor)
{
std::string str = "Test";
StringRef ref(str);
- EXPECT_EQ(ref.size(), 4u);
+ EXPECT_EQ(ref.size(), 4);
EXPECT_EQ(ref.data(), str.data());
}
TEST(string_ref, SubscriptOperator)
{
StringRef ref("hello");
- EXPECT_EQ(ref.size(), 5u);
+ EXPECT_EQ(ref.size(), 5);
EXPECT_EQ(ref[0], 'h');
EXPECT_EQ(ref[1], 'e');
EXPECT_EQ(ref[2], 'l');
@@ -99,7 +99,7 @@ TEST(string_ref, ToStdString)
{
StringRef ref("test");
std::string str = ref;
- EXPECT_EQ(str.size(), 4u);
+ EXPECT_EQ(str.size(), 4);
EXPECT_EQ(str, "test");
}
@@ -204,7 +204,7 @@ TEST(string_ref, Iterate)
for (char c : ref) {
chars.append(c);
}
- EXPECT_EQ(chars.size(), 4u);
+ EXPECT_EQ(chars.size(), 4);
EXPECT_EQ(chars[0], 't');
EXPECT_EQ(chars[1], 'e');
EXPECT_EQ(chars[2], 's');
@@ -240,8 +240,8 @@ TEST(string_ref, DropPrefixN)
StringRef ref("test");
StringRef ref2 = ref.drop_prefix(2);
StringRef ref3 = ref2.drop_prefix(2);
- EXPECT_EQ(ref2.size(), 2u);
- EXPECT_EQ(ref3.size(), 0u);
+ EXPECT_EQ(ref2.size(), 2);
+ EXPECT_EQ(ref3.size(), 0);
EXPECT_EQ(ref2, "st");
EXPECT_EQ(ref3, "");
}
@@ -250,7 +250,7 @@ TEST(string_ref, DropPrefix)
{
StringRef ref("test");
StringRef ref2 = ref.drop_prefix("tes");
- EXPECT_EQ(ref2.size(), 1u);
+ EXPECT_EQ(ref2.size(), 1);
EXPECT_EQ(ref2, "t");
}
diff --git a/tests/gtests/blenlib/BLI_vector_set_test.cc b/tests/gtests/blenlib/BLI_vector_set_test.cc
index 3c3b4d55959..116c4747c5a 100644
--- a/tests/gtests/blenlib/BLI_vector_set_test.cc
+++ b/tests/gtests/blenlib/BLI_vector_set_test.cc
@@ -9,14 +9,14 @@ namespace blender {
TEST(vector_set, DefaultConstructor)
{
VectorSet<int> set;
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
EXPECT_TRUE(set.is_empty());
}
TEST(vector_set, InitializerListConstructor_WithoutDuplicates)
{
VectorSet<int> set = {1, 4, 5};
- EXPECT_EQ(set.size(), 3u);
+ EXPECT_EQ(set.size(), 3);
EXPECT_EQ(set[0], 1);
EXPECT_EQ(set[1], 4);
EXPECT_EQ(set[2], 5);
@@ -25,7 +25,7 @@ TEST(vector_set, InitializerListConstructor_WithoutDuplicates)
TEST(vector_set, InitializerListConstructor_WithDuplicates)
{
VectorSet<int> set = {1, 3, 3, 2, 1, 5};
- EXPECT_EQ(set.size(), 4u);
+ EXPECT_EQ(set.size(), 4);
EXPECT_EQ(set[0], 1);
EXPECT_EQ(set[1], 3);
EXPECT_EQ(set[2], 2);
@@ -36,10 +36,10 @@ TEST(vector_set, Copy)
{
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = set1;
- EXPECT_EQ(set1.size(), 3u);
- EXPECT_EQ(set2.size(), 3u);
- EXPECT_EQ(set1.index_of(2), 1u);
- EXPECT_EQ(set2.index_of(2), 1u);
+ EXPECT_EQ(set1.size(), 3);
+ EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.index_of(2), 1);
+ EXPECT_EQ(set2.index_of(2), 1);
}
TEST(vector_set, CopyAssignment)
@@ -47,18 +47,18 @@ TEST(vector_set, CopyAssignment)
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = {};
set2 = set1;
- EXPECT_EQ(set1.size(), 3u);
- EXPECT_EQ(set2.size(), 3u);
- EXPECT_EQ(set1.index_of(2), 1u);
- EXPECT_EQ(set2.index_of(2), 1u);
+ EXPECT_EQ(set1.size(), 3);
+ EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.index_of(2), 1);
+ EXPECT_EQ(set2.index_of(2), 1);
}
TEST(vector_set, Move)
{
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = std::move(set1);
- EXPECT_EQ(set1.size(), 0u);
- EXPECT_EQ(set2.size(), 3u);
+ EXPECT_EQ(set1.size(), 0);
+ EXPECT_EQ(set2.size(), 3);
}
TEST(vector_set, MoveAssignment)
@@ -66,36 +66,36 @@ TEST(vector_set, MoveAssignment)
VectorSet<int> set1 = {1, 2, 3};
VectorSet<int> set2 = {};
set2 = std::move(set1);
- EXPECT_EQ(set1.size(), 0u);
- EXPECT_EQ(set2.size(), 3u);
+ EXPECT_EQ(set1.size(), 0);
+ EXPECT_EQ(set2.size(), 3);
}
TEST(vector_set, AddNewIncreasesSize)
{
VectorSet<int> set;
EXPECT_TRUE(set.is_empty());
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
set.add(5);
EXPECT_FALSE(set.is_empty());
- EXPECT_EQ(set.size(), 1u);
+ EXPECT_EQ(set.size(), 1);
}
TEST(vector_set, AddExistingDoesNotIncreaseSize)
{
VectorSet<int> set;
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
EXPECT_TRUE(set.add(5));
- EXPECT_EQ(set.size(), 1u);
+ EXPECT_EQ(set.size(), 1);
EXPECT_FALSE(set.add(5));
- EXPECT_EQ(set.size(), 1u);
+ EXPECT_EQ(set.size(), 1);
}
TEST(vector_set, Index)
{
VectorSet<int> set = {3, 6, 4};
- EXPECT_EQ(set.index_of(6), 1u);
- EXPECT_EQ(set.index_of(3), 0u);
- EXPECT_EQ(set.index_of(4), 2u);
+ EXPECT_EQ(set.index_of(6), 1);
+ EXPECT_EQ(set.index_of(3), 0);
+ EXPECT_EQ(set.index_of(4), 2);
}
TEST(vector_set, IndexTry)
@@ -110,21 +110,21 @@ TEST(vector_set, IndexTry)
TEST(vector_set, RemoveContained)
{
VectorSet<int> set = {4, 5, 6, 7};
- EXPECT_EQ(set.size(), 4u);
+ EXPECT_EQ(set.size(), 4);
set.remove_contained(5);
- EXPECT_EQ(set.size(), 3u);
+ EXPECT_EQ(set.size(), 3);
EXPECT_EQ(set[0], 4);
EXPECT_EQ(set[1], 7);
EXPECT_EQ(set[2], 6);
set.remove_contained(6);
- EXPECT_EQ(set.size(), 2u);
+ EXPECT_EQ(set.size(), 2);
EXPECT_EQ(set[0], 4);
EXPECT_EQ(set[1], 7);
set.remove_contained(4);
- EXPECT_EQ(set.size(), 1u);
+ EXPECT_EQ(set.size(), 1);
EXPECT_EQ(set[0], 7);
set.remove_contained(7);
- EXPECT_EQ(set.size(), 0u);
+ EXPECT_EQ(set.size(), 0);
}
TEST(vector_set, AddMultipleTimes)
diff --git a/tests/gtests/blenlib/BLI_vector_test.cc b/tests/gtests/blenlib/BLI_vector_test.cc
index 25435739a43..f581626d1ad 100644
--- a/tests/gtests/blenlib/BLI_vector_test.cc
+++ b/tests/gtests/blenlib/BLI_vector_test.cc
@@ -10,13 +10,13 @@ namespace blender {
TEST(vector, DefaultConstructor)
{
Vector<int> vec;
- EXPECT_EQ(vec.size(), 0u);
+ EXPECT_EQ(vec.size(), 0);
}
TEST(vector, SizeConstructor)
{
Vector<int> vec(3);
- EXPECT_EQ(vec.size(), 3u);
+ EXPECT_EQ(vec.size(), 3);
}
/**
@@ -42,7 +42,7 @@ TEST(vector, TrivialTypeSizeConstructor)
TEST(vector, SizeValueConstructor)
{
Vector<int> vec(4, 10);
- EXPECT_EQ(vec.size(), 4u);
+ EXPECT_EQ(vec.size(), 4);
EXPECT_EQ(vec[0], 10);
EXPECT_EQ(vec[1], 10);
EXPECT_EQ(vec[2], 10);
@@ -52,7 +52,7 @@ TEST(vector, SizeValueConstructor)
TEST(vector, InitializerListConstructor)
{
Vector<int> vec = {1, 3, 4, 6};
- EXPECT_EQ(vec.size(), 4u);
+ EXPECT_EQ(vec.size(), 4);
EXPECT_EQ(vec[0], 1);
EXPECT_EQ(vec[1], 3);
EXPECT_EQ(vec[2], 4);
@@ -63,7 +63,7 @@ TEST(vector, ConvertingConstructor)
{
std::array<float, 5> values = {5.4f, 7.3f, -8.1f, 5.0f, 0.0f};
Vector<int> vec = values;
- EXPECT_EQ(vec.size(), 5u);
+ EXPECT_EQ(vec.size(), 5);
EXPECT_EQ(vec[0], 5);
EXPECT_EQ(vec[1], 7);
EXPECT_EQ(vec[2], -8);
@@ -88,7 +88,7 @@ TEST(vector, ListBaseConstructor)
BLI_addtail(&list, value3);
Vector<TestListValue *> vec(list);
- EXPECT_EQ(vec.size(), 3u);
+ EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0]->value, 4);
EXPECT_EQ(vec[1]->value, 5);
EXPECT_EQ(vec[2]->value, 6);
@@ -106,7 +106,7 @@ TEST(vector, ContainerConstructor)
list.push_front(5);
Vector<int> vec = Vector<int>::FromContainer(list);
- EXPECT_EQ(vec.size(), 3u);
+ EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0], 5);
EXPECT_EQ(vec[1], 1);
EXPECT_EQ(vec[2], 3);
@@ -116,7 +116,7 @@ TEST(vector, CopyConstructor)
{
Vector<int> vec1 = {1, 2, 3};
Vector<int> vec2(vec1);
- EXPECT_EQ(vec2.size(), 3u);
+ EXPECT_EQ(vec2.size(), 3);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
EXPECT_EQ(vec2[2], 3);
@@ -131,8 +131,8 @@ TEST(vector, CopyConstructor2)
Vector<int, 2> vec1 = {1, 2, 3, 4};
Vector<int, 3> vec2(vec1);
- EXPECT_EQ(vec1.size(), 4u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_NE(vec1.data(), vec2.data());
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
@@ -145,8 +145,8 @@ TEST(vector, CopyConstructor3)
Vector<int, 20> vec1 = {1, 2, 3, 4};
Vector<int, 1> vec2(vec1);
- EXPECT_EQ(vec1.size(), 4u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_NE(vec1.data(), vec2.data());
EXPECT_EQ(vec2[2], 3);
}
@@ -156,8 +156,8 @@ TEST(vector, CopyConstructor4)
Vector<int, 5> vec1 = {1, 2, 3, 4};
Vector<int, 6> vec2(vec1);
- EXPECT_EQ(vec1.size(), 4u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_NE(vec1.data(), vec2.data());
EXPECT_EQ(vec2[3], 4);
}
@@ -167,8 +167,8 @@ TEST(vector, MoveConstructor)
Vector<int> vec1 = {1, 2, 3, 4};
Vector<int> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 0);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
EXPECT_EQ(vec2[2], 3);
@@ -180,8 +180,8 @@ TEST(vector, MoveConstructor2)
Vector<int, 2> vec1 = {1, 2, 3, 4};
Vector<int, 3> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 0);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_EQ(vec2[0], 1);
EXPECT_EQ(vec2[1], 2);
EXPECT_EQ(vec2[2], 3);
@@ -193,8 +193,8 @@ TEST(vector, MoveConstructor3)
Vector<int, 20> vec1 = {1, 2, 3, 4};
Vector<int, 1> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 0);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_EQ(vec2[2], 3);
}
@@ -203,20 +203,20 @@ TEST(vector, MoveConstructor4)
Vector<int, 5> vec1 = {1, 2, 3, 4};
Vector<int, 6> vec2(std::move(vec1));
- EXPECT_EQ(vec1.size(), 0u);
- EXPECT_EQ(vec2.size(), 4u);
+ EXPECT_EQ(vec1.size(), 0);
+ EXPECT_EQ(vec2.size(), 4);
EXPECT_EQ(vec2[3], 4);
}
TEST(vector, MoveAssignment)
{
Vector<int> vec = {1, 2};
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
EXPECT_EQ(vec[0], 1);
EXPECT_EQ(vec[1], 2);
vec = Vector<int>({5});
- EXPECT_EQ(vec.size(), 1u);
+ EXPECT_EQ(vec.size(), 1);
EXPECT_EQ(vec[0], 5);
}
@@ -224,11 +224,11 @@ TEST(vector, CopyAssignment)
{
Vector<int> vec1 = {1, 2, 3};
Vector<int> vec2 = {4, 5};
- EXPECT_EQ(vec1.size(), 3u);
- EXPECT_EQ(vec2.size(), 2u);
+ EXPECT_EQ(vec1.size(), 3);
+ EXPECT_EQ(vec2.size(), 2);
vec2 = vec1;
- EXPECT_EQ(vec2.size(), 3u);
+ EXPECT_EQ(vec2.size(), 3);
vec1[0] = 7;
EXPECT_EQ(vec1[0], 7);
@@ -241,7 +241,7 @@ TEST(vector, Append)
vec.append(3);
vec.append(6);
vec.append(7);
- EXPECT_EQ(vec.size(), 3u);
+ EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0], 3);
EXPECT_EQ(vec[1], 6);
EXPECT_EQ(vec[2], 7);
@@ -250,56 +250,33 @@ TEST(vector, Append)
TEST(vector, AppendAndGetIndex)
{
Vector<int> vec;
- EXPECT_EQ(vec.append_and_get_index(10), 0u);
- EXPECT_EQ(vec.append_and_get_index(10), 1u);
- EXPECT_EQ(vec.append_and_get_index(10), 2u);
+ EXPECT_EQ(vec.append_and_get_index(10), 0);
+ EXPECT_EQ(vec.append_and_get_index(10), 1);
+ EXPECT_EQ(vec.append_and_get_index(10), 2);
vec.append(10);
- EXPECT_EQ(vec.append_and_get_index(10), 4u);
+ EXPECT_EQ(vec.append_and_get_index(10), 4);
}
TEST(vector, AppendNonDuplicates)
{
Vector<int> vec;
vec.append_non_duplicates(4);
- EXPECT_EQ(vec.size(), 1u);
+ EXPECT_EQ(vec.size(), 1);
vec.append_non_duplicates(5);
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
vec.append_non_duplicates(4);
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
}
TEST(vector, ExtendNonDuplicates)
{
Vector<int> vec;
vec.extend_non_duplicates({1, 2});
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
vec.extend_non_duplicates({3, 4});
- EXPECT_EQ(vec.size(), 4u);
+ EXPECT_EQ(vec.size(), 4);
vec.extend_non_duplicates({0, 1, 2, 3});
- EXPECT_EQ(vec.size(), 5u);
-}
-
-TEST(vector, Fill)
-{
- Vector<int> vec(5);
- vec.fill(3);
- EXPECT_EQ(vec.size(), 5u);
- EXPECT_EQ(vec[0], 3);
- EXPECT_EQ(vec[1], 3);
- EXPECT_EQ(vec[2], 3);
- EXPECT_EQ(vec[3], 3);
- EXPECT_EQ(vec[4], 3);
-}
-
-TEST(vector, FillIndices)
-{
- Vector<int> vec(5, 0);
- vec.fill_indices({1, 2}, 4);
- EXPECT_EQ(vec[0], 0);
- EXPECT_EQ(vec[1], 4);
- EXPECT_EQ(vec[2], 4);
- EXPECT_EQ(vec[3], 0);
- EXPECT_EQ(vec[4], 0);
+ EXPECT_EQ(vec.size(), 5);
}
TEST(vector, Iterator)
@@ -318,8 +295,8 @@ TEST(vector, BecomeLarge)
for (int i = 0; i < 100; i++) {
vec.append(i * 5);
}
- EXPECT_EQ(vec.size(), 100u);
- for (uint i = 0; i < 100; i++) {
+ EXPECT_EQ(vec.size(), 100);
+ for (int i = 0; i < 100; i++) {
EXPECT_EQ(vec[i], static_cast<int>(i * 5));
}
}
@@ -332,7 +309,7 @@ static Vector<int> return_by_value_helper()
TEST(vector, ReturnByValue)
{
Vector<int> vec = return_by_value_helper();
- EXPECT_EQ(vec.size(), 3u);
+ EXPECT_EQ(vec.size(), 3);
EXPECT_EQ(vec[0], 3);
EXPECT_EQ(vec[1], 5);
EXPECT_EQ(vec[2], 1);
@@ -341,39 +318,26 @@ TEST(vector, ReturnByValue)
TEST(vector, VectorOfVectors_Append)
{
Vector<Vector<int>> vec;
- EXPECT_EQ(vec.size(), 0u);
+ EXPECT_EQ(vec.size(), 0);
Vector<int> v({1, 2});
vec.append(v);
vec.append({7, 8});
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
EXPECT_EQ(vec[0][0], 1);
EXPECT_EQ(vec[0][1], 2);
EXPECT_EQ(vec[1][0], 7);
EXPECT_EQ(vec[1][1], 8);
}
-TEST(vector, VectorOfVectors_Fill)
-{
- Vector<Vector<int>> vec(3);
- vec.fill({4, 5});
-
- EXPECT_EQ(vec[0][0], 4);
- EXPECT_EQ(vec[0][1], 5);
- EXPECT_EQ(vec[1][0], 4);
- EXPECT_EQ(vec[1][1], 5);
- EXPECT_EQ(vec[2][0], 4);
- EXPECT_EQ(vec[2][1], 5);
-}
-
TEST(vector, RemoveLast)
{
Vector<int> vec = {5, 6};
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
vec.remove_last();
- EXPECT_EQ(vec.size(), 1u);
+ EXPECT_EQ(vec.size(), 1);
vec.remove_last();
- EXPECT_EQ(vec.size(), 0u);
+ EXPECT_EQ(vec.size(), 0);
}
TEST(vector, IsEmpty)
@@ -415,7 +379,7 @@ TEST(vector, RemoveFirstOccurrenceAndReorder)
vec.remove_first_occurrence_and_reorder(4);
EXPECT_EQ(vec[0], 7);
vec.remove_first_occurrence_and_reorder(7);
- EXPECT_EQ(vec.size(), 0u);
+ EXPECT_EQ(vec.size(), 0);
}
TEST(vector, Remove)
@@ -440,7 +404,7 @@ TEST(vector, ExtendSmallVector)
Vector<int> a = {2, 3, 4};
Vector<int> b = {11, 12};
b.extend(a);
- EXPECT_EQ(b.size(), 5u);
+ EXPECT_EQ(b.size(), 5);
EXPECT_EQ(b[0], 11);
EXPECT_EQ(b[1], 12);
EXPECT_EQ(b[2], 2);
@@ -455,7 +419,7 @@ TEST(vector, ExtendArray)
Vector<int> a;
a.extend(array, 2);
- EXPECT_EQ(a.size(), 2u);
+ EXPECT_EQ(a.size(), 2);
EXPECT_EQ(a[0], 3);
EXPECT_EQ(a[1], 4);
}
@@ -471,7 +435,7 @@ TEST(vector, AppendNTimes)
Vector<int> a;
a.append_n_times(5, 3);
a.append_n_times(2, 2);
- EXPECT_EQ(a.size(), 5u);
+ EXPECT_EQ(a.size(), 5);
EXPECT_EQ(a[0], 5);
EXPECT_EQ(a[1], 5);
EXPECT_EQ(a[2], 5);
@@ -486,13 +450,13 @@ TEST(vector, UniquePtrValue)
vec.append(std::unique_ptr<int>(new int()));
vec.append(std::unique_ptr<int>(new int()));
vec.append(std::unique_ptr<int>(new int()));
- EXPECT_EQ(vec.size(), 4u);
+ EXPECT_EQ(vec.size(), 4);
std::unique_ptr<int> &a = vec.last();
std::unique_ptr<int> b = vec.pop_last();
vec.remove_and_reorder(0);
vec.remove(0);
- EXPECT_EQ(vec.size(), 1u);
+ EXPECT_EQ(vec.size(), 1);
UNUSED_VARS(a, b);
}
@@ -607,29 +571,29 @@ TEST(vector, Resize)
{
std::string long_string = "012345678901234567890123456789";
Vector<std::string> vec;
- EXPECT_EQ(vec.size(), 0u);
+ EXPECT_EQ(vec.size(), 0);
vec.resize(2);
- EXPECT_EQ(vec.size(), 2u);
+ EXPECT_EQ(vec.size(), 2);
EXPECT_EQ(vec[0], "");
EXPECT_EQ(vec[1], "");
vec.resize(5, long_string);
- EXPECT_EQ(vec.size(), 5u);
+ EXPECT_EQ(vec.size(), 5);
EXPECT_EQ(vec[0], "");
EXPECT_EQ(vec[1], "");
EXPECT_EQ(vec[2], long_string);
EXPECT_EQ(vec[3], long_string);
EXPECT_EQ(vec[4], long_string);
vec.resize(1);
- EXPECT_EQ(vec.size(), 1u);
+ EXPECT_EQ(vec.size(), 1);
EXPECT_EQ(vec[0], "");
}
TEST(vector, FirstIndexOf)
{
Vector<int> vec = {2, 3, 5, 7, 5, 9};
- EXPECT_EQ(vec.first_index_of(2), 0u);
- EXPECT_EQ(vec.first_index_of(5), 2u);
- EXPECT_EQ(vec.first_index_of(9), 5u);
+ EXPECT_EQ(vec.first_index_of(2), 0);
+ EXPECT_EQ(vec.first_index_of(5), 2);
+ EXPECT_EQ(vec.first_index_of(9), 5);
}
TEST(vector, FirstIndexTryOf)
@@ -657,7 +621,19 @@ TEST(vector, ConstructVoidPointerVector)
float b;
double c;
Vector<void *> vec = {&a, &b, &c};
- EXPECT_EQ(vec.size(), 3u);
+ EXPECT_EQ(vec.size(), 3);
+}
+
+TEST(vector, Fill)
+{
+ Vector<int> vec(5);
+ vec.fill(3);
+ EXPECT_EQ(vec.size(), 5u);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 3);
+ EXPECT_EQ(vec[2], 3);
+ EXPECT_EQ(vec[3], 3);
+ EXPECT_EQ(vec[4], 3);
}
} // namespace blender
diff --git a/tests/gtests/functions/FN_array_spans_test.cc b/tests/gtests/functions/FN_array_spans_test.cc
index 6912a62ff17..6b7bb8429ff 100644
--- a/tests/gtests/functions/FN_array_spans_test.cc
+++ b/tests/gtests/functions/FN_array_spans_test.cc
@@ -50,7 +50,7 @@ TEST(virtual_array_span, MultipleArrayConstructor)
std::array<int, 2> values1 = {6, 7};
std::array<int, 1> values2 = {8};
std::array<const int *, 3> starts = {values0.data(), values1.data(), values2.data()};
- std::array<uint, 3> sizes{values0.size(), values1.size(), values2.size()};
+ std::array<int64_t, 3> sizes{values0.size(), values1.size(), values2.size()};
VArraySpan<int> span{starts, sizes};
EXPECT_EQ(span.size(), 3);
diff --git a/tests/gtests/functions/FN_attributes_ref_test.cc b/tests/gtests/functions/FN_attributes_ref_test.cc
index 0b0afdc210f..9c7cce83493 100644
--- a/tests/gtests/functions/FN_attributes_ref_test.cc
+++ b/tests/gtests/functions/FN_attributes_ref_test.cc
@@ -58,7 +58,7 @@ TEST(mutable_attributes_ref, ComplexTest)
info_builder.add<std::string>("Name", "<no name>");
AttributesInfo info{info_builder};
- uint amount = 5;
+ int amount = 5;
Array<float3> positions(amount);
Array<uint> ids(amount, 0);
Array<float> sizes(amount);
diff --git a/tests/gtests/functions/FN_cpp_type_test.cc b/tests/gtests/functions/FN_cpp_type_test.cc
index 78731f9c987..85fc1105c25 100644
--- a/tests/gtests/functions/FN_cpp_type_test.cc
+++ b/tests/gtests/functions/FN_cpp_type_test.cc
@@ -67,7 +67,7 @@ struct TestType {
return false;
}
- uint32_t hash() const
+ uint64_t hash() const
{
return 0;
}
diff --git a/tests/gtests/functions/FN_multi_function_network_test.cc b/tests/gtests/functions/FN_multi_function_network_test.cc
index 35af8300cfa..9f16b71bb10 100644
--- a/tests/gtests/functions/FN_multi_function_network_test.cc
+++ b/tests/gtests/functions/FN_multi_function_network_test.cc
@@ -78,7 +78,7 @@ class ConcatVectorsFunction : public MultiFunction {
GVectorArrayRef<int> a = params.vector_mutable<int>(0);
VArraySpan<int> b = params.readonly_vector_input<int>(1);
- for (uint i : mask) {
+ for (int64_t i : mask) {
a.extend(i, b[i]);
}
}
@@ -98,7 +98,7 @@ class AppendFunction : public MultiFunction {
GVectorArrayRef<int> vectors = params.vector_mutable<int>(0);
VSpan<int> values = params.readonly_single_input<int>(1);
- for (uint i : mask) {
+ for (int64_t i : mask) {
vectors.append(i, values[i]);
}
}
@@ -118,10 +118,10 @@ class SumVectorFunction : public MultiFunction {
VArraySpan<int> vectors = params.readonly_vector_input<int>(0);
MutableSpan<int> sums = params.uninitialized_single_output<int>(1);
- for (uint i : mask) {
+ for (int64_t i : mask) {
int sum = 0;
VSpan<int> vector = vectors[i];
- for (uint j = 0; j < vector.size(); j++) {
+ for (int j = 0; j < vector.size(); j++) {
sum += vector[j];
}
sums[i] = sum;
@@ -143,7 +143,7 @@ class CreateRangeFunction : public MultiFunction {
VSpan<int> sizes = params.readonly_single_input<int>(0, "Size");
GVectorArrayRef<int> ranges = params.vector_output<int>(1, "Range");
- for (int i : mask) {
+ for (int64_t i : mask) {
int size = sizes[i];
for (int j : IndexRange(size)) {
ranges.append(i, j);
diff --git a/tests/gtests/functions/FN_multi_function_test.cc b/tests/gtests/functions/FN_multi_function_test.cc
index 66039e463ed..8b5fb060c36 100644
--- a/tests/gtests/functions/FN_multi_function_test.cc
+++ b/tests/gtests/functions/FN_multi_function_test.cc
@@ -23,7 +23,7 @@ class AddFunction : public MultiFunction {
VSpan<int> b = params.readonly_single_input<int>(1, "B");
MutableSpan<int> result = params.uninitialized_single_output<int>(2, "Result");
- for (uint i : mask) {
+ for (int64_t i : mask) {
result[i] = a[i] + b[i];
}
}
@@ -65,7 +65,7 @@ class AddPrefixFunction : public MultiFunction {
VSpan<std::string> prefixes = params.readonly_single_input<std::string>(0, "Prefix");
MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings");
- for (uint i : mask) {
+ for (int64_t i : mask) {
strings[i] = prefixes[i] + strings[i];
}
}
@@ -112,7 +112,7 @@ class CreateRangeFunction : public MultiFunction {
VSpan<uint> sizes = params.readonly_single_input<uint>(0, "Size");
GVectorArrayRef<uint> ranges = params.vector_output<uint>(1, "Range");
- for (uint i : mask) {
+ for (int64_t i : mask) {
uint size = sizes[i];
for (uint j : IndexRange(size)) {
ranges.append(i, j);
@@ -164,7 +164,7 @@ class GenericAppendFunction : public MultiFunction {
GVectorArray &vectors = params.vector_mutable(0, "Vector");
GVSpan values = params.readonly_single_input(1, "Value");
- for (uint i : mask) {
+ for (int64_t i : mask) {
vectors.append(i, values[i]);
}
}
@@ -355,7 +355,7 @@ TEST(multi_function, CustomMF_GenericConstantArray)
EXPECT_EQ(vector_array[1].size(), 4);
EXPECT_EQ(vector_array[2].size(), 4);
EXPECT_EQ(vector_array[3].size(), 4);
- for (uint i = 1; i < 4; i++) {
+ for (int i = 1; i < 4; i++) {
EXPECT_EQ(vector_array[i][0], 3);
EXPECT_EQ(vector_array[i][1], 4);
EXPECT_EQ(vector_array[i][2], 5);