UI: Generalize drop target API, support them for UI views #105963
|
@ -78,12 +78,7 @@ include(cmake/tbb.cmake)
|
|||
include(cmake/python.cmake)
|
||||
include(cmake/llvm.cmake)
|
||||
include(cmake/osl.cmake)
|
||||
option(USE_PIP_NUMPY "Install NumPy using pip wheel instead of building from source" OFF)
|
||||
if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
|
||||
set(USE_PIP_NUMPY ON)
|
||||
else()
|
||||
include(cmake/numpy.cmake)
|
||||
endif()
|
||||
include(cmake/numpy.cmake)
|
||||
include(cmake/python_site_packages.cmake)
|
||||
include(cmake/package_python.cmake)
|
||||
include(cmake/openimageio.cmake)
|
||||
|
|
|
@ -38,15 +38,6 @@ ExternalProject_Add(external_python_site_packages
|
|||
--no-binary :all:
|
||||
)
|
||||
|
||||
if(USE_PIP_NUMPY)
|
||||
# Use only wheel (and not build from source) to stop NumPy from linking against buggy
|
||||
# Accelerate framework backend on macOS. Official wheels are built with OpenBLAS.
|
||||
ExternalProject_Add_Step(external_python_site_packages after_install
|
||||
COMMAND ${PYTHON_BINARY} -m pip install --no-cache-dir numpy==${NUMPY_VERSION} --only-binary :all:
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
||||
add_dependencies(
|
||||
external_python_site_packages
|
||||
external_python
|
||||
|
|
|
@ -204,7 +204,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
|
|||
ray.time = 0.5f;
|
||||
ray.dP = differential_zero_compact();
|
||||
ray.dD = differential_zero_compact();
|
||||
integrator_state_write_ray(kg, state, &ray);
|
||||
integrator_state_write_ray(state, &ray);
|
||||
|
||||
/* Setup next kernel to execute. */
|
||||
integrator_path_init(kg, state, DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND);
|
||||
|
@ -299,7 +299,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
|
|||
ray.dD = differential_zero_compact();
|
||||
|
||||
/* Write ray. */
|
||||
integrator_state_write_ray(kg, state, &ray);
|
||||
integrator_state_write_ray(state, &ray);
|
||||
|
||||
/* Setup and write intersection. */
|
||||
Intersection isect ccl_optional_struct_init;
|
||||
|
@ -309,7 +309,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
|
|||
isect.v = v;
|
||||
isect.t = 1.0f;
|
||||
isect.type = PRIMITIVE_TRIANGLE;
|
||||
integrator_state_write_isect(kg, state, &isect);
|
||||
integrator_state_write_isect(state, &isect);
|
||||
|
||||
/* Setup next kernel to execute. */
|
||||
const bool use_caustics = kernel_data.integrator.use_caustics &&
|
||||
|
|
|
@ -85,7 +85,7 @@ ccl_device bool integrator_init_from_camera(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* Write camera ray to state. */
|
||||
integrator_state_write_ray(kg, state, &ray);
|
||||
integrator_state_write_ray(state, &ray);
|
||||
}
|
||||
|
||||
/* Initialize path state for path integration. */
|
||||
|
|
|
@ -150,7 +150,7 @@ ccl_device_forceinline void integrator_intersect_next_kernel_after_shadow_catche
|
|||
/* Continue with shading shadow catcher surface. Same as integrator_split_shadow_catcher, but
|
||||
* using NEXT instead of INIT. */
|
||||
Intersection isect ccl_optional_struct_init;
|
||||
integrator_state_read_isect(kg, state, &isect);
|
||||
integrator_state_read_isect(state, &isect);
|
||||
|
||||
const int shader = intersection_get_shader(kg, &isect);
|
||||
const int flags = kernel_data_fetch(shaders, shader).flags;
|
||||
|
@ -326,7 +326,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
|
|||
|
||||
/* Read ray from integrator state into local memory. */
|
||||
Ray ray ccl_optional_struct_init;
|
||||
integrator_state_read_ray(kg, state, &ray);
|
||||
integrator_state_read_ray(state, &ray);
|
||||
kernel_assert(ray.tmax != 0.0f);
|
||||
|
||||
const uint visibility = path_state_ray_visibility(state);
|
||||
|
@ -397,7 +397,7 @@ ccl_device void integrator_intersect_closest(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* Write intersection result into global integrator state memory. */
|
||||
integrator_state_write_isect(kg, state, &isect);
|
||||
integrator_state_write_isect(state, &isect);
|
||||
|
||||
/* Setup up next kernel to be executed. */
|
||||
integrator_intersect_next_kernel<DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST>(
|
||||
|
|
|
@ -142,7 +142,7 @@ ccl_device void integrator_intersect_shadow(KernelGlobals kg, IntegratorShadowSt
|
|||
|
||||
/* Read ray from integrator state into local memory. */
|
||||
Ray ray ccl_optional_struct_init;
|
||||
integrator_state_read_shadow_ray(kg, state, &ray);
|
||||
integrator_state_read_shadow_ray(state, &ray);
|
||||
ray.self.object = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, object);
|
||||
ray.self.prim = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 0, prim);
|
||||
ray.self.light_object = INTEGRATOR_STATE_ARRAY(state, shadow_isect, 1, object);
|
||||
|
|
|
@ -73,7 +73,7 @@ ccl_device void integrator_volume_stack_init(KernelGlobals kg, IntegratorState s
|
|||
ccl_private ShaderData *stack_sd = AS_SHADER_DATA(&stack_sd_storage);
|
||||
|
||||
Ray volume_ray ccl_optional_struct_init;
|
||||
integrator_state_read_ray(kg, state, &volume_ray);
|
||||
integrator_state_read_ray(state, &volume_ray);
|
||||
|
||||
/* Trace ray in random direction. Any direction works, Z up is a guess to get the
|
||||
* fewest hits. */
|
||||
|
|
|
@ -16,7 +16,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
|
|||
{
|
||||
/* Setup light sample. */
|
||||
Intersection isect ccl_optional_struct_init;
|
||||
integrator_state_read_isect(kg, state, &isect);
|
||||
integrator_state_read_isect(state, &isect);
|
||||
|
||||
guiding_record_light_surface_segment(kg, state, &isect);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ ccl_device_inline Spectrum integrate_transparent_surface_shadow(KernelGlobals kg
|
|||
integrator_state_read_shadow_isect(state, &isect, hit);
|
||||
|
||||
Ray ray ccl_optional_struct_init;
|
||||
integrator_state_read_shadow_ray(kg, state, &ray);
|
||||
integrator_state_read_shadow_ray(state, &ray);
|
||||
|
||||
shader_setup_from_ray(kg, shadow_sd, &ray, &isect);
|
||||
|
||||
|
@ -70,7 +70,7 @@ ccl_device_inline void integrate_transparent_volume_shadow(KernelGlobals kg,
|
|||
|
||||
/* Setup shader data. */
|
||||
Ray ray ccl_optional_struct_init;
|
||||
integrator_state_read_shadow_ray(kg, state, &ray);
|
||||
integrator_state_read_shadow_ray(state, &ray);
|
||||
ray.self.object = OBJECT_NONE;
|
||||
ray.self.prim = PRIM_NONE;
|
||||
ray.self.light_object = OBJECT_NONE;
|
||||
|
|
|
@ -24,10 +24,10 @@ ccl_device_forceinline void integrate_surface_shader_setup(KernelGlobals kg,
|
|||
ccl_private ShaderData *sd)
|
||||
{
|
||||
Intersection isect ccl_optional_struct_init;
|
||||
integrator_state_read_isect(kg, state, &isect);
|
||||
integrator_state_read_isect(state, &isect);
|
||||
|
||||
Ray ray ccl_optional_struct_init;
|
||||
integrator_state_read_ray(kg, state, &ray);
|
||||
integrator_state_read_ray(state, &ray);
|
||||
|
||||
shader_setup_from_ray(kg, sd, &ray, &isect);
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
|||
}
|
||||
|
||||
/* Write shadow ray and associated state to global memory. */
|
||||
integrator_state_write_shadow_ray(kg, shadow_state, &ray);
|
||||
integrator_state_write_shadow_ray(shadow_state, &ray);
|
||||
// Save memory by storing the light and object indices in the shadow_isect
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, object) = ray.self.object;
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, prim) = ray.self.prim;
|
||||
|
@ -548,7 +548,7 @@ ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg,
|
|||
integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
|
||||
|
||||
/* Write shadow ray and associated state to global memory. */
|
||||
integrator_state_write_shadow_ray(kg, shadow_state, &ray);
|
||||
integrator_state_write_shadow_ray(shadow_state, &ray);
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, object) = ray.self.object;
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, prim) = ray.self.prim;
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 1, object) = ray.self.light_object;
|
||||
|
|
|
@ -827,7 +827,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
|||
kg, state, DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW, false);
|
||||
|
||||
/* Write shadow ray and associated state to global memory. */
|
||||
integrator_state_write_shadow_ray(kg, shadow_state, &ray);
|
||||
integrator_state_write_shadow_ray(shadow_state, &ray);
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, object) = ray.self.object;
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 0, prim) = ray.self.prim;
|
||||
INTEGRATOR_STATE_ARRAY_WRITE(shadow_state, shadow_isect, 1, object) = ray.self.light_object;
|
||||
|
@ -1172,10 +1172,10 @@ ccl_device void integrator_shade_volume(KernelGlobals kg,
|
|||
#ifdef __VOLUME__
|
||||
/* Setup shader data. */
|
||||
Ray ray ccl_optional_struct_init;
|
||||
integrator_state_read_ray(kg, state, &ray);
|
||||
integrator_state_read_ray(state, &ray);
|
||||
|
||||
Intersection isect ccl_optional_struct_init;
|
||||
integrator_state_read_isect(kg, state, &isect);
|
||||
integrator_state_read_isect(state, &isect);
|
||||
|
||||
/* Set ray length to current segment. */
|
||||
ray.tmax = (isect.prim != PRIM_NONE) ? isect.t : FLT_MAX;
|
||||
|
|
|
@ -11,8 +11,7 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Ray */
|
||||
|
||||
ccl_device_forceinline void integrator_state_write_ray(KernelGlobals kg,
|
||||
IntegratorState state,
|
||||
ccl_device_forceinline void integrator_state_write_ray(IntegratorState state,
|
||||
ccl_private const Ray *ccl_restrict ray)
|
||||
{
|
||||
INTEGRATOR_STATE_WRITE(state, ray, P) = ray->P;
|
||||
|
@ -24,8 +23,7 @@ ccl_device_forceinline void integrator_state_write_ray(KernelGlobals kg,
|
|||
INTEGRATOR_STATE_WRITE(state, ray, dD) = ray->dD;
|
||||
}
|
||||
|
||||
ccl_device_forceinline void integrator_state_read_ray(KernelGlobals kg,
|
||||
ConstIntegratorState state,
|
||||
ccl_device_forceinline void integrator_state_read_ray(ConstIntegratorState state,
|
||||
ccl_private Ray *ccl_restrict ray)
|
||||
{
|
||||
ray->P = INTEGRATOR_STATE(state, ray, P);
|
||||
|
@ -40,7 +38,7 @@ ccl_device_forceinline void integrator_state_read_ray(KernelGlobals kg,
|
|||
/* Shadow Ray */
|
||||
|
||||
ccl_device_forceinline void integrator_state_write_shadow_ray(
|
||||
KernelGlobals kg, IntegratorShadowState state, ccl_private const Ray *ccl_restrict ray)
|
||||
IntegratorShadowState state, ccl_private const Ray *ccl_restrict ray)
|
||||
{
|
||||
INTEGRATOR_STATE_WRITE(state, shadow_ray, P) = ray->P;
|
||||
INTEGRATOR_STATE_WRITE(state, shadow_ray, D) = ray->D;
|
||||
|
@ -50,8 +48,7 @@ ccl_device_forceinline void integrator_state_write_shadow_ray(
|
|||
INTEGRATOR_STATE_WRITE(state, shadow_ray, dP) = ray->dP;
|
||||
}
|
||||
|
||||
ccl_device_forceinline void integrator_state_read_shadow_ray(KernelGlobals kg,
|
||||
ConstIntegratorShadowState state,
|
||||
ccl_device_forceinline void integrator_state_read_shadow_ray(ConstIntegratorShadowState state,
|
||||
ccl_private Ray *ccl_restrict ray)
|
||||
{
|
||||
ray->P = INTEGRATOR_STATE(state, shadow_ray, P);
|
||||
|
@ -66,7 +63,7 @@ ccl_device_forceinline void integrator_state_read_shadow_ray(KernelGlobals kg,
|
|||
/* Intersection */
|
||||
|
||||
ccl_device_forceinline void integrator_state_write_isect(
|
||||
KernelGlobals kg, IntegratorState state, ccl_private const Intersection *ccl_restrict isect)
|
||||
IntegratorState state, ccl_private const Intersection *ccl_restrict isect)
|
||||
{
|
||||
INTEGRATOR_STATE_WRITE(state, isect, t) = isect->t;
|
||||
INTEGRATOR_STATE_WRITE(state, isect, u) = isect->u;
|
||||
|
@ -77,7 +74,7 @@ ccl_device_forceinline void integrator_state_write_isect(
|
|||
}
|
||||
|
||||
ccl_device_forceinline void integrator_state_read_isect(
|
||||
KernelGlobals kg, ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
|
||||
ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
|
||||
{
|
||||
isect->prim = INTEGRATOR_STATE(state, isect, prim);
|
||||
isect->object = INTEGRATOR_STATE(state, isect, object);
|
||||
|
|
|
@ -162,8 +162,8 @@ ccl_device_inline bool subsurface_scatter(KernelGlobals kg, IntegratorState stat
|
|||
ray.P += ray.D * ray.tmax * 2.0f;
|
||||
ray.D = -ray.D;
|
||||
|
||||
integrator_state_write_isect(kg, state, &ss_isect.hits[0]);
|
||||
integrator_state_write_ray(kg, state, &ray);
|
||||
integrator_state_write_isect(state, &ss_isect.hits[0]);
|
||||
integrator_state_write_ray(state, &ray);
|
||||
|
||||
/* Advance random number offset for bounce. */
|
||||
INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
|
||||
|
|
|
@ -161,7 +161,11 @@ ccl_device_inline void osl_eval_nodes(KernelGlobals kg,
|
|||
/* shadeindex = */ 0);
|
||||
# endif
|
||||
|
||||
# if __cplusplus < 201703L
|
||||
if (type == SHADER_TYPE_DISPLACEMENT) {
|
||||
# else
|
||||
if constexpr (type == SHADER_TYPE_DISPLACEMENT) {
|
||||
# endif
|
||||
sd->P = globals.P;
|
||||
}
|
||||
else if (globals.Ci) {
|
||||
|
|
|
@ -1646,8 +1646,8 @@ enum KernelFeatureFlag : uint32_t {
|
|||
|
||||
/* Must be constexpr on the CPU to avoid compile errors because the state types
|
||||
* are different depending on the main, shadow or null path. For GPU we don't have
|
||||
* C++17 everywhere so can't use it. */
|
||||
#ifdef __KERNEL_GPU__
|
||||
* C++17 everywhere so need to check it. */
|
||||
#if __cplusplus < 201703L
|
||||
# define IF_KERNEL_FEATURE(feature) if ((node_feature_mask & (KERNEL_FEATURE_##feature)) != 0U)
|
||||
# define IF_KERNEL_NODES_FEATURE(feature) \
|
||||
if ((node_feature_mask & (KERNEL_FEATURE_NODE_##feature)) != 0U)
|
||||
|
|
|
@ -40,6 +40,25 @@
|
|||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="3.5" date="2023-03-29">
|
||||
<description>
|
||||
<p>New features:</p>
|
||||
<ul>
|
||||
<li>Real-Time compositor</li>
|
||||
<li>Vector displacement sculpting</li>
|
||||
<li>Built-in hair node groups</li>
|
||||
<li>Cycles many light sampling</li>
|
||||
<li>Metal Viewport for macOS</li>
|
||||
</ul>
|
||||
<p>Enhancements:</p>
|
||||
<ul>
|
||||
<li>Support for importing and exporting compressed .USDZ files</li>
|
||||
<li>New Ease operator in the graph editor</li>
|
||||
<li>New Geometry Nodes, like Image Info and Blur Attribute</li>
|
||||
<li>Font previews now differentiate better between Korean, Japanese, Simplified and Traditional Chinese</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="3.4" date="2022-12-07">
|
||||
<description>
|
||||
<p>New features:</p>
|
||||
|
|
|
@ -177,6 +177,16 @@
|
|||
# define HASH_TABLE_KEY_FALLBACK ((hash_key)-2)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Ensure duplicate entries aren't added to temporary hash table
|
||||
* needed for arrays where many values match (an array of booleans all true/false for e.g.).
|
||||
*
|
||||
* Without this, a huge number of duplicates are added a single bucket, making hash lookups slow.
|
||||
* While de-duplication adds some cost, it's only performed with other chunks in the same bucket
|
||||
* so cases when all chunks are unique will quickly detect and exit the `memcmp` in most cases.
|
||||
*/
|
||||
#define USE_HASH_TABLE_DEDUPLICATE
|
||||
|
||||
/**
|
||||
* How much larger the table is then the total number of chunks.
|
||||
*/
|
||||
|
@ -367,13 +377,23 @@ static void bchunk_decref(BArrayMemory *bs_mem, BChunk *chunk)
|
|||
}
|
||||
}
|
||||
|
||||
BLI_INLINE bool bchunk_data_compare_unchecked(const BChunk *chunk,
|
||||
const uchar *data_base,
|
||||
const size_t data_base_len,
|
||||
const size_t offset)
|
||||
{
|
||||
BLI_assert(offset + (size_t)chunk->data_len <= data_base_len);
|
||||
UNUSED_VARS_NDEBUG(data_base_len);
|
||||
return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0);
|
||||
}
|
||||
|
||||
static bool bchunk_data_compare(const BChunk *chunk,
|
||||
const uchar *data_base,
|
||||
const size_t data_base_len,
|
||||
const size_t offset)
|
||||
{
|
||||
if (offset + (size_t)chunk->data_len <= data_base_len) {
|
||||
return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0);
|
||||
return bchunk_data_compare_unchecked(chunk, data_base, data_base_len, offset);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -944,23 +964,26 @@ static const BChunkRef *table_lookup(const BArrayInfo *info,
|
|||
const size_t offset,
|
||||
const hash_key *table_hash_array)
|
||||
{
|
||||
size_t size_left = data_len - offset;
|
||||
hash_key key = table_hash_array[((offset - i_table_start) / info->chunk_stride)];
|
||||
size_t key_index = (size_t)(key % (hash_key)table_len);
|
||||
for (const BTableRef *tref = table[key_index]; tref; tref = tref->next) {
|
||||
const BChunkRef *cref = tref->cref;
|
||||
uint key_index = (uint)(key % (hash_key)table_len);
|
||||
const BTableRef *tref = table[key_index];
|
||||
if (tref != NULL) {
|
||||
const size_t size_left = data_len - offset;
|
||||
do {
|
||||
const BChunkRef *cref = tref->cref;
|
||||
# ifdef USE_HASH_TABLE_KEY_CACHE
|
||||
if (cref->link->key == key)
|
||||
if (cref->link->key == key)
|
||||
# endif
|
||||
{
|
||||
BChunk *chunk_test = cref->link;
|
||||
if (chunk_test->data_len <= size_left) {
|
||||
if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
|
||||
/* we could remove the chunk from the table, to avoid multiple hits */
|
||||
return cref;
|
||||
{
|
||||
BChunk *chunk_test = cref->link;
|
||||
if (chunk_test->data_len <= size_left) {
|
||||
if (bchunk_data_compare_unchecked(chunk_test, data, data_len, offset)) {
|
||||
/* we could remove the chunk from the table, to avoid multiple hits */
|
||||
return cref;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((tref = tref->next));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1009,7 +1032,7 @@ static const BChunkRef *table_lookup(const BArrayInfo *info,
|
|||
|
||||
size_t size_left = data_len - offset;
|
||||
hash_key key = hash_data(&data[offset], MIN2(data_hash_len, size_left));
|
||||
size_t key_index = (size_t)(key % (hash_key)table_len);
|
||||
uint key_index = (uint)(key % (hash_key)table_len);
|
||||
for (BTableRef *tref = table[key_index]; tref; tref = tref->next) {
|
||||
const BChunkRef *cref = tref->cref;
|
||||
# ifdef USE_HASH_TABLE_KEY_CACHE
|
||||
|
@ -1018,7 +1041,7 @@ static const BChunkRef *table_lookup(const BArrayInfo *info,
|
|||
{
|
||||
BChunk *chunk_test = cref->link;
|
||||
if (chunk_test->data_len <= size_left) {
|
||||
if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
|
||||
if (bchunk_data_compare_unchecked(chunk_test, data, data_len, offset)) {
|
||||
/* we could remove the chunk from the table, to avoid multiple hits */
|
||||
return cref;
|
||||
}
|
||||
|
@ -1292,13 +1315,29 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
|
|||
hash_store_len
|
||||
#endif
|
||||
);
|
||||
size_t key_index = (size_t)(key % (hash_key)table_len);
|
||||
uint key_index = (uint)(key % (hash_key)table_len);
|
||||
BTableRef *tref_prev = table[key_index];
|
||||
BLI_assert(table_ref_stack_n < chunk_list_reference_remaining_len);
|
||||
BTableRef *tref = &table_ref_stack[table_ref_stack_n++];
|
||||
tref->cref = cref;
|
||||
tref->next = tref_prev;
|
||||
table[key_index] = tref;
|
||||
#ifdef USE_HASH_TABLE_DEDUPLICATE
|
||||
bool is_duplicate = false;
|
||||
for (BTableRef *tref_iter = tref_prev; tref_iter; tref_iter = tref_iter->next) {
|
||||
if ((cref->link->data_len == tref_iter->cref->link->data_len) &&
|
||||
(memcmp(cref->link->data,
|
||||
tref_iter->cref->link->data,
|
||||
tref_iter->cref->link->data_len) == 0)) {
|
||||
is_duplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_duplicate)
|
||||
#endif /* USE_HASH_TABLE_DEDUPLICATE */
|
||||
{
|
||||
BTableRef *tref = &table_ref_stack[table_ref_stack_n++];
|
||||
tref->cref = cref;
|
||||
tref->next = tref_prev;
|
||||
table[key_index] = tref;
|
||||
}
|
||||
|
||||
chunk_list_reference_bytes_remaining -= cref->link->data_len;
|
||||
cref = cref->next;
|
||||
|
|
|
@ -51,8 +51,15 @@
|
|||
|
||||
# include "BLI_array_store.h"
|
||||
# include "BLI_array_store_utils.h"
|
||||
/* check on best size later... */
|
||||
# define ARRAY_CHUNK_SIZE 256
|
||||
/**
|
||||
* This used to be much smaller (256), but this caused too much overhead
|
||||
* when selection moved to boolean arrays. Especially with high-poly meshes
|
||||
* where managing a large number of small chunks could be slow, blocking user interactivity.
|
||||
* Use a larger value (in bytes) which calculates the chunk size using #array_chunk_size_calc.
|
||||
* See: #105046 & #105205.
|
||||
*/
|
||||
# define ARRAY_CHUNK_SIZE_IN_BYTES 65536
|
||||
# define ARRAY_CHUNK_NUM_MIN 256
|
||||
|
||||
# define USE_ARRAY_STORE_THREAD
|
||||
#endif
|
||||
|
@ -70,6 +77,14 @@ static CLG_LogRef LOG = {"ed.undo.mesh"};
|
|||
|
||||
#ifdef USE_ARRAY_STORE
|
||||
|
||||
static size_t array_chunk_size_calc(const size_t stride)
|
||||
{
|
||||
/* Return a chunk size that targets a size in bytes,
|
||||
* this is done so boolean arrays don't add so much overhead and
|
||||
* larger arrays aren't unreasonably big, see: #105205. */
|
||||
return std::max(ARRAY_CHUNK_NUM_MIN, ARRAY_CHUNK_SIZE_IN_BYTES / power_of_2_max_i(stride));
|
||||
}
|
||||
|
||||
/* Single linked list of layers stored per type */
|
||||
struct BArrayCustomData {
|
||||
BArrayCustomData *next;
|
||||
|
@ -190,8 +205,9 @@ static void um_arraystore_cd_compact(CustomData *cdata,
|
|||
}
|
||||
|
||||
const int stride = CustomData_sizeof(type);
|
||||
BArrayStore *bs = create ? BLI_array_store_at_size_ensure(
|
||||
&um_arraystore.bs_stride[bs_index], stride, ARRAY_CHUNK_SIZE) :
|
||||
BArrayStore *bs = create ? BLI_array_store_at_size_ensure(&um_arraystore.bs_stride[bs_index],
|
||||
stride,
|
||||
array_chunk_size_calc(stride)) :
|
||||
nullptr;
|
||||
const int layer_len = layer_end - layer_start;
|
||||
|
||||
|
@ -372,7 +388,7 @@ static void um_arraystore_compact_ex(UndoMesh *um, const UndoMesh *um_ref, bool
|
|||
BArrayStore *bs = create ? BLI_array_store_at_size_ensure(
|
||||
&um_arraystore.bs_stride[ARRAY_STORE_INDEX_SHAPE],
|
||||
stride,
|
||||
ARRAY_CHUNK_SIZE) :
|
||||
array_chunk_size_calc(stride)) :
|
||||
nullptr;
|
||||
if (create) {
|
||||
um->store.keyblocks = static_cast<BArrayState **>(
|
||||
|
@ -403,7 +419,9 @@ static void um_arraystore_compact_ex(UndoMesh *um, const UndoMesh *um_ref, bool
|
|||
BArrayState *state_reference = um_ref ? um_ref->store.mselect : nullptr;
|
||||
const size_t stride = sizeof(*me->mselect);
|
||||
BArrayStore *bs = BLI_array_store_at_size_ensure(
|
||||
&um_arraystore.bs_stride[ARRAY_STORE_INDEX_MSEL], stride, ARRAY_CHUNK_SIZE);
|
||||
&um_arraystore.bs_stride[ARRAY_STORE_INDEX_MSEL],
|
||||
stride,
|
||||
array_chunk_size_calc(stride));
|
||||
um->store.mselect = BLI_array_store_state_add(
|
||||
bs, me->mselect, size_t(me->totselect) * stride, state_reference);
|
||||
}
|
||||
|
|
|
@ -145,11 +145,16 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
|||
}
|
||||
|
||||
class LazyFunctionForSwitchNode : public LazyFunction {
|
||||
private:
|
||||
bool can_be_field_ = false;
|
||||
|
||||
public:
|
||||
LazyFunctionForSwitchNode(const bNode &node)
|
||||
{
|
||||
const NodeSwitch &storage = node_storage(node);
|
||||
const eNodeSocketDatatype data_type = eNodeSocketDatatype(storage.input_type);
|
||||
can_be_field_ = ELEM(data_type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA);
|
||||
|
||||
const bNodeSocketType *socket_type = nullptr;
|
||||
for (const bNodeSocket *socket : node.output_sockets()) {
|
||||
if (socket->type == data_type) {
|
||||
|
@ -169,7 +174,7 @@ class LazyFunctionForSwitchNode : public LazyFunction {
|
|||
void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override
|
||||
{
|
||||
const ValueOrField<bool> condition = params.get_input<ValueOrField<bool>>(0);
|
||||
if (condition.is_field()) {
|
||||
if (condition.is_field() && can_be_field_) {
|
||||
Field<bool> condition_field = condition.as_field();
|
||||
if (condition_field.node().depends_on_input()) {
|
||||
this->execute_field(condition.as_field(), params);
|
||||
|
|
|
@ -48,7 +48,7 @@ static void report_deprecated_call(const char *function_name)
|
|||
}
|
||||
char message[256];
|
||||
SNPRINTF(message,
|
||||
"'bgl.gl%s' is deprecated and will be removed in Blender 3.7. Report or update your "
|
||||
"'bgl.gl%s' is deprecated and will be removed in Blender 4.0. Report or update your "
|
||||
"script to use 'gpu' module.",
|
||||
function_name);
|
||||
CLOG_WARN(&LOG, "%s", message);
|
||||
|
@ -2653,7 +2653,7 @@ PyObject *BPyInit_bgl(void)
|
|||
if (GPU_backend_get_type() != GPU_BACKEND_OPENGL) {
|
||||
CLOG_WARN(&LOG,
|
||||
"'bgl' imported without an OpenGL backend. Please update your add-ons to use the "
|
||||
"'gpu' module. In Blender 3.7 'bgl' will be removed.");
|
||||
"'gpu' module. In Blender 4.0 'bgl' will be removed.");
|
||||
}
|
||||
|
||||
PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType);
|
||||
|
|
Loading…
Reference in New Issue