Compare commits

..

18 Commits

Author SHA1 Message Date
2935fd5f4d Cleanup: Convert interface_region_search.cc to C++ 2021-11-10 14:42:59 -06:00
abf62d06d1 Merge branch 'blender-v3.0-release' 2021-11-10 11:11:58 -06:00
35ae7ab933 Cleanup: Use bool instead of int 2021-11-10 11:11:35 -06:00
cc17ed26ce Merge branch 'blender-v3.0-release' 2021-11-10 10:52:34 -06:00
20224369d9 Geometry Nodes: Clarify modifier node group errors
This commit adds modifier error messages to some of the cases
where the node group is configured improperly. It also clears the
geometry set when there is an error with the node group. This is
consistent to what we do in nodes themselves, and feels more
intuitive than passing the input geometry through the node group
silently.

Fixes T87142
2021-11-10 10:52:18 -06:00
e9b7e5e0b9 Merge branch 'blender-v3.0-release' 2021-11-10 10:47:09 -06:00
67e5edbaa3 Fix: Incorrect translation search for modifier error messages
This function was renamed in rB2bb9a465e6c0e1ca765, but it looks like
that commit missed changing the corresponding translation regular
expression.

Differential Revision: https://developer.blender.org/D13171
2021-11-10 10:46:49 -06:00
f565620435 Fix T92985: CUDA errors with Cycles film convert kernels
rB3a4c8f406a3a3bf0627477c6183a594fa707a6e2 changed the macros that create the film
convert kernel entry points, but in the process accidentally changed the parameter definition
to one of those (which caused CUDA launch and misaligned address errors) and changed the
implementation as well. This restores the correct implementation from before.

In addition, the `ccl_gpu_kernel_threads` macro did not work as intended and caused the
generated launch bounds to end up with an incorrect input for the second parameter (it was
set to "thread_num_registers", rather than the result of the block number calculation). I'm
not entirely sure why, as the macro definition looked sound to me. Decided to simply go with
two separate macros instead, to simplify and solve this.

Also changed how state is captured with the `ccl_gpu_kernel_lambda` macro slightly, to avoid
a compiler warning (expression has no effect) that otherwise occurred.

Maniphest Tasks: T92985

Differential Revision: https://developer.blender.org/D13175
2021-11-10 15:49:50 +01:00
a6e4cb092e Merge branch 'blender-v3.0-release' 2021-11-10 13:53:44 +01:00
Jeroen Bakker
bc0c06ecbe Fix T91518: crash when recalculating looptris after clearing geometry.
When clearing geometry the runtime mutexes of a mesh were freed. This
resulted in crashes afterwards. The clear geometry is an RNA function so
would only effect when using from scripts.

This patch separates init/freeing of the mutexes from other code so they
can be used when needed.

Reviewed By: mont29

Maniphest Tasks: T91518

Differential Revision: https://developer.blender.org/D13142
2021-11-10 13:50:15 +01:00
53468c2b13 Merge branch 'blender-v3.0-release' 2021-11-10 13:43:08 +01:00
47b8baa5c4 Fix T92864: curve object does not sync correctly in cycles
The issue was that the `object_is_geometry` method was used in two different
contexts that expected the function to behave differently. So a recent change
that fixed `object_is_geometry` for one context, broke it for the other context.
The two contexts are:
* Check if a "real" object can contain a geometry to check if it has to be tagged
  for sync after an update.
* Check if an object/instance actually is a geometry that cycles can work with.

I created a new `object_can_have_geometry` method for the first use case, instead
of trying to adapt the existing object_is_geometry method to serve both uses.
Additionally, I changed it so that a BObjectInfo is passed into `object_is_geometry`
to make it more explicit when this method is supposed to be used.

Differential Revision: https://developer.blender.org/D13135
2021-11-10 13:38:07 +01:00
03e22da665 Merge branch 'blender-v3.0-release' 2021-11-10 12:47:01 +01:00
aa2f6e5977 Fix T92979: Emission Strength Animation read wrong in 3.0
First this was wrong for files written in 2.93 read into blender in 3.0
after the CyclesX merge.
Then this was fixed by versioning in rB6321dd3d4007.
But this caused files written in 3.0 to have this versioning applied as
well (leading to socket shifting).

Now only do the versioning for files created before the CyclesX
merge.

Maniphest Tasks: T92979

Differential Revision: https://developer.blender.org/D13173
2021-11-10 12:45:41 +01:00
ff0c42acfc Merge branch 'blender-v3.0-release' 2021-11-10 21:22:01 +11:00
a49d6a5350 Merge branch 'blender-v3.0-release' 2021-11-10 21:21:58 +11:00
bec72a43ae Fix T92874: Custom normals reset when vertex is deleted
Storing and restoring custom normals was broken by
39b2a7bb7e

This also caused "Sharp Edge" option for Weld by Distance to fail,
reported as T92875.
2021-11-10 21:11:41 +11:00
7b530c6096 Fix: Incorrect assert in dot grid drawing
It's totally valid for the grid levels to be zero.
2021-11-09 13:15:34 -06:00
46 changed files with 298 additions and 1216 deletions

View File

@@ -62,15 +62,15 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
return false;
}
bool BlenderSync::object_is_geometry(BL::Object &b_ob)
bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info)
{
BL::ID b_ob_data = b_ob.data();
BL::ID b_ob_data = b_ob_info.object_data;
if (!b_ob_data) {
return false;
}
BL::Object::type_enum type = b_ob.type();
BL::Object::type_enum type = b_ob_info.iter_object.type();
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR) {
/* Will be exported attached to mesh. */
@@ -87,6 +87,24 @@ bool BlenderSync::object_is_geometry(BL::Object &b_ob)
return b_ob_data.is_a(&RNA_Mesh);
}
bool BlenderSync::object_can_have_geometry(BL::Object &b_ob)
{
BL::Object::type_enum type = b_ob.type();
switch (type) {
case BL::Object::type_MESH:
case BL::Object::type_CURVE:
case BL::Object::type_SURFACE:
case BL::Object::type_META:
case BL::Object::type_FONT:
case BL::Object::type_HAIR:
case BL::Object::type_POINTCLOUD:
case BL::Object::type_VOLUME:
return true;
default:
return false;
}
}
bool BlenderSync::object_is_light(BL::Object &b_ob)
{
BL::ID b_ob_data = b_ob.data();
@@ -189,7 +207,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
}
/* only interested in object that we can create meshes from */
if (!object_is_geometry(b_ob)) {
if (!object_is_geometry(b_ob_info)) {
return NULL;
}

View File

@@ -162,19 +162,19 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
/* Object */
else if (b_id.is_a(&RNA_Object)) {
BL::Object b_ob(b_id);
const bool is_geometry = object_is_geometry(b_ob);
const bool is_light = !is_geometry && object_is_light(b_ob);
const bool can_have_geometry = object_can_have_geometry(b_ob);
const bool is_light = !can_have_geometry && object_is_light(b_ob);
if (b_ob.is_instancer() && b_update.is_updated_shading()) {
/* Needed for e.g. object color updates on instancer. */
object_map.set_recalc(b_ob);
}
if (is_geometry || is_light) {
if (can_have_geometry || is_light) {
const bool updated_geometry = b_update.is_updated_geometry();
/* Geometry (mesh, hair, volume). */
if (is_geometry) {
if (can_have_geometry) {
if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
object_map.set_recalc(b_ob);
}

View File

@@ -208,7 +208,8 @@ class BlenderSync {
/* util */
void find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader);
bool BKE_object_is_modified(BL::Object &b_ob);
bool object_is_geometry(BL::Object &b_ob);
bool object_is_geometry(BObjectInfo &b_ob_info);
bool object_can_have_geometry(BL::Object &b_ob);
bool object_is_light(BL::Object &b_ob);
/* variables */

View File

@@ -379,7 +379,6 @@ if(WITH_CYCLES_CUDA_BINARIES)
${SRC_KERNEL_HEADERS}
${SRC_KERNEL_DEVICE_GPU_HEADERS}
${SRC_KERNEL_DEVICE_CUDA_HEADERS}
${SRC_KERNEL_DEVICE_METAL_HEADERS}
${SRC_UTIL_HEADERS}
)
set(cuda_cubins)

View File

@@ -92,25 +92,19 @@
/* Compute number of threads per block and minimum blocks per multiprocessor
* given the maximum number of registers per thread. */
#define ccl_gpu_kernel_threads(block_num_threads) \
extern "C" __global__ void __launch_bounds__(block_num_threads)
#define ccl_gpu_kernel_threads_registers(block_num_threads, thread_num_registers) \
#define ccl_gpu_kernel(block_num_threads, thread_num_registers) \
extern "C" __global__ void __launch_bounds__(block_num_threads, \
GPU_MULTIPRESSOR_MAX_REGISTERS / \
(block_num_threads * thread_num_registers))
/* allow ccl_gpu_kernel to accept 1 or 2 parameters */
#define SELECT_MACRO(_1, _2, NAME, ...) NAME
#define ccl_gpu_kernel(...) \
SELECT_MACRO(__VA_ARGS__, ccl_gpu_kernel_threads_registers, ccl_gpu_kernel_threads)(__VA_ARGS__)
#define ccl_gpu_kernel_threads(block_num_threads) \
extern "C" __global__ void __launch_bounds__(block_num_threads)
#define ccl_gpu_kernel_signature(name, ...) kernel_gpu_##name(__VA_ARGS__)
#define ccl_gpu_kernel_call(x) x
/* define a function object where "func" is the lambda body, and additional parameters are used to
/* Define a function object where "func" is the lambda body, and additional parameters are used to
* specify captured state */
#define ccl_gpu_kernel_lambda(func, ...) \
struct KernelLambda { \
@@ -119,8 +113,7 @@
{ \
return (func); \
} \
} ccl_gpu_kernel_lambda_pass; \
ccl_gpu_kernel_lambda_pass
} ccl_gpu_kernel_lambda_pass
/* sanity checks */

View File

@@ -56,8 +56,7 @@
*/
ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
ccl_gpu_kernel_signature(integrator_reset,
int num_states)
ccl_gpu_kernel_signature(integrator_reset, int num_states)
{
const int state = ccl_gpu_global_id_x();
@@ -265,7 +264,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
}
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_queued_paths_array,
int num_states,
ccl_global int *indices,
@@ -273,14 +272,14 @@ ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int kernel_index)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, path, queued_kernel) == kernel_index,
int kernel_index)
.kernel_index = kernel_index;
int kernel_index);
ccl_gpu_kernel_lambda_pass.kernel_index = kernel_index;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_queued_shadow_paths_array,
int num_states,
ccl_global int *indices,
@@ -288,25 +287,26 @@ ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int kernel_index)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, shadow_path, queued_kernel) == kernel_index,
int kernel_index)
.kernel_index = kernel_index;
int kernel_index);
ccl_gpu_kernel_lambda_pass.kernel_index = kernel_index;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_active_paths_array,
int num_states,
ccl_global int *indices,
ccl_global int *num_indices)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, path, queued_kernel) != 0);
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_terminated_paths_array,
int num_states,
ccl_global int *indices,
@@ -314,11 +314,12 @@ ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int indices_offset)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, path, queued_kernel) == 0);
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices + indices_offset, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_terminated_shadow_paths_array,
int num_states,
ccl_global int *indices,
@@ -326,11 +327,12 @@ ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
int indices_offset)
{
ccl_gpu_kernel_lambda(INTEGRATOR_STATE(state, shadow_path, queued_kernel) == 0);
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices + indices_offset, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_sorted_paths_array,
int num_states,
int num_states_limit,
@@ -343,37 +345,37 @@ ccl_gpu_kernel(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_lambda((INTEGRATOR_STATE(state, path, queued_kernel) == kernel_index) ?
INTEGRATOR_STATE(state, path, shader_sort_key) :
GPU_PARALLEL_SORTED_INDEX_INACTIVE_KEY,
int kernel_index)
.kernel_index = kernel_index;
int kernel_index);
ccl_gpu_kernel_lambda_pass.kernel_index = kernel_index;
const uint state_index = ccl_gpu_global_id_x();
gpu_parallel_sorted_index_array(
state_index,
num_states,
num_states_limit,
indices,
gpu_parallel_sorted_index_array(state_index,
num_states,
num_states_limit,
indices,
num_indices,
key_counter,
key_prefix_sum,
ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_compact_paths_array,
int num_states,
ccl_global int *indices,
ccl_global int *num_indices,
int num_active_paths)
ccl_global int *num_indices,
int num_active_paths)
{
ccl_gpu_kernel_lambda((state >= num_active_paths) && (INTEGRATOR_STATE(state, path, queued_kernel) != 0),
int num_active_paths)
.num_active_paths = num_active_paths;
ccl_gpu_kernel_lambda((state >= num_active_paths) &&
(INTEGRATOR_STATE(state, path, queued_kernel) != 0),
int num_active_paths);
ccl_gpu_kernel_lambda_pass.num_active_paths = num_active_paths;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_compact_states,
ccl_global const int *active_terminated_states,
const int active_states_offset,
@@ -390,22 +392,23 @@ ccl_gpu_kernel(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
}
}
ccl_gpu_kernel(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_compact_shadow_paths_array,
int num_states,
ccl_global int *indices,
ccl_global int *num_indices,
int num_active_paths)
ccl_global int *num_indices,
int num_active_paths)
{
ccl_gpu_kernel_lambda((state >= num_active_paths) && (INTEGRATOR_STATE(state, shadow_path, queued_kernel) != 0),
int num_active_paths)
.num_active_paths = num_active_paths;
ccl_gpu_kernel_lambda((state >= num_active_paths) &&
(INTEGRATOR_STATE(state, shadow_path, queued_kernel) != 0),
int num_active_paths);
ccl_gpu_kernel_lambda_pass.num_active_paths = num_active_paths;
gpu_parallel_active_index_array<GPU_PARALLEL_ACTIVE_INDEX_DEFAULT_BLOCK_SIZE>(
num_states, indices, num_indices, ccl_gpu_kernel_lambda_pass);
}
ccl_gpu_kernel(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_compact_shadow_states,
ccl_global const int *active_terminated_states,
const int active_states_offset,
@@ -422,7 +425,7 @@ ccl_gpu_kernel(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
}
}
ccl_gpu_kernel(GPU_PARALLEL_PREFIX_SUM_DEFAULT_BLOCK_SIZE) ccl_gpu_kernel_signature(
ccl_gpu_kernel_threads(GPU_PARALLEL_PREFIX_SUM_DEFAULT_BLOCK_SIZE) ccl_gpu_kernel_signature(
prefix_sum, ccl_global int *counter, ccl_global int *prefix_sum, int num_values)
{
gpu_parallel_prefix_sum(ccl_gpu_global_id_x(), counter, prefix_sum, num_values);
@@ -524,7 +527,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS) \
ccl_gpu_kernel_signature(film_convert_##variant, \
const KernelFilmConvert kfilm_convert, \
ccl_global uchar4 *rgba, \
ccl_global float *pixels, \
ccl_global float *render_buffer, \
int num_pixels, \
int width, \
@@ -544,20 +547,10 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
ccl_global const float *buffer = render_buffer + offset + x * kfilm_convert.pass_stride + \
y * stride * kfilm_convert.pass_stride; \
\
float pixel[4]; \
ccl_global float *pixel = pixels + \
(render_pixel_index + rgba_offset) * kfilm_convert.pixel_stride; \
\
film_get_pass_pixel_##variant(&kfilm_convert, buffer, pixel); \
\
film_apply_pass_pixel_overlays_rgba(&kfilm_convert, buffer, pixel); \
\
if (input_channel_count == 1) { \
pixel[1] = pixel[2] = pixel[0]; \
} \
if (input_channel_count <= 3) { \
pixel[3] = 1.0f; \
} \
\
ccl_global float *out = ((ccl_global float *)rgba) + rgba_offset + y * rgba_stride + x; \
*(ccl_global float4 *)out = make_float4(pixel[0], pixel[1], pixel[2], pixel[3]); \
} \
\
ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS) \
@@ -585,8 +578,6 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
\
float pixel[4]; \
film_get_pass_pixel_##variant(&kfilm_convert, buffer, pixel); \
\
film_apply_pass_pixel_overlays_rgba(&kfilm_convert, buffer, pixel); \
\
if (input_channel_count == 1) { \
pixel[1] = pixel[2] = pixel[0]; \
@@ -595,7 +586,9 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
pixel[3] = 1.0f; \
} \
\
ccl_global half4 *out = ((ccl_global half4 *)rgba) + (rgba_offset + y * rgba_stride + x); \
film_apply_pass_pixel_overlays_rgba(&kfilm_convert, buffer, pixel); \
\
ccl_global half4 *out = ((ccl_global half4 *)rgba) + rgba_offset + y * rgba_stride + x; \
*out = float4_to_half4_display(make_float4(pixel[0], pixel[1], pixel[2], pixel[3])); \
}
@@ -617,6 +610,8 @@ KERNEL_FILM_CONVERT_VARIANT(shadow_catcher_matte_with_shadow, 4)
KERNEL_FILM_CONVERT_VARIANT(combined, 4)
KERNEL_FILM_CONVERT_VARIANT(float4, 4)
#undef KERNEL_FILM_CONVERT_VARIANT
/* --------------------------------------------------------------------
* Shader evaluation.
*/

View File

@@ -35,25 +35,19 @@
/* Compute number of threads per block and minimum blocks per multiprocessor
* given the maximum number of registers per thread. */
#define ccl_gpu_kernel_threads(block_num_threads) \
extern "C" __global__ void __launch_bounds__(block_num_threads)
#define ccl_gpu_kernel_threads_registers(block_num_threads, thread_num_registers) \
#define ccl_gpu_kernel(block_num_threads, thread_num_registers) \
extern "C" __global__ void __launch_bounds__(block_num_threads, \
GPU_MULTIPRESSOR_MAX_REGISTERS / \
(block_num_threads * thread_num_registers))
/* allow ccl_gpu_kernel to accept 1 or 2 parameters */
#define SELECT_MACRO(_1, _2, NAME, ...) NAME
#define ccl_gpu_kernel(...) \
SELECT_MACRO(__VA_ARGS__, ccl_gpu_kernel_threads_registers, ccl_gpu_kernel_threads)(__VA_ARGS__)
#define ccl_gpu_kernel_threads(block_num_threads) \
extern "C" __global__ void __launch_bounds__(block_num_threads)
#define ccl_gpu_kernel_signature(name, ...) kernel_gpu_##name(__VA_ARGS__)
#define ccl_gpu_kernel_call(x) x
/* define a function object where "func" is the lambda body, and additional parameters are used to
/* Define a function object where "func" is the lambda body, and additional parameters are used to
* specify captured state */
#define ccl_gpu_kernel_lambda(func, ...) \
struct KernelLambda { \
@@ -62,8 +56,7 @@
{ \
return (func); \
} \
} ccl_gpu_kernel_lambda_pass; \
ccl_gpu_kernel_lambda_pass
} ccl_gpu_kernel_lambda_pass
/* sanity checks */

View File

@@ -70,7 +70,8 @@ using namespace metal;
/* kernel.h adapters */
#define ccl_gpu_kernel(...)
#define ccl_gpu_kernel(block_num_threads, thread_num_registers)
#define ccl_gpu_kernel_threads(block_num_threads)
/* convert a comma-separated list into a semicolon-separated list (so that we can generate a struct based on kernel entrypoint parameters) */
#define FN0()
@@ -143,7 +144,7 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
ccl_private MetalKernelContext &context; \
__VA_ARGS__; \
int operator()(const int state) const { return (func); } \
}ccl_gpu_kernel_lambda_pass(context); ccl_gpu_kernel_lambda_pass
} ccl_gpu_kernel_lambda_pass(context)
// clang-format on
@@ -247,4 +248,4 @@ constant constexpr array<sampler, SamplerCount> metal_samplers = {
sampler(address::repeat, filter::linear),
sampler(address::clamp_to_edge, filter::linear),
sampler(address::clamp_to_zero, filter::linear),
};
};

View File

@@ -264,7 +264,7 @@ PYGETTEXT_KEYWORDS = (() +
for it in ("BMO_error_raise",)) +
tuple(("{}\\((?:[^\"',]+,)\\s*" + _msg_re + r"\s*(?:\)|,)").format(it)
for it in ("modifier_setError",)) +
for it in ("BKE_modifier_set_error",)) +
tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" +
r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it)

View File

@@ -306,31 +306,6 @@ class NODE_OT_tree_path_parent(Operator):
return {'FINISHED'}
class NODE_OT_enum_item_add(Operator):
'''Add enum item'''
bl_idname = "node.enum_item_add"
bl_label = "Add Enum Item"
bl_options = {'UNDO'}
node_name: StringProperty()
@classmethod
def poll(cls, context):
space = context.space_data
return space is not None and space.type == 'NODE_EDITOR' and space.edit_tree is not None
def execute(self, context):
import random
space = context.space_data
node = space.edit_tree.nodes.get(self.node_name)
if node is None:
return {'CANCELLED'}
item = node.enum_items.new()
item.value = random.randint(0, 1e7)
return {'FINISHED'}
classes = (
NodeSetting,
@@ -339,5 +314,4 @@ classes = (
NODE_OT_add_search,
NODE_OT_collapse_hide_unused_toggle,
NODE_OT_tree_path_parent,
NODE_OT_enum_item_add,
)

View File

@@ -754,7 +754,6 @@ geometry_node_categories = [
NodeItem("GeometryNodeSwitch"),
NodeItem("FunctionNodeRandomValue"),
NodeItem("FunctionNodeAlignEulerToVector"),
NodeItem("FunctionNodeEnum"),
]),
GeometryNodeCategory("GEO_VECTOR", "Vector", items=[
NodeItem("ShaderNodeVectorCurve"),

View File

@@ -41,7 +41,8 @@ struct Mesh;
struct Object;
struct Scene;
void BKE_mesh_runtime_reset(struct Mesh *mesh);
void BKE_mesh_runtime_init_data(struct Mesh *mesh);
void BKE_mesh_runtime_free_data(struct Mesh *mesh);
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, const int flag);
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);

View File

@@ -264,12 +264,6 @@ typedef struct bNodeType {
/* Additional parameters in the side panel */
void (*draw_buttons_ex)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr);
bool (*draw_socket)(struct uiLayout *layout,
const struct bContext *C,
struct bNodeTree *ntree,
struct bNode *node,
struct bNodeSocket *socket);
/* Additional drawing on backdrop */
void (*draw_backdrop)(
struct SpaceNode *snode, struct ImBuf *backdrop, struct bNode *node, int x, int y);
@@ -741,7 +735,6 @@ void nodeSetSocketAvailability(struct bNodeSocket *sock, bool is_available);
int nodeSocketLinkLimit(const struct bNodeSocket *sock);
void nodeUpdateFromDeclaration(struct bNodeTree *ntree, struct bNode *node);
bool nodeDeclarationEnsure(struct bNodeTree *ntree, struct bNode *node);
bool nodeDeclarationEnsureOnOutdatedNode(struct bNodeTree *ntree, struct bNode *node);
void nodeSocketDeclarationsUpdate(struct bNode *node);
@@ -1584,7 +1577,6 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_REPLACE_STRING 1218
#define FN_NODE_INPUT_BOOL 1219
#define FN_NODE_INPUT_INT 1220
#define FN_NODE_ENUM 1221
/** \} */

View File

@@ -88,7 +88,7 @@ static void mesh_init_data(ID *id)
CustomData_reset(&mesh->pdata);
CustomData_reset(&mesh->ldata);
BKE_mesh_runtime_reset(mesh);
BKE_mesh_runtime_init_data(mesh);
mesh->face_sets_color_seed = BLI_hash_int(PIL_check_seconds_timer_i() & UINT_MAX);
}
@@ -168,7 +168,7 @@ static void mesh_free_data(ID *id)
mesh->edit_mesh = nullptr;
}
BKE_mesh_runtime_clear_cache(mesh);
BKE_mesh_runtime_free_data(mesh);
mesh_clear_geometry(mesh);
MEM_SAFE_FREE(mesh->mat);
}
@@ -308,7 +308,9 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->texflag &= ~ME_AUTOSPACE_EVALUATED;
mesh->edit_mesh = nullptr;
BKE_mesh_runtime_reset(mesh);
memset(&mesh->runtime, 0, sizeof(mesh->runtime));
BKE_mesh_runtime_init_data(mesh);
/* happens with old files */
if (mesh->mselect == nullptr) {

View File

@@ -45,17 +45,54 @@
* \{ */
/**
* Default values defined at read time.
* \brief Initialize the runtime mutexes of the given mesh.
*
* Any existing mutexes will be overridden.
*/
void BKE_mesh_runtime_reset(Mesh *mesh)
static void mesh_runtime_init_mutexes(Mesh *mesh)
{
memset(&mesh->runtime, 0, sizeof(mesh->runtime));
mesh->runtime.eval_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime eval_mutex");
BLI_mutex_init(mesh->runtime.eval_mutex);
mesh->runtime.render_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime render_mutex");
BLI_mutex_init(mesh->runtime.render_mutex);
}
/**
* \brief free the mutexes of the given mesh runtime.
*/
static void mesh_runtime_free_mutexes(Mesh *mesh)
{
if (mesh->runtime.eval_mutex != NULL) {
BLI_mutex_end(mesh->runtime.eval_mutex);
MEM_freeN(mesh->runtime.eval_mutex);
mesh->runtime.eval_mutex = NULL;
}
if (mesh->runtime.render_mutex != NULL) {
BLI_mutex_end(mesh->runtime.render_mutex);
MEM_freeN(mesh->runtime.render_mutex);
mesh->runtime.render_mutex = NULL;
}
}
/**
* \brief Initialize the runtime of the given mesh.
*
* Function expects that the runtime is already cleared.
*/
void BKE_mesh_runtime_init_data(Mesh *mesh)
{
mesh_runtime_init_mutexes(mesh);
}
/**
* \brief Free all data (and mutexes) inside the runtime of the given mesh.
*/
void BKE_mesh_runtime_free_data(Mesh *mesh)
{
BKE_mesh_runtime_clear_cache(mesh);
mesh_runtime_free_mutexes(mesh);
}
/* Clear all pointers which we don't want to be shared on copying the datablock.
* However, keep all the flags which defines what the mesh is (for example, that
* it's deformed only, or that its custom data layers are out of date.) */
@@ -71,25 +108,16 @@ void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int UNUSED(flag))
runtime->bvh_cache = NULL;
runtime->shrinkwrap_data = NULL;
mesh->runtime.eval_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime eval_mutex");
BLI_mutex_init(mesh->runtime.eval_mutex);
mesh->runtime.render_mutex = MEM_mallocN(sizeof(ThreadMutex), "mesh runtime render_mutex");
BLI_mutex_init(mesh->runtime.render_mutex);
mesh_runtime_init_mutexes(mesh);
}
/**
* \brief This function clears runtime cache of the given mesh.
*
* Call this function to recalculate runtime data when used.
*/
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
{
if (mesh->runtime.eval_mutex != NULL) {
BLI_mutex_end(mesh->runtime.eval_mutex);
MEM_freeN(mesh->runtime.eval_mutex);
mesh->runtime.eval_mutex = NULL;
}
if (mesh->runtime.render_mutex != NULL) {
BLI_mutex_end(mesh->runtime.render_mutex);
MEM_freeN(mesh->runtime.render_mutex);
mesh->runtime.render_mutex = NULL;
}
if (mesh->runtime.mesh_eval != NULL) {
mesh->runtime.mesh_eval->edit_mesh = NULL;
BKE_id_free(NULL, mesh->runtime.mesh_eval);

View File

@@ -87,7 +87,6 @@
#include "NOD_node_tree_ref.hh"
#include "NOD_shader.h"
#include "NOD_socket.h"
#include "NOD_socket_declarations.hh"
#include "NOD_texture.h"
#include "DEG_depsgraph.h"
@@ -131,6 +130,10 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree,
struct bNode *node,
const bool mute);
static FieldInferencingInterface *node_field_inferencing_interface_copy(
const FieldInferencingInterface &field_inferencing_interface);
static void node_field_inferencing_interface_free(
const FieldInferencingInterface *field_inferencing_interface);
static void ntree_init_data(ID *id)
{
@@ -243,13 +246,9 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
ntree_dst->interface_type = nullptr;
if (ntree_src->field_inferencing_interface) {
ntree_dst->field_inferencing_interface = new blender::nodes::FieldInferencingInterface(
ntree_dst->field_inferencing_interface = node_field_inferencing_interface_copy(
*ntree_src->field_inferencing_interface);
}
if (ntree_src->enum_inferencing_interface) {
ntree_dst->enum_inferencing_interface = new blender::nodes::EnumInferencingInterface(
*ntree_src->enum_inferencing_interface);
}
if (flag & LIB_ID_COPY_NO_PREVIEW) {
ntree_dst->preview = nullptr;
@@ -302,8 +301,7 @@ static void ntree_free_data(ID *id)
MEM_freeN(sock);
}
delete ntree->field_inferencing_interface;
delete ntree->enum_inferencing_interface;
node_field_inferencing_interface_free(ntree->field_inferencing_interface);
/* free preview hash */
if (ntree->previews) {
@@ -361,7 +359,6 @@ static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY:
case SOCK_ENUM:
break;
}
}
@@ -493,9 +490,6 @@ static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *so
case SOCK_MATERIAL:
BLO_write_struct(writer, bNodeSocketValueMaterial, sock->default_value);
break;
case SOCK_ENUM:
BLO_write_struct(writer, bNodeSocketValueEnum, sock->default_value);
break;
case __SOCK_MESH:
case SOCK_CUSTOM:
case SOCK_SHADER:
@@ -626,15 +620,6 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
}
BLO_write_struct_by_name(writer, node->typeinfo->storagename, storage);
}
else if (node->type == FN_NODE_ENUM) {
NodeFunctionEnum *storage = (NodeFunctionEnum *)node->storage;
BLO_write_struct(writer, NodeFunctionEnum, storage);
BLO_write_struct_list(writer, NodeFunctionEnumItem, &storage->items);
LISTBASE_FOREACH (NodeFunctionEnumItem *, item, &storage->items) {
BLO_write_string(writer, item->name);
BLO_write_string(writer, item->description);
}
}
else if (node->typeinfo != &NodeTypeUndefined) {
BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
}
@@ -697,10 +682,6 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
sock->total_inputs = 0; /* Clear runtime data set before drawing. */
sock->cache = nullptr;
sock->declaration = nullptr;
if (sock->type == SOCK_ENUM) {
bNodeSocketValueEnum *socket_value = (bNodeSocketValueEnum *)sock->default_value;
socket_value->items = nullptr;
}
}
/* ntree itself has been read! */
@@ -716,7 +697,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
ntree->execdata = nullptr;
ntree->field_inferencing_interface = nullptr;
ntree->enum_inferencing_interface = nullptr;
BLO_read_data_address(reader, &ntree->adt);
BKE_animdata_blend_read_data(reader, ntree->adt);
@@ -821,17 +801,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
BLO_read_data_address(reader, &storage->string);
break;
}
case FN_NODE_ENUM: {
NodeFunctionEnum *storage = (NodeFunctionEnum *)node->storage;
BLO_read_data_address(reader, &storage->owner_node);
BLO_read_list(reader, &storage->items);
LISTBASE_FOREACH (NodeFunctionEnumItem *, item, &storage->items) {
BLO_read_data_address(reader, &item->owner_node);
BLO_read_data_address(reader, &item->name);
BLO_read_data_address(reader, &item->description);
}
break;
}
default:
break;
}
@@ -936,7 +905,6 @@ static void lib_link_node_socket(BlendLibReader *reader, Library *lib, bNodeSock
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY:
case SOCK_ENUM:
break;
}
}
@@ -1032,7 +1000,6 @@ static void expand_node_socket(BlendExpander *expander, bNodeSocket *sock)
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY:
case SOCK_ENUM:
break;
}
}
@@ -1160,6 +1127,8 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
BLI_strncpy(node->name, DATA_(ntype->ui_name), NODE_MAXSTR);
nodeUniqueName(ntree, node);
node_add_sockets_from_type(ntree, node, ntype);
if (ntype->initfunc != nullptr) {
ntype->initfunc(ntree, node);
}
@@ -1168,8 +1137,6 @@ static void node_init(const struct bContext *C, bNodeTree *ntree, bNode *node)
ntree->typeinfo->node_add_init(ntree, node);
}
node_add_sockets_from_type(ntree, node, ntype);
if (node->id) {
id_us_plus(node->id);
}
@@ -1447,7 +1414,7 @@ void nodeRegisterType(bNodeType *nt)
if (nt->declare && !nt->declaration_is_dynamic) {
if (nt->fixed_declaration == nullptr) {
nt->fixed_declaration = new blender::nodes::NodeDeclaration();
blender::nodes::NodeDeclarationBuilder builder{*nt->fixed_declaration, nullptr};
blender::nodes::NodeDeclarationBuilder builder{*nt->fixed_declaration};
nt->declare(builder);
}
}
@@ -1633,7 +1600,6 @@ static void socket_id_user_increment(bNodeSocket *sock)
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY:
case SOCK_ENUM:
break;
}
}
@@ -1687,7 +1653,6 @@ static void socket_id_user_decrement(bNodeSocket *sock)
case SOCK_CUSTOM:
case SOCK_SHADER:
case SOCK_GEOMETRY:
case SOCK_ENUM:
break;
}
}
@@ -1850,8 +1815,6 @@ const char *nodeStaticSocketType(int type, int subtype)
return "NodeSocketTexture";
case SOCK_MATERIAL:
return "NodeSocketMaterial";
case SOCK_ENUM:
return "NodeSocketEnum";
}
return nullptr;
}
@@ -1929,8 +1892,6 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype)
return "NodeSocketInterfaceTexture";
case SOCK_MATERIAL:
return "NodeSocketInterfaceMaterial";
case SOCK_ENUM:
return "NodeSocketInterfaceEnum";
}
return nullptr;
}
@@ -1964,8 +1925,6 @@ const char *nodeStaticSocketLabel(int type, int UNUSED(subtype))
return "Texture";
case SOCK_MATERIAL:
return "Material";
case SOCK_ENUM:
return "Enum";
}
return nullptr;
}
@@ -4094,7 +4053,7 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree *UNUSED(ntree), bNode *node)
}
if (node->typeinfo->declaration_is_dynamic) {
node->declaration = new blender::nodes::NodeDeclaration();
blender::nodes::NodeDeclarationBuilder builder{*node->declaration, node};
blender::nodes::NodeDeclarationBuilder builder{*node->declaration};
node->typeinfo->declare(builder);
}
else {
@@ -4118,16 +4077,6 @@ bool nodeDeclarationEnsure(bNodeTree *ntree, bNode *node)
return false;
}
void nodeUpdateFromDeclaration(bNodeTree *ntree, bNode *node)
{
if (!node->typeinfo->declaration_is_dynamic) {
return;
}
delete node->declaration;
node->declaration = nullptr;
node_verify_sockets(ntree, node, true);
}
/* ************** Node Clipboard *********** */
#define USE_NODE_CB_VALIDATE
@@ -4591,14 +4540,24 @@ void ntreeUpdateAllNew(Main *main)
}
}
/* Ideally this would first sort the trees based on their dependencies and then update every
* tree just once. */
ntreeUpdateTree(main, ntree);
ntreeUpdateTree(nullptr, ntree);
}
}
FOREACH_NODETREE_END;
}
static FieldInferencingInterface *node_field_inferencing_interface_copy(
const FieldInferencingInterface &field_inferencing_interface)
{
return new FieldInferencingInterface(field_inferencing_interface);
}
static void node_field_inferencing_interface_free(
const FieldInferencingInterface *field_inferencing_interface)
{
delete field_inferencing_interface;
}
namespace blender::bke::node_field_inferencing {
static bool is_field_socket_type(eNodeSocketDatatype type)
@@ -4611,7 +4570,7 @@ static bool is_field_socket_type(const SocketRef &socket)
return is_field_socket_type((eNodeSocketDatatype)socket.typeinfo()->type);
}
static bool update_field_inferencing(const NodeTreeRef &tree);
static bool update_field_inferencing(bNodeTree &btree);
static InputSocketFieldType get_interface_input_field_type(const NodeRef &node,
const InputSocketRef &socket)
@@ -4710,8 +4669,7 @@ static FieldInferencingInterface get_node_field_inferencing_interface(const Node
}
if (group->field_inferencing_interface == nullptr) {
/* Update group recursively. */
const NodeTreeRef group_tree{group};
update_field_inferencing(group_tree);
update_field_inferencing(*group);
}
return *group->field_inferencing_interface;
}
@@ -5069,10 +5027,12 @@ static void update_socket_shapes(const NodeTreeRef &tree,
}
}
static bool update_field_inferencing(const NodeTreeRef &tree)
static bool update_field_inferencing(bNodeTree &btree)
{
using namespace blender::nodes;
bNodeTree &btree = *tree.btree();
if (btree.type != NTREE_GEOMETRY) {
return false;
}
/* Create new inferencing interface for this node group. */
FieldInferencingInterface *new_inferencing_interface = new FieldInferencingInterface();
@@ -5081,6 +5041,9 @@ static bool update_field_inferencing(const NodeTreeRef &tree)
new_inferencing_interface->outputs.resize(BLI_listbase_count(&btree.outputs),
OutputFieldDependency::ForDataSource());
/* Create #NodeTreeRef to accelerate various queries on the node tree (e.g. linked sockets). */
const NodeTreeRef tree{&btree};
/* Keep track of the state of all sockets. The index into this array is #SocketRef::id(). */
Array<SocketFieldState> field_state_by_socket_id(tree.sockets().size());
@@ -5102,185 +5065,6 @@ static bool update_field_inferencing(const NodeTreeRef &tree)
} // namespace blender::bke::node_field_inferencing
namespace blender::bke::enum_inferencing {
using namespace blender::nodes;
static bool update_enum_inferencing(const NodeTreeRef &tree);
static EnumInputInferencingInfo get_input_enum_socket_inferencing_info(
const InputSocketRef &socket)
{
BLI_assert(socket.typeinfo()->type == SOCK_ENUM);
const NodeRef &node = socket.node();
if (node.is_group_node()) {
bNodeTree *group = (bNodeTree *)node.bnode()->id;
if (group == nullptr) {
return {};
}
if (!ntreeIsRegistered(group)) {
return {};
}
if (group->enum_inferencing_interface == nullptr) {
/* Update group recursively. */
const NodeTreeRef group_tree{group};
update_enum_inferencing(group_tree);
}
return group->enum_inferencing_interface->inputs[socket.index()];
}
if (node.is_reroute_node()) {
return {};
}
const decl::Enum &socket_decl = static_cast<const decl::Enum &>(*socket.bsocket()->declaration);
return socket_decl.inferencing_info();
}
struct EnumState {
std::shared_ptr<EnumItems> items;
int group_output_index = -1;
bool targets_are_invalid = false;
};
static bool enum_states_are_compatible(const EnumState &a, const EnumState &b)
{
if (a.items && b.items) {
return a.items->items() == b.items->items();
}
if (a.group_output_index == -1 || b.group_output_index == -1) {
return true;
}
if (a.group_output_index == b.group_output_index) {
return true;
}
return false;
}
static bool update_enum_inferencing(const NodeTreeRef &tree)
{
using namespace blender::nodes;
bNodeTree &btree = *tree.btree();
/* TODO: handle cyclic trees */
const NodeTreeRef::ToposortResult toposort_result = tree.toposort(
NodeTreeRef::ToposortDirection::RightToLeft);
Map<const SocketRef *, EnumState> state_by_socket;
for (const NodeRef *node : toposort_result.sorted_nodes) {
bNode &bnode = *node->bnode();
nodeDeclarationEnsure(&btree, &bnode);
if (node->is_group_output_node()) {
for (const InputSocketRef *input_socket : node->inputs()) {
if (input_socket->typeinfo()->type == SOCK_ENUM) {
state_by_socket.add(input_socket, EnumState{nullptr, input_socket->index()});
}
}
continue;
}
for (const OutputSocketRef *socket : node->outputs()) {
if (socket->typeinfo()->type != SOCK_ENUM) {
continue;
}
EnumState enum_state;
for (const InputSocketRef *target_socket : socket->directly_linked_sockets()) {
if (target_socket->is_available()) {
EnumState new_state = state_by_socket.lookup_default(target_socket, {});
if (enum_states_are_compatible(enum_state, new_state)) {
enum_state = new_state;
enum_state.targets_are_invalid = false;
}
else {
enum_state = {};
enum_state.targets_are_invalid = true;
break;
}
}
}
state_by_socket.add_new(socket, enum_state);
}
for (const InputSocketRef *socket : node->inputs()) {
if (socket->typeinfo()->type != SOCK_ENUM) {
continue;
}
EnumInputInferencingInfo inferencing_info = get_input_enum_socket_inferencing_info(*socket);
EnumState input_state;
if (inferencing_info.items) {
input_state.items = inferencing_info.items;
}
else {
int inference_index = inferencing_info.inference_index;
if (inference_index == -1) {
for (const OutputSocketRef *output_socket : node->outputs()) {
if (output_socket->typeinfo()->type == SOCK_ENUM) {
inference_index = output_socket->index();
break;
}
}
}
BLI_assert(inference_index >= 0);
const OutputSocketRef &output_socket = node->output(inference_index);
input_state = state_by_socket.lookup(&output_socket);
input_state.targets_are_invalid = false;
}
state_by_socket.add_new(socket, input_state);
}
}
for (const auto item : state_by_socket.items()) {
const SocketRef *socket = item.key;
const EnumState &state = item.value;
bNodeSocketValueEnum *socket_value = (bNodeSocketValueEnum *)socket->bsocket()->default_value;
if (state.items) {
socket_value->items = state.items->items();
}
else {
socket_value->items = nullptr;
}
socket_value->targets_are_invalid = state.targets_are_invalid;
}
EnumInferencingInterface *new_inferencing_interface = new EnumInferencingInterface();
new_inferencing_interface->inputs.resize(BLI_listbase_count(&btree.inputs));
for (const NodeRef *node : tree.nodes_by_type("NodeGroupInput")) {
for (const OutputSocketRef *output_socket : node->outputs().drop_back(1)) {
if (output_socket->typeinfo()->type != SOCK_ENUM) {
continue;
}
const EnumState &state = state_by_socket.lookup(output_socket);
EnumInputInferencingInfo &group_input_info =
new_inferencing_interface->inputs[output_socket->index()];
if (state.items) {
group_input_info.items = state.items;
}
else if (state.group_output_index >= 0) {
group_input_info.inference_index = state.group_output_index;
}
else {
group_input_info.items = std::make_shared<EnumItems>();
}
bNodeSocket *interface_socket = (bNodeSocket *)BLI_findlink(&btree.inputs,
output_socket->index());
BLI_assert(interface_socket->type == SOCK_ENUM);
bNodeSocketValueEnum *interface_value = (bNodeSocketValueEnum *)
interface_socket->default_value;
interface_value->items = group_input_info.items ? group_input_info.items->items() : nullptr;
}
}
delete btree.enum_inferencing_interface;
btree.enum_inferencing_interface = new_inferencing_interface;
/* TODO: Only return true when the interface changed. */
return true;
}
} // namespace blender::bke::enum_inferencing
/**
* \param tree_update_flag: #eNodeTreeUpdate enum.
*/
@@ -5349,7 +5133,6 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
/* node tree update tags override individual node update flags */
if ((node->update & NODE_UPDATE) || (ntree->update & NTREE_UPDATE)) {
nodeUpdateFromDeclaration(ntree, node);
if (node->typeinfo->updatefunc) {
node->typeinfo->updatefunc(ntree, node);
}
@@ -5372,19 +5155,10 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
int tree_user_update_flag = 0;
if (ntree->update & NTREE_UPDATE) {
if (ntree->type == NTREE_GEOMETRY) {
/* Create #NodeTreeRef to accelerate various queries on the node tree (e.g. linked
* sockets). */
const NodeTreeRef tree{ntree};
/* If the field interface of this node tree has changed, all node trees using
* this group will need to recalculate their interface as well. */
if (blender::bke::node_field_inferencing::update_field_inferencing(tree)) {
tree_user_update_flag |= NTREE_UPDATE_FIELD_INFERENCING;
}
if (blender::bke::enum_inferencing::update_enum_inferencing(tree)) {
/* TODO: Fix flag handling. */
tree_user_update_flag |= NTREE_UPDATE_FIELD_INFERENCING;
}
/* If the field interface of this node tree has changed, all node trees using
* this group will need to recalculate their interface as well. */
if (blender::bke::node_field_inferencing::update_field_inferencing(*ntree)) {
tree_user_update_flag |= NTREE_UPDATE_FIELD_INFERENCING;
}
}
@@ -5420,7 +5194,6 @@ void nodeUpdate(bNodeTree *ntree, bNode *node)
}
ntree->is_updating = true;
nodeUpdateFromDeclaration(ntree, node);
if (node->typeinfo->updatefunc) {
node->typeinfo->updatefunc(ntree, node);
}
@@ -5451,7 +5224,6 @@ bool nodeUpdateID(bNodeTree *ntree, ID *id)
if (node->id == id) {
changed = true;
node->update |= NODE_UPDATE_ID;
nodeUpdateFromDeclaration(ntree, node);
if (node->typeinfo->updatefunc) {
node->typeinfo->updatefunc(ntree, node);
}
@@ -6184,7 +5956,6 @@ static void registerFunctionNodes()
register_node_type_fn_align_euler_to_vector();
register_node_type_fn_boolean_math();
register_node_type_fn_enum();
register_node_type_fn_float_compare();
register_node_type_fn_float_to_int();
register_node_type_fn_input_bool();

View File

@@ -645,6 +645,10 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 25)) {
version_node_socket_index_animdata(bmain, NTREE_SHADER, SH_NODE_BSDF_PRINCIPLED, 4, 2, 25);
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 26)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *tool_settings = scene->toolsettings;
@@ -780,7 +784,6 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
{
/* Keep this block, even when empty. */
version_node_socket_index_animdata(bmain, NTREE_SHADER, SH_NODE_BSDF_PRINCIPLED, 4, 2, 25);
}
}

View File

@@ -404,16 +404,13 @@ void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges)
*/
static void bm_mesh_edges_sharp_tag(BMesh *bm,
const float (*fnos)[3],
const float split_angle,
float split_angle_cos,
const bool do_sharp_edges_tag)
{
BMIter eiter;
BMEdge *e;
int i;
const bool check_angle = (split_angle < (float)M_PI);
const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
if (fnos) {
BM_mesh_elem_index_ensure(bm, BM_FACE);
}
@@ -451,7 +448,7 @@ void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle)
return;
}
bm_mesh_edges_sharp_tag(bm, NULL, split_angle, true);
bm_mesh_edges_sharp_tag(bm, NULL, cosf(split_angle), true);
}
/** \} */
@@ -1110,11 +1107,13 @@ static void bm_mesh_loops_calc_normals__single_threaded(BMesh *bm,
const short (*clnors_data)[2],
const int cd_loop_clnors_offset,
const bool do_rebuild,
const float split_angle)
const float split_angle_cos)
{
BMIter fiter;
BMFace *f_curr;
const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
/* When false the caller must have already tagged the edges. */
const bool do_edge_tag = (split_angle_cos != EDGE_TAG_FROM_SPLIT_ANGLE_BYPASS);
MLoopNorSpaceArray _lnors_spacearr = {NULL};
@@ -1155,7 +1154,9 @@ static void bm_mesh_loops_calc_normals__single_threaded(BMesh *bm,
/* Always tag edges based on winding & sharp edge flag
* (even when the auto-smooth angle doesn't need to be calculated). */
bm_mesh_edges_sharp_tag(bm, fnos, has_clnors ? (float)M_PI : split_angle, false);
if (do_edge_tag) {
bm_mesh_edges_sharp_tag(bm, fnos, has_clnors ? -1.0f : split_angle_cos, false);
}
/* We now know edges that can be smoothed (they are tagged),
* and edges that will be hard (they aren't).
@@ -1308,12 +1309,9 @@ static void bm_mesh_loops_calc_normals__multi_threaded(BMesh *bm,
const short (*clnors_data)[2],
const int cd_loop_clnors_offset,
const bool do_rebuild,
const float split_angle)
const float split_angle_cos)
{
const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
const bool check_angle = (split_angle < (float)M_PI);
const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
MLoopNorSpaceArray _lnors_spacearr = {NULL};
{
@@ -1387,7 +1385,7 @@ static void bm_mesh_loops_calc_normals(BMesh *bm,
const short (*clnors_data)[2],
const int cd_loop_clnors_offset,
const bool do_rebuild,
const float split_angle)
const float split_angle_cos)
{
if (bm->totloop < BM_OMP_LIMIT) {
bm_mesh_loops_calc_normals__single_threaded(bm,
@@ -1398,7 +1396,7 @@ static void bm_mesh_loops_calc_normals(BMesh *bm,
clnors_data,
cd_loop_clnors_offset,
do_rebuild,
split_angle);
split_angle_cos);
}
else {
bm_mesh_loops_calc_normals__multi_threaded(bm,
@@ -1409,7 +1407,7 @@ static void bm_mesh_loops_calc_normals(BMesh *bm,
clnors_data,
cd_loop_clnors_offset,
do_rebuild,
split_angle);
split_angle_cos);
}
}
@@ -1620,7 +1618,7 @@ static void bm_mesh_loops_custom_normals_set(BMesh *bm,
/* Tag smooth edges and set lnos from vnos when they might be completely smooth...
* When using custom loop normals, disable the angle feature! */
bm_mesh_edges_sharp_tag(bm, fnos, (float)M_PI, false);
bm_mesh_edges_sharp_tag(bm, fnos, -1.0f, false);
/* Finish computing lnos by accumulating face normals
* in each fan of faces defined by sharp edges. */
@@ -1751,7 +1749,7 @@ void BM_loops_calc_normal_vcos(BMesh *bm,
clnors_data,
cd_loop_clnors_offset,
do_rebuild,
has_clnors ? (float)M_PI : split_angle);
has_clnors ? -1.0f : cosf(split_angle));
}
else {
BLI_assert(!r_lnors_spacearr);

View File

@@ -66,7 +66,7 @@ set(SRC
interface_region_menu_popup.c
interface_region_popover.c
interface_region_popup.c
interface_region_search.c
interface_region_search.cc
interface_region_tooltip.c
interface_regions.c
interface_style.c

View File

@@ -397,8 +397,8 @@ typedef struct uiHandleButtonData {
float vec[3], origvec[3];
ColorBand *coba;
/* Tool-tip. */
uint tooltip_force : 1;
/* True when alt is held and the preference for displaying tooltips should be ignored. */
bool tooltip_force;
/* auto open */
bool used_mouse;

View File

@@ -23,9 +23,9 @@
* Search Box Region & Interaction
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include "DNA_ID.h"
#include "MEM_guardedalloc.h"
@@ -84,7 +84,7 @@ struct uiSearchItems {
void *active;
};
typedef struct uiSearchboxData {
struct uiSearchboxData {
rcti bbox;
uiFontStyle fstyle;
uiSearchItems items;
@@ -102,7 +102,7 @@ typedef struct uiSearchboxData {
* Used so we can show leading text to menu items less prominently (not related to 'use_sep').
*/
const char *sep_string;
} uiSearchboxData;
};
#define SEARCH_ITEMS 10
@@ -166,9 +166,9 @@ bool UI_search_item_add(uiSearchItems *items,
if (name_prefix_offset != 0) {
/* Lazy initialize, as this isn't used often. */
if (items->name_prefix_offsets == NULL) {
items->name_prefix_offsets = MEM_callocN(
items->maxitem * sizeof(*items->name_prefix_offsets), "search name prefix offsets");
if (items->name_prefix_offsets == nullptr) {
items->name_prefix_offsets = (uint8_t *)MEM_callocN(
items->maxitem * sizeof(*items->name_prefix_offsets), __func__);
}
items->name_prefix_offsets[items->totitem] = name_prefix_offset;
}
@@ -198,7 +198,7 @@ int UI_searchbox_size_x(void)
int UI_search_items_find_index(uiSearchItems *items, const char *name)
{
if (items->name_prefix_offsets != NULL) {
if (items->name_prefix_offsets != nullptr) {
for (int i = 0; i < items->totitem; i++) {
if (STREQ(name, items->names[i] + items->name_prefix_offsets[i])) {
return i;
@@ -218,7 +218,7 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name)
/* region is the search box itself */
static void ui_searchbox_select(bContext *C, ARegion *region, uiBut *but, int step)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
/* apply step */
data->active += step;
@@ -285,14 +285,14 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr
int ui_searchbox_find_index(ARegion *region, const char *name)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
return UI_search_items_find_index(&data->items, name);
}
/* x and y in screen-coords. */
bool ui_searchbox_inside(ARegion *region, const int xy[2])
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
return BLI_rcti_isect_pt(&data->bbox, xy[0] - region->winrct.xmin, xy[1] - region->winrct.ymin);
}
@@ -300,12 +300,12 @@ bool ui_searchbox_inside(ARegion *region, const int xy[2])
/* string validated to be of correct length (but->hardmax) */
bool ui_searchbox_apply(uiBut *but, ARegion *region)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
uiButSearch *search_but = (uiButSearch *)but;
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
search_but->item_active = NULL;
search_but->item_active = nullptr;
if (data->active != -1) {
const char *name = data->items.names[data->active] +
@@ -314,7 +314,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
data->items.name_prefix_offsets[data->active] :
0);
const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : nullptr;
/* Search button with dynamic string properties may have their own method of applying
* the search results, so only copy the result if there is a proper space for it. */
@@ -356,7 +356,7 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
}
ARegion *searchbox_region = UI_region_searchbox_region_get(region);
uiSearchboxData *data = searchbox_region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(searchbox_region->regiondata);
BLI_assert(data->items.pointers[data->active] == search_but->item_active);
@@ -367,13 +367,13 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
C, region, &rect, search_but->arg, search_but->item_active);
}
}
return NULL;
return nullptr;
}
bool ui_searchbox_event(
bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
uiButSearch *search_but = (uiButSearch *)but;
int type = event->type, val = event->val;
bool handled = false;
@@ -481,7 +481,7 @@ static void ui_searchbox_update_fn(bContext *C,
void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset)
{
uiButSearch *search_but = (uiButSearch *)but;
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
@@ -499,7 +499,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
if (search_but->items_update_fn && search_but->item_active) {
data->items.active = search_but->item_active;
ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
data->items.active = NULL;
data->items.active = nullptr;
/* found active item, calculate real offset by centering it */
if (data->items.totitem) {
@@ -538,7 +538,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
/* Never include the prefix in the button. */
(data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] :
0);
const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : nullptr;
if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
data->active = a;
break;
@@ -558,7 +558,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str)
{
uiButSearch *search_but = (uiButSearch *)but;
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
int match = AUTOCOMPLETE_NO_MATCH;
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
@@ -569,7 +569,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *st
ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
match = UI_autocomplete_end(data->items.autocpl, str);
data->items.autocpl = NULL;
data->items.autocpl = nullptr;
}
return match;
@@ -577,7 +577,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *st
static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
/* pixel space */
wmOrtho2_region_pixelspace(region);
@@ -630,7 +630,7 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region)
const int state = ((a == data->active) ? UI_ACTIVE : 0) | data->items.states[a];
char *name = data->items.names[a];
int icon = data->items.icons[a];
char *name_sep_test = NULL;
char *name_sep_test = nullptr;
uiMenuItemSeparatorType separator_type = UI_MENU_ITEM_SEPARATOR_NONE;
if (data->use_shortcut_sep) {
@@ -652,15 +652,15 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region)
}
/* Simple menu item. */
ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, separator_type, NULL);
ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, separator_type, nullptr);
}
else {
/* Split menu item, faded text before the separator. */
char *name_sep = NULL;
char *name_sep = nullptr;
do {
name_sep = name_sep_test;
name_sep_test = strstr(name_sep + search_sep_len, data->sep_string);
} while (name_sep_test != NULL);
} while (name_sep_test != nullptr);
name_sep += search_sep_len;
const char name_sep_prev = *name_sep;
@@ -683,7 +683,7 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region)
}
/* The previous menu item draws the active selection. */
ui_draw_menu_item(&data->fstyle, &rect, name_sep, icon, state, separator_type, NULL);
ui_draw_menu_item(&data->fstyle, &rect, name_sep, icon, state, separator_type, nullptr);
}
}
/* indicate more */
@@ -705,7 +705,7 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region)
static void ui_searchbox_region_free_fn(ARegion *region)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
/* free search data */
for (int a = 0; a < data->items.maxitem; a++) {
@@ -716,12 +716,12 @@ static void ui_searchbox_region_free_fn(ARegion *region)
MEM_freeN(data->items.icons);
MEM_freeN(data->items.states);
if (data->items.name_prefix_offsets != NULL) {
if (data->items.name_prefix_offsets != nullptr) {
MEM_freeN(data->items.name_prefix_offsets);
}
MEM_freeN(data);
region->regiondata = NULL;
region->regiondata = nullptr;
}
static ARegion *ui_searchbox_create_generic_ex(bContext *C,
@@ -746,7 +746,7 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
region->type = &type;
/* create searchbox data */
uiSearchboxData *data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
uiSearchboxData *data = (uiSearchboxData *)MEM_callocN(sizeof(uiSearchboxData), __func__);
/* set font, get bb */
data->fstyle = style->widget; /* copy struct */
@@ -767,7 +767,7 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
data->prv_cols = but->a2;
}
if (but->optype != NULL || use_shortcut_sep) {
if (but->optype != nullptr || use_shortcut_sep) {
data->use_shortcut_sep = true;
}
data->sep_string = search_but->item_sep_string;
@@ -881,13 +881,13 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C,
/* In case the button's string is dynamic, make sure there are buffers available. */
data->items.maxstrlen = but->hardmax == 0 ? UI_MAX_NAME_STR : but->hardmax;
data->items.totitem = 0;
data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
data->items.states = MEM_callocN(data->items.maxitem * sizeof(int), "search flags");
data->items.name_prefix_offsets = NULL; /* Lazy initialized as needed. */
data->items.names = (char **)MEM_callocN(data->items.maxitem * sizeof(void *), __func__);
data->items.pointers = (void **)MEM_callocN(data->items.maxitem * sizeof(void *), __func__);
data->items.icons = (int *)MEM_callocN(data->items.maxitem * sizeof(int), __func__);
data->items.states = (int *)MEM_callocN(data->items.maxitem * sizeof(int), __func__);
data->items.name_prefix_offsets = nullptr; /* Lazy initialized as needed. */
for (int i = 0; i < data->items.maxitem; i++) {
data->items.names[i] = MEM_callocN(data->items.maxstrlen + 1, "search pointers");
data->items.names[i] = (char *)MEM_callocN(data->items.maxstrlen + 1, __func__);
}
return region;
@@ -924,7 +924,7 @@ static void str_tolower_titlecaps_ascii(char *str, const size_t len)
static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARegion *region)
{
uiSearchboxData *data = region->regiondata;
uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata);
/* pixel space */
wmOrtho2_region_pixelspace(region);
@@ -952,10 +952,10 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
{
const int state = ((a == data->active) ? UI_ACTIVE : 0) | data->items.states[a];
wmOperatorType *ot = data->items.pointers[a];
wmOperatorType *ot = static_cast<wmOperatorType *>(data->items.pointers[a]);
char text_pre[128];
char *text_pre_p = strstr(ot->idname, "_OT_");
if (text_pre_p == NULL) {
const char *text_pre_p = strstr(ot->idname, "_OT_");
if (text_pre_p == nullptr) {
text_pre[0] = '\0';
}
else {
@@ -975,7 +975,7 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
data->items.icons[a],
state,
UI_MENU_ITEM_SEPARATOR_NONE,
NULL);
nullptr);
ui_draw_menu_item(&data->fstyle,
&rect_post,
data->items.names[a],
@@ -983,7 +983,7 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
state,
data->use_shortcut_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT :
UI_MENU_ITEM_SEPARATOR_NONE,
NULL);
nullptr);
}
}
/* indicate more */
@@ -1044,17 +1044,17 @@ void ui_but_search_refresh(uiButSearch *search_but)
return;
}
uiSearchItems *items = MEM_callocN(sizeof(uiSearchItems), "search items");
uiSearchItems *items = (uiSearchItems *)MEM_callocN(sizeof(uiSearchItems), __func__);
/* setup search struct */
items->maxitem = 10;
items->maxstrlen = 256;
items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names");
items->names = (char **)MEM_callocN(items->maxitem * sizeof(void *), __func__);
for (int i = 0; i < items->maxitem; i++) {
items->names[i] = MEM_callocN(but->hardmax + 1, "search names");
items->names[i] = (char *)MEM_callocN(but->hardmax + 1, __func__);
}
ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items);
ui_searchbox_update_fn((bContext *)but->block->evil_C, search_but, but->drawstr, items);
if (!search_but->results_are_suggestions) {
/* Only red-alert when we are sure of it, this can miss cases when >10 matches. */

View File

@@ -22,9 +22,17 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* interface_region_menu_popup.c */
uint ui_popup_menu_hash(const char *str);
/* interface_regions_intern.h */
ARegion *ui_region_temp_add(bScreen *screen);
void ui_region_temp_remove(struct bContext *C, bScreen *screen, ARegion *region);
#ifdef __cplusplus
}
#endif

View File

@@ -1348,7 +1348,7 @@ void UI_view2d_dot_grid_draw(const View2D *v2d,
const float min_step,
const int grid_levels)
{
BLI_assert(grid_levels > 0 && grid_levels < 10);
BLI_assert(grid_levels >= 0 && grid_levels < 10);
const float zoom_x = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
const float zoom_normalized = (zoom_x - v2d->minzoom) / (v2d->maxzoom - v2d->minzoom);

View File

@@ -3472,7 +3472,6 @@ static const float std_node_socket_colors[][4] = {
{0.96, 0.96, 0.96, 1.0}, /* SOCK_COLLECTION */
{0.62, 0.31, 0.64, 1.0}, /* SOCK_TEXTURE */
{0.92, 0.46, 0.51, 1.0}, /* SOCK_MATERIAL */
{0.00, 0.00, 0.00, 1.0}, /* SOCK_ENUM */
};
/* common color callbacks for standard types */
@@ -3691,10 +3690,6 @@ static void std_node_socket_draw(
uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
break;
}
case SOCK_ENUM: {
uiItemR(layout, ptr, "default_value", DEFAULT_FLAGS, text, 0);
break;
}
default:
node_socket_button_label(C, layout, ptr, node_ptr, text);
break;
@@ -3732,8 +3727,7 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout
}
case SOCK_BOOLEAN:
case SOCK_RGBA:
case SOCK_STRING:
case SOCK_ENUM: {
case SOCK_STRING: {
uiItemR(col, ptr, "default_value", DEFAULT_FLAGS, IFACE_("Default"), 0);
break;
}
@@ -4450,12 +4444,6 @@ void node_draw_link(const bContext *C, View2D *v2d, SpaceNode *snode, bNodeLink
th_col1 = th_col2 = th_col3 = TH_REDALERT;
}
}
if (link->fromsock && link->fromsock->type == SOCK_ENUM) {
bNodeSocketValueEnum *socket_value = (bNodeSocketValueEnum *)link->fromsock->default_value;
if (socket_value->targets_are_invalid) {
th_col1 = th_col2 = th_col3 = TH_REDALERT;
}
}
node_draw_link_bezier(C, v2d, snode, link, th_col1, th_col2, th_col3);
}

View File

@@ -419,10 +419,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
uiLayout *row = uiLayoutRow(layout, true);
uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
const char *socket_label = nodeSocketLabel(nsock);
if (node->typeinfo->draw_socket == NULL ||
!node->typeinfo->draw_socket(row, C, ntree, node, nsock)) {
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(socket_label));
}
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(socket_label));
UI_block_align_end(node->block);
UI_block_layout_resolve(node->block, nullptr, &buty);
@@ -557,11 +554,8 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
uiLayout *row = uiLayoutRow(layout, true);
if (node->typeinfo->draw_socket == NULL ||
!node->typeinfo->draw_socket(row, C, ntree, node, nsock)) {
const char *socket_label = nodeSocketLabel(nsock);
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(socket_label));
}
const char *socket_label = nodeSocketLabel(nsock);
nsock->typeinfo->draw((bContext *)C, row, &sockptr, &nodeptr, IFACE_(socket_label));
UI_block_align_end(node->block);
UI_block_layout_resolve(node->block, nullptr, &buty);

View File

@@ -1335,8 +1335,6 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* add modal handler */
WM_event_add_modal_handler(C, op);
ntreeUpdateTree(bmain, snode->edittree);
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
@@ -2180,7 +2178,6 @@ static int get_main_socket_priority(const bNodeSocket *socket)
case SOCK_COLLECTION:
case SOCK_TEXTURE:
case SOCK_MATERIAL:
case SOCK_ENUM:
return 5;
}
return -1;

View File

@@ -377,7 +377,7 @@ static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
using namespace blender::nodes;
r_node_decl.emplace(NodeDeclaration());
NodeDeclarationBuilder node_decl_builder{*r_node_decl, nullptr};
NodeDeclarationBuilder node_decl_builder{*r_node_decl};
arg->node_type->declare(node_decl_builder);
Span<SocketDeclarationPtr> socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs() :
r_node_decl->outputs();

View File

@@ -191,7 +191,6 @@ typedef enum eNodeSocketDatatype {
SOCK_COLLECTION = 11,
SOCK_TEXTURE = 12,
SOCK_MATERIAL = 13,
SOCK_ENUM = 14,
} eNodeSocketDatatype;
/* Socket shape. */
@@ -478,13 +477,10 @@ typedef struct bNodeLink {
#ifdef __cplusplus
namespace blender::nodes {
struct FieldInferencingInterface;
struct EnumInferencingInterface;
} // namespace blender::nodes
}
using FieldInferencingInterfaceHandle = blender::nodes::FieldInferencingInterface;
using EnumInferencingInterfaceHandle = blender::nodes::EnumInferencingInterface;
#else
typedef struct FieldInferencingInterfaceHandle FieldInferencingInterfaceHandle;
typedef struct EnumInferencingInterfaceHandle EnumInferencingInterfaceHandle;
#endif
/* the basis for a Node tree, all links and nodes reside internal here */
@@ -511,7 +507,6 @@ typedef struct bNodeTree {
ListBase nodes, links;
/** Information about how inputs and outputs of the node group interact with fields. */
FieldInferencingInterfaceHandle *field_inferencing_interface;
EnumInferencingInterfaceHandle *enum_inferencing_interface;
/** Set init on fileread. */
int type, init;
@@ -684,17 +679,6 @@ typedef struct bNodeSocketValueMaterial {
struct Material *value;
} bNodeSocketValueMaterial;
/* TODO: Add something to help with versioning for built-in enums. */
typedef struct bNodeSocketValueEnum {
int value;
char targets_are_invalid;
char _pad[3];
/**
* Possible items for the enum. This is only runtime data and is not owned by the socket.
*/
const struct EnumPropertyItem *items;
} bNodeSocketValueEnum;
/* Data structs, for node->storage. */
enum {
CMP_NODE_MASKTYPE_ADD = 0,
@@ -1622,21 +1606,6 @@ typedef struct NodeGeometryViewer {
int8_t data_type;
} NodeGeometryViewer;
typedef struct NodeFunctionEnumItem {
struct NodeFunctionEnumItem *next, *prev;
bNode *owner_node;
int value;
char _pad[4];
char *name;
char *description;
} NodeFunctionEnumItem;
typedef struct NodeFunctionEnum {
bNode *owner_node;
/** NodeFunctionEnumItem. */
ListBase items;
} NodeFunctionEnum;
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0
#define NODE_SCRIPT_EXTERNAL 1

View File

@@ -449,8 +449,6 @@ extern StructRNA RNA_MusgraveTexture;
extern StructRNA RNA_NlaStrip;
extern StructRNA RNA_NlaTrack;
extern StructRNA RNA_Node;
extern StructRNA RNA_NodeFunctionEnum;
extern StructRNA RNA_NodeFunctionEnumItem;
extern StructRNA RNA_NodeInstanceHash;
extern StructRNA RNA_NodeLink;
extern StructRNA RNA_NodeOutputFileSlotFile;

View File

@@ -78,7 +78,6 @@ static const EnumPropertyItem node_socket_data_type_items[] = {
{SOCK_COLLECTION, "COLLECTION", 0, "Collection", ""},
{SOCK_TEXTURE, "TEXTURE", 0, "Texture", ""},
{SOCK_MATERIAL, "MATERIAL", 0, "Material", ""},
{SOCK_ENUM, "ENUM", 0, "Enum", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -107,7 +106,6 @@ static const EnumPropertyItem node_socket_type_items[] = {
{SOCK_COLLECTION, "COLLECTION", 0, "Collection", ""},
{SOCK_TEXTURE, "TEXTURE", 0, "Texture", ""},
{SOCK_MATERIAL, "MATERIAL", 0, "Material", ""},
{SOCK_ENUM, "ENUM", 0, "Enum", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -1237,8 +1235,8 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
ntreeTexCheckCyclics(ntree);
}
nodeUpdate(ntree, node);
ntreeUpdateTree(CTX_data_main(C), ntree);
nodeUpdate(ntree, node);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
return node;
@@ -2059,8 +2057,7 @@ static bool switch_type_supported(const EnumPropertyItem *item)
SOCK_COLLECTION,
SOCK_TEXTURE,
SOCK_MATERIAL,
SOCK_IMAGE,
SOCK_ENUM);
SOCK_IMAGE);
}
static const EnumPropertyItem *rna_GeometryNodeSwitch_type_itemf(bContext *UNUSED(C),
@@ -3441,7 +3438,6 @@ static bool rna_NodeInternal_poll_instance(bNode *node, bNodeTree *ntree)
static void rna_NodeInternal_update(ID *id, bNode *node)
{
bNodeTree *ntree = (bNodeTree *)id;
nodeUpdateFromDeclaration(ntree, node);
if (node->typeinfo->updatefunc) {
node->typeinfo->updatefunc(ntree, node);
}
@@ -4573,58 +4569,6 @@ bool rna_NodeSocketMaterial_default_value_poll(PointerRNA *UNUSED(ptr), PointerR
return ma->gp_style == NULL;
}
static void rna_nodeFunctionEnum_update_enum(Main *bmain, bNodeTree *ntree, bNode *node)
{
ntree->update |= NTREE_UPDATE_FIELD_INFERENCING;
nodeUpdate(ntree, node);
ED_node_tag_update_nodetree(bmain, ntree, node);
ntreeUpdateTree(bmain, ntree);
}
static void rna_NodeFunctionEnumItem_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
NodeFunctionEnumItem *item = (NodeFunctionEnumItem *)ptr->data;
bNode *node = item->owner_node;
rna_nodeFunctionEnum_update_enum(bmain, (bNodeTree *)ptr->owner_id, node);
}
static NodeFunctionEnumItem *rna_NodeFunctionEnumItems_items_new(ID *id, bNode *node, bContext *C)
{
NodeFunctionEnum *storage = node->storage;
NodeFunctionEnumItem *item = MEM_callocN(sizeof(NodeFunctionEnumItem), __func__);
item->owner_node = node;
BLI_addtail(&storage->items, item);
PointerRNA node_ptr;
RNA_pointer_create(id, &RNA_Node, node, &node_ptr);
Main *bmain = CTX_data_main(C);
bNodeTree *ntree = (bNodeTree *)id;
rna_nodeFunctionEnum_update_enum(bmain, ntree, node);
return item;
}
static const EnumPropertyItem *rna_NodeSocketEnum_items(bContext *UNUSED(C),
PointerRNA *ptr,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
*r_free = false;
bNodeSocket *socket = ptr->data;
bNodeSocketValueEnum *storage = (bNodeSocketValueEnum *)socket->default_value;
if (storage->items == NULL) {
return DummyRNA_NULL_items;
}
return storage->items;
}
static void rna_NodeSocketEnum_set(PointerRNA *ptr, int value)
{
bNodeSocket *socket = ptr->data;
bNodeSocketValueEnum *storage = (bNodeSocketValueEnum *)socket->default_value;
storage->value = value;
}
#else
static const EnumPropertyItem prop_image_layer_items[] = {
@@ -5120,60 +5064,6 @@ static void def_fn_input_string(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void rna_def_fn_enum_item(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "NodeFunctionEnumItem", NULL);
RNA_def_struct_ui_text(srna, "Node Function Enum Item", "");
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Value", "Internal identifier if the enum item");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeFunctionEnumItem_update");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Display name of the enum item");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeFunctionEnumItem_update");
prop = RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Description", "Tooltip for the enum item");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeFunctionEnumItem_update");
}
static void rna_def_fn_enum_items_api(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "NodeFunctionEnumItems");
srna = RNA_def_struct(brna, "NodeFunctionEnumItems", NULL);
RNA_def_struct_sdna(srna, "bNode");
RNA_def_struct_ui_text(srna, "Enum Items", "");
func = RNA_def_function(srna, "new", "rna_NodeFunctionEnumItems_items_new");
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_SELF_ID);
RNA_def_function_ui_description(func, "Add a new enum item");
parm = RNA_def_pointer(func, "item", "NodeFunctionEnumItem", "", "New enum item");
RNA_def_function_return(func, parm);
}
static void def_fn_enum(BlenderRNA *brna, StructRNA *srna)
{
PropertyRNA *prop;
rna_def_fn_enum_item(brna);
RNA_def_struct_sdna_from(srna, "NodeFunctionEnum", "storage");
prop = RNA_def_property(srna, "enum_items", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "items", NULL);
RNA_def_property_struct_type(prop, "NodeFunctionEnumItem");
RNA_def_property_ui_text(prop, "Items", "");
rna_def_fn_enum_items_api(brna, prop);
}
/* -- Shader Nodes ---------------------------------------------------------- */
static void def_sh_output(StructRNA *srna)
@@ -12070,47 +11960,6 @@ static void rna_def_node_socket_material(BlenderRNA *brna,
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
}
static void rna_def_node_socket_enum(BlenderRNA *brna,
const char *identifier,
const char *interface_idname)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, identifier, "NodeSocketStandard");
RNA_def_struct_ui_text(srna, "Enum Node Socket", "Enum socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
RNA_def_struct_sdna_from(srna, "bNodeSocketValueEnum", "default_value");
prop = RNA_def_property(srna, "default_value", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "value");
RNA_def_property_enum_funcs(prop, NULL, "rna_NodeSocketEnum_set", "rna_NodeSocketEnum_items");
RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
/* socket interface */
srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard");
RNA_def_struct_ui_text(srna, "Enum Node Socket Interface", "Enum socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
RNA_def_struct_sdna_from(srna, "bNodeSocketValueEnum", "default_value");
prop = RNA_def_property(srna, "default_value", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "value");
RNA_def_property_enum_funcs(prop, NULL, "rna_NodeSocketEnum_set", "rna_NodeSocketEnum_items");
RNA_def_property_enum_items(prop, DummyRNA_DEFAULT_items);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update");
RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL);
}
static void rna_def_node_socket_standard_types(BlenderRNA *brna)
{
/* XXX Workaround: Registered functions are not exposed in python by bpy,
@@ -12263,8 +12112,6 @@ static void rna_def_node_socket_standard_types(BlenderRNA *brna)
rna_def_node_socket_texture(brna, "NodeSocketTexture", "NodeSocketInterfaceTexture");
rna_def_node_socket_material(brna, "NodeSocketMaterial", "NodeSocketInterfaceMaterial");
rna_def_node_socket_enum(brna, "NodeSocketEnum", "NodeSocketInterfaceEnum");
}
static void rna_def_internal_node(BlenderRNA *brna)
@@ -13274,9 +13121,6 @@ void RNA_def_nodetree(BlenderRNA *brna)
/* needs brna argument, can't use NOD_static_types.h */ \
def_cmp_output_file(brna, srna); \
} \
if (ID == FN_NODE_ENUM) { \
def_fn_enum(brna, srna); \
} \
}
/* hack, don't want to add include path to RNA just for this, since in the future RNA types

View File

@@ -1049,17 +1049,6 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md)
continue;
}
}
bool has_geometry_output = false;
LISTBASE_FOREACH (const bNodeSocket *, socket, &nmd->node_group->outputs) {
if (socket->type == SOCK_GEOMETRY) {
has_geometry_output = true;
}
}
if (!has_geometry_output) {
BKE_modifier_set_error(ob, md, "Node group must have a geometry output");
}
}
static void modifyGeometry(ModifierData *md,
@@ -1078,6 +1067,7 @@ static void modifyGeometry(ModifierData *md,
if (tree.has_link_cycles()) {
BKE_modifier_set_error(ctx->object, md, "Node group has cycles");
geometry_set.clear();
return;
}
@@ -1085,17 +1075,23 @@ static void modifyGeometry(ModifierData *md,
Span<const NodeRef *> input_nodes = root_tree_ref.nodes_by_type("NodeGroupInput");
Span<const NodeRef *> output_nodes = root_tree_ref.nodes_by_type("NodeGroupOutput");
if (output_nodes.size() != 1) {
BKE_modifier_set_error(ctx->object, md, "Node group must have a single output node");
geometry_set.clear();
return;
}
const NodeRef &output_node = *output_nodes[0];
Span<const InputSocketRef *> group_outputs = output_node.inputs().drop_back(1);
if (group_outputs.is_empty()) {
BKE_modifier_set_error(ctx->object, md, "Node group must have an output socket");
geometry_set.clear();
return;
}
const InputSocketRef *first_output_socket = group_outputs[0];
if (first_output_socket->idname() != "NodeSocketGeometry") {
BKE_modifier_set_error(ctx->object, md, "Node group's first output must be a geometry");
geometry_set.clear();
return;
}

View File

@@ -139,7 +139,6 @@ set(SRC
function/nodes/node_fn_align_euler_to_vector.cc
function/nodes/node_fn_boolean_math.cc
function/nodes/node_fn_enum.cc
function/nodes/node_fn_float_compare.cc
function/nodes/node_fn_float_to_int.cc
function/nodes/node_fn_input_bool.cc

View File

@@ -24,7 +24,6 @@ void register_node_type_fn_legacy_random_float(void);
void register_node_type_fn_align_euler_to_vector(void);
void register_node_type_fn_boolean_math(void);
void register_node_type_fn_enum(void);
void register_node_type_fn_float_compare(void);
void register_node_type_fn_float_to_int(void);
void register_node_type_fn_input_bool(void);

View File

@@ -66,27 +66,6 @@ using fn::GVMutableArray_Typed;
using fn::GVMutableArrayPtr;
using geometry_nodes_eval_log::NodeWarningType;
/** Wrapper for an integer so that one can not perform various operations like addition on it. */
struct EnumValue {
int value;
friend std::ostream &operator<<(std::ostream &stream, const EnumValue &value)
{
stream << value.value;
return stream;
}
friend bool operator==(const EnumValue &a, const EnumValue &b)
{
return a.value == b.value;
}
uint64_t hash() const
{
return this->value;
}
};
/**
* This class exists to separate the memory management details of the geometry nodes evaluator
* from the node execution functions and related utilities.
@@ -160,8 +139,7 @@ class GeoNodeExecParams {
std::is_same_v<T, bool> ||
std::is_same_v<T, ColorGeometry4f> ||
std::is_same_v<T, float3> ||
std::is_same_v<T, std::string> ||
std::is_same_v<T, EnumValue>;
std::is_same_v<T, std::string>;
/**
* Get the input value for the input socket with the given identifier.
@@ -233,10 +211,6 @@ class GeoNodeExecParams {
const Field<T> &field = this->get_input<Field<T>>(identifier);
return fn::evaluate_constant_field(field);
}
else if constexpr (std::is_enum_v<T>) {
const int value = this->get_input<EnumValue>(identifier).value;
return (T)this->validate_enum_value(identifier, value);
}
else {
#ifdef DEBUG
this->check_input_access(identifier, &CPPType::get<T>());
@@ -380,8 +354,6 @@ class GeoNodeExecParams {
/* Find the active socket with the input name (not the identifier). */
const bNodeSocket *find_available_socket(const StringRef name) const;
const int validate_enum_value(StringRef identifier, const int value) const;
};
} // namespace blender::nodes

View File

@@ -243,13 +243,11 @@ class NodeDeclaration {
class NodeDeclarationBuilder {
private:
/** The node may be null. */
NodeDeclaration &declaration_;
const bNode *node_;
Vector<std::unique_ptr<BaseSocketDeclarationBuilder>> builders_;
public:
NodeDeclarationBuilder(NodeDeclaration &declaration, const bNode *node);
NodeDeclarationBuilder(NodeDeclaration &declaration);
/**
* All inputs support fields, and all outputs are fields if any of the inputs is a field.
@@ -260,12 +258,6 @@ class NodeDeclarationBuilder {
declaration_.is_function_node_ = value;
}
/** Return the node this declaration is build for. It may be null. */
const bNode *node() const
{
return node_;
}
template<typename DeclType>
typename DeclType::Builder &add_input(StringRef name, StringRef identifier = "");
template<typename DeclType>
@@ -399,9 +391,8 @@ inline const OutputFieldDependency &SocketDeclaration::output_field_dependency()
/** \name #NodeDeclarationBuilder Inline Methods
* \{ */
inline NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration,
const bNode *node)
: declaration_(declaration), node_(node)
inline NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration)
: declaration_(declaration)
{
}

View File

@@ -16,41 +16,12 @@
#pragma once
#include <functional>
#include "NOD_node_declaration.hh"
#include "RNA_types.h"
#include "BLI_color.hh"
#include "BLI_float3.hh"
#include "BLI_utility_mixins.hh"
namespace blender::nodes {
class EnumItems : NonCopyable, NonMovable {
private:
const EnumPropertyItem *items_;
std::function<void()> free_fn_;
public:
EnumItems();
EnumItems(const EnumPropertyItem *items, std::function<void()> free_fn);
~EnumItems();
const EnumPropertyItem *items() const;
};
struct EnumInputInferencingInfo {
std::shared_ptr<EnumItems> items;
int inference_index = -1;
};
struct EnumInferencingInterface {
Vector<EnumInputInferencingInfo> inputs;
};
} // namespace blender::nodes
namespace blender::nodes::decl {
@@ -194,32 +165,6 @@ class StringBuilder : public SocketDeclarationBuilder<String> {
StringBuilder &default_value(const std::string value);
};
class EnumBuilder;
class Enum : public SocketDeclaration {
private:
int default_value_ = 0;
EnumInputInferencingInfo inferencing_info_;
friend EnumBuilder;
public:
using Builder = EnumBuilder;
const EnumInputInferencingInfo &inferencing_info() const;
bNodeSocket &build(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out) const override;
bool matches(const bNodeSocket &socket) const override;
};
class EnumBuilder : public SocketDeclarationBuilder<Enum> {
public:
EnumBuilder &default_value(const int value);
EnumBuilder &static_items(const EnumPropertyItem *items);
EnumBuilder &dynamic_items(std::shared_ptr<EnumItems> items);
EnumBuilder &inference_items(const int output_index = -1);
};
class IDSocketDeclaration : public SocketDeclaration {
private:
const char *idname_;
@@ -393,18 +338,6 @@ inline StringBuilder &StringBuilder::default_value(std::string value)
/** \} */
/* -------------------------------------------------------------------- */
/** \name #EnumBuilder Inline Methods
* \{ */
inline EnumBuilder &EnumBuilder::default_value(const int value)
{
decl_->default_value_ = value;
return *this;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name #IDSocketDeclaration and Children Inline Methods
* \{ */

View File

@@ -268,7 +268,6 @@ DefNode(FunctionNode, FN_NODE_LEGACY_RANDOM_FLOAT, 0, "LEGACY_RANDOM_FLOAT", Leg
DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler To Vector", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_COMPARE_FLOATS, def_float_compare, "COMPARE_FLOATS", CompareFloats, "Compare Floats", "")
DefNode(FunctionNode, FN_NODE_ENUM, 0, "ENUM", Enum, "Enum", "")
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "")
DefNode(FunctionNode, FN_NODE_INPUT_COLOR, def_fn_input_color, "INPUT_COLOR", InputColor, "Color", "")

View File

@@ -1,206 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cmath>
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "NOD_geometry_exec.hh"
#include "node_function_util.hh"
namespace blender::nodes {
static void fn_node_enum_declare(NodeDeclarationBuilder &b)
{
const bNode *node = b.node();
if (node == nullptr) {
return;
}
b.add_output<decl::Int>("Index");
EnumPropertyItem *items = nullptr;
int tot_items = 0;
const NodeFunctionEnum *storage = (const NodeFunctionEnum *)node->storage;
LISTBASE_FOREACH (const NodeFunctionEnumItem *, item, &storage->items) {
b.add_output<decl::Bool>(item->name ? item->name : "Bool",
"item_" + std::to_string(item->value));
EnumPropertyItem enum_item = {0};
enum_item.identifier = BLI_strdup(item->name ? item->name : "");
enum_item.name = enum_item.identifier;
enum_item.description = BLI_strdup(item->description ? item->description : "");
enum_item.value = item->value;
RNA_enum_item_add(&items, &tot_items, &enum_item);
}
RNA_enum_item_end(&items, &tot_items);
std::shared_ptr<EnumItems> socket_items = std::make_shared<EnumItems>(
items, [tot_items, items]() {
for (const int i : IndexRange(tot_items - 1)) {
EnumPropertyItem &enum_item = items[i];
MEM_freeN((void *)enum_item.identifier);
MEM_freeN((void *)enum_item.description);
}
MEM_freeN(items);
});
b.add_input<decl::Enum>("Enum").dynamic_items(std::move(socket_items)).hide_label();
};
static bool fn_node_enum_draw_socket(uiLayout *layout,
const bContext *UNUSED(C),
bNodeTree *ntree,
bNode *node,
bNodeSocket *socket)
{
const int socket_index = BLI_findindex(&node->outputs, socket);
if (socket_index <= 0) {
return false;
}
NodeFunctionEnum *storage = (NodeFunctionEnum *)node->storage;
NodeFunctionEnumItem *item = (NodeFunctionEnumItem *)BLI_findlink(&storage->items,
socket_index - 1);
PointerRNA item_ptr;
RNA_pointer_create(&ntree->id, &RNA_NodeFunctionEnumItem, item, &item_ptr);
uiItemR(layout, &item_ptr, "name", 0, "", ICON_NONE);
return true;
}
static void fn_node_enum_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeFunctionEnum *data = (NodeFunctionEnum *)MEM_callocN(sizeof(NodeFunctionEnum), __func__);
data->owner_node = node;
node->storage = data;
}
static void fn_node_enum_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
uiItemStringO(layout, "Add", ICON_PLUS, "node.enum_item_add", "node_name", node->name);
}
class EnumFunction : public fn::MultiFunction {
private:
Vector<int> enum_values_;
fn::MFSignature signature_;
public:
EnumFunction(const bNode &node)
{
fn::MFSignatureBuilder signature{"Enum Function"};
signature.single_input<EnumValue>("Enum");
signature.single_output<int>("Index");
const NodeFunctionEnum *storage = (NodeFunctionEnum *)node.storage;
LISTBASE_FOREACH (const NodeFunctionEnumItem *, item, &storage->items) {
signature.single_output<bool>(item->name);
enum_values_.append(item->value);
}
signature_ = signature.build();
this->set_signature(&signature_);
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
{
const VArray<EnumValue> &enum_in = params.readonly_single_input<EnumValue>(0, "Enum");
MutableSpan<int> r_indices = params.uninitialized_single_output_if_required<int>(1, "Index");
if (!r_indices.is_empty()) {
for (const int i : mask) {
const int in_value = enum_in[i].value;
r_indices[i] = enum_values_.first_index_of_try(in_value);
}
}
for (const int enum_index : enum_values_.index_range()) {
MutableSpan<bool> r_bools = params.uninitialized_single_output_if_required<bool>(2 +
enum_index);
if (r_bools.is_empty()) {
continue;
}
const int enum_value = enum_values_[enum_index];
for (const int i : mask) {
const int in_value = enum_in[i].value;
r_bools[i] = in_value == enum_value;
}
}
}
};
static void fn_node_enum_build_multi_function(NodeMultiFunctionBuilder &builder)
{
builder.construct_and_set_matching_fn<EnumFunction>(builder.node());
}
static void fn_node_enum_copy_storage(bNodeTree *UNUSED(dest_ntree),
bNode *dst_node,
const bNode *src_node)
{
const NodeFunctionEnum *src_storage = (const NodeFunctionEnum *)src_node->storage;
NodeFunctionEnum *dst_storage = (NodeFunctionEnum *)MEM_dupallocN(src_storage);
dst_storage->owner_node = dst_node;
BLI_listbase_clear(&dst_storage->items);
LISTBASE_FOREACH (const NodeFunctionEnumItem *, src_item, &src_storage->items) {
NodeFunctionEnumItem *dst_item = (NodeFunctionEnumItem *)MEM_dupallocN(src_item);
dst_item->owner_node = dst_node;
dst_item->name = (char *)MEM_dupallocN(src_item->name);
dst_item->description = (char *)MEM_dupallocN(src_item->description);
BLI_addtail(&dst_storage->items, dst_item);
}
dst_node->storage = dst_storage;
}
static void fn_node_enum_free_storage(bNode *node)
{
NodeFunctionEnum *storage = (NodeFunctionEnum *)node->storage;
LISTBASE_FOREACH_MUTABLE (NodeFunctionEnumItem *, item, &storage->items) {
if (item->name) {
MEM_freeN(item->name);
}
if (item->description) {
MEM_freeN(item->description);
}
MEM_freeN(item);
}
MEM_freeN(storage);
}
} // namespace blender::nodes
void register_node_type_fn_enum()
{
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_ENUM, "Enum", NODE_CLASS_SCRIPT, 0);
node_type_storage(&ntype,
"NodeFunctionEnum",
blender::nodes::fn_node_enum_free_storage,
blender::nodes::fn_node_enum_copy_storage);
node_type_init(&ntype, blender::nodes::fn_node_enum_init);
ntype.declare = blender::nodes::fn_node_enum_declare;
ntype.declaration_is_dynamic = true;
ntype.build_multi_function = blender::nodes::fn_node_enum_build_multi_function;
ntype.draw_buttons = blender::nodes::fn_node_enum_layout;
ntype.draw_socket = blender::nodes::fn_node_enum_draw_socket;
nodeRegisterType(&ntype);
}

View File

@@ -110,8 +110,7 @@ static bool geometry_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype
SOCK_COLLECTION,
SOCK_TEXTURE,
SOCK_IMAGE,
SOCK_MATERIAL,
SOCK_ENUM);
SOCK_MATERIAL);
}
void register_node_tree_type_geo(void)

View File

@@ -31,25 +31,7 @@ namespace blender::nodes {
static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
{
static const EnumPropertyItem rna_node_geometry_collection_info_transform_space_items[] = {
{GEO_NODE_TRANSFORM_SPACE_ORIGINAL,
"ORIGINAL",
0,
"Original",
"Output the geometry relative to the collection offset"},
{GEO_NODE_TRANSFORM_SPACE_RELATIVE,
"RELATIVE",
0,
"Relative",
"Bring the input collection geometry into the modified object, maintaining the relative "
"position between the objects in the scene"},
{0, NULL, 0, NULL, NULL},
};
b.add_input<decl::Collection>(N_("Collection")).hide_label();
b.add_input<decl::Enum>(N_("Transform Space"))
.static_items(rna_node_geometry_collection_info_transform_space_items)
.hide_label();
b.add_input<decl::Bool>(N_("Separate Children"))
.description(
N_("Output each child of the collection as a separate instance, sorted alphabetically"));
@@ -60,6 +42,11 @@ static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
static void geo_node_collection_info_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
static void geo_node_collection_info_node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCollectionInfo *data = (NodeGeometryCollectionInfo *)MEM_callocN(
@@ -93,8 +80,10 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
return;
}
const bool use_relative_transform = params.get_input<GeometryNodeTransformSpace>(
"Transform Space") == GEO_NODE_TRANSFORM_SPACE_RELATIVE;
const bNode &bnode = params.node();
NodeGeometryCollectionInfo *node_storage = (NodeGeometryCollectionInfo *)bnode.storage;
const bool use_relative_transform = (node_storage->transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
@@ -180,5 +169,6 @@ void register_node_type_geo_collection_info()
node_free_standard_storage,
node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_collection_info_exec;
ntype.draw_buttons = blender::nodes::geo_node_collection_info_layout;
nodeRegisterType(&ntype);
}

View File

@@ -35,17 +35,15 @@ namespace blender::nodes {
static void geo_node_curve_fill_declare(NodeDeclarationBuilder &b)
{
static const EnumPropertyItem mode_items[] = {
{GEO_NODE_CURVE_FILL_MODE_TRIANGULATED, "TRIANGLES", 0, "Triangles", ""},
{GEO_NODE_CURVE_FILL_MODE_NGONS, "NGONS", 0, "N-gons", ""},
{0, NULL, 0, NULL, NULL},
};
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Enum>(N_("Mode")).static_items(mode_items);
b.add_output<decl::Geometry>(N_("Mesh"));
}
static void geo_node_curve_fill_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
static void geo_node_curve_fill_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryCurveFill *data = (NodeGeometryCurveFill *)MEM_callocN(sizeof(NodeGeometryCurveFill),
@@ -153,7 +151,8 @@ static void geo_node_curve_fill_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
const GeometryNodeCurveFillMode mode = params.get_input<GeometryNodeCurveFillMode>("Mode");
const NodeGeometryCurveFill &storage = *(const NodeGeometryCurveFill *)params.node().storage;
const GeometryNodeCurveFillMode mode = (GeometryNodeCurveFillMode)storage.mode;
geometry_set.modify_geometry_sets(
[&](GeometrySet &geometry_set) { curve_fill_calculate(geometry_set, mode); });
@@ -174,5 +173,6 @@ void register_node_type_geo_curve_fill()
&ntype, "NodeGeometryCurveFill", node_free_standard_storage, node_copy_standard_storage);
ntype.declare = blender::nodes::geo_node_curve_fill_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_curve_fill_exec;
ntype.draw_buttons = blender::nodes::geo_node_curve_fill_layout;
nodeRegisterType(&ntype);
}

View File

@@ -68,8 +68,6 @@ static void geo_node_switch_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Material>(N_("True"), "True_010");
b.add_input<decl::Image>(N_("False"), "False_011");
b.add_input<decl::Image>(N_("True"), "True_011");
b.add_input<decl::Enum>(N_("False"), "False_012");
b.add_input<decl::Enum>(N_("True"), "True_012");
b.add_output<decl::Float>(N_("Output")).dependent_field();
b.add_output<decl::Int>(N_("Output"), "Output_001").dependent_field();
@@ -83,7 +81,6 @@ static void geo_node_switch_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Texture>(N_("Output"), "Output_009");
b.add_output<decl::Material>(N_("Output"), "Output_010");
b.add_output<decl::Image>(N_("Output"), "Output_011");
b.add_output<decl::Enum>(N_("Output"), "Output_012").inference_items();
}
static void geo_node_switch_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -290,10 +287,6 @@ static void geo_node_switch_exec(GeoNodeExecParams params)
switch_no_fields<Image *>(params, "_011");
break;
}
case SOCK_ENUM: {
switch_no_fields<EnumValue>(params, "_012");
break;
}
default:
BLI_assert_unreachable();
break;

View File

@@ -254,29 +254,6 @@ std::string GeoNodeExecParams::attribute_producer_name() const
return provider_->dnode->label_or_name() + TIP_(" node");
}
const int GeoNodeExecParams::validate_enum_value(StringRef identifier, const int value) const
{
const bNodeSocket &socket = *provider_->dnode->input_by_identifier(identifier).bsocket();
BLI_assert(socket.type == SOCK_ENUM);
const bNodeSocketValueEnum *socket_value = (const bNodeSocketValueEnum *)socket.default_value;
BLI_assert(socket_value->items != nullptr);
for (const EnumPropertyItem *item = socket_value->items; item->identifier != nullptr; item++) {
if (item->identifier[0]) {
if (item->value == value) {
return value;
}
}
}
/* Use the first value as default if the passed in value is invalid. */
for (const EnumPropertyItem *item = socket_value->items; item->identifier != nullptr; item++) {
if (item->identifier[0]) {
return item->value;
}
}
BLI_assert_unreachable();
return 0;
}
void GeoNodeExecParams::check_input_access(StringRef identifier,
const CPPType *requested_type) const
{

View File

@@ -44,13 +44,11 @@
#include "MEM_guardedalloc.h"
#include "NOD_geometry_exec.hh"
#include "NOD_node_declaration.hh"
#include "NOD_socket.h"
#include "FN_cpp_type_make.hh"
#include "FN_field.hh"
#include "FN_field_cpp_type.hh"
using namespace blender;
using blender::nodes::SocketDeclarationPtr;
@@ -400,14 +398,6 @@ void node_socket_init_default_value(bNodeSocket *sock)
sizeof(bNodeSocketValueMaterial), "node socket value material");
dval->value = nullptr;
sock->default_value = dval;
break;
}
case SOCK_ENUM: {
bNodeSocketValueEnum *dval = (bNodeSocketValueEnum *)MEM_callocN(
sizeof(bNodeSocketValueEnum), "node socket value enum");
dval->value = 0;
sock->default_value = dval;
break;
}
@@ -504,12 +494,6 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from)
id_us_plus(&toval->value->id);
break;
}
case SOCK_ENUM: {
bNodeSocketValueEnum *toval = (bNodeSocketValueEnum *)to->default_value;
bNodeSocketValueEnum *fromval = (bNodeSocketValueEnum *)from->default_value;
*toval = *fromval;
break;
}
}
to->flag |= (from->flag & SOCK_HIDE_VALUE);
@@ -827,8 +811,6 @@ MAKE_CPP_TYPE(Collection, Collection *, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(Texture, Tex *, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(Image, Image *, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(Material, Material *, CPPTypeFlags::BasicType)
MAKE_CPP_TYPE(EnumValue, blender::nodes::EnumValue, CPPTypeFlags::None)
MAKE_FIELD_CPP_TYPE(EnumValueField, blender::nodes::EnumValue);
static bNodeSocketType *make_socket_type_object()
{
@@ -902,26 +884,6 @@ static bNodeSocketType *make_socket_type_material()
return socktype;
}
static bNodeSocketType *make_socket_type_enum()
{
using blender::nodes::EnumValue;
bNodeSocketType *socktype = make_standard_socket_type(SOCK_ENUM, PROP_NONE);
socktype->get_base_cpp_type = []() { return &blender::fn::CPPType::get<EnumValue>(); };
socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
((EnumValue *)r_value)->value = ((bNodeSocketValueEnum *)socket.default_value)->value;
};
socktype->get_geometry_nodes_cpp_type = []() {
return &blender::fn::CPPType::get<blender::fn::Field<EnumValue>>();
};
socktype->get_geometry_nodes_cpp_value = [](const bNodeSocket &socket, void *r_value) {
EnumValue value;
socket.typeinfo->get_base_cpp_value(socket, &value);
new (r_value) blender::fn::Field<EnumValue>(blender::fn::make_constant_field(value));
};
return socktype;
}
void register_standard_node_socket_types(void)
{
/* Draw callbacks are set in `drawnode.c` to avoid bad-level calls. */
@@ -968,7 +930,5 @@ void register_standard_node_socket_types(void)
nodeRegisterSocketType(make_socket_type_material());
nodeRegisterSocketType(make_socket_type_enum());
nodeRegisterSocketType(make_socket_type_virtual());
}

View File

@@ -19,36 +19,8 @@
#include "BKE_node.h"
#include "RNA_enum_types.h"
#include "BLI_math_vector.h"
namespace blender::nodes {
EnumItems::EnumItems() : items_(DummyRNA_NULL_items)
{
}
EnumItems::EnumItems(const EnumPropertyItem *items, std::function<void()> free_fn)
: items_(items), free_fn_(std::move(free_fn))
{
BLI_assert(items != nullptr);
}
EnumItems::~EnumItems()
{
if (free_fn_) {
free_fn_();
}
}
const EnumPropertyItem *EnumItems::items() const
{
return items_;
}
} // namespace blender::nodes
namespace blender::nodes::decl {
static void modify_subtype_except_for_storage(bNodeSocket &socket, int new_subtype)
@@ -301,56 +273,6 @@ bool String::matches(const bNodeSocket &socket) const
/** \} */
/* -------------------------------------------------------------------- */
/** \name #Enum
* \{ */
const EnumInputInferencingInfo &Enum::inferencing_info() const
{
return inferencing_info_;
}
bNodeSocket &Enum::build(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out) const
{
bNodeSocket &socket = *nodeAddStaticSocket(
&ntree, &node, in_out, SOCK_ENUM, PROP_NONE, identifier_.c_str(), name_.c_str());
((bNodeSocketValueEnum *)socket.default_value)->value = default_value_;
this->set_common_flags(socket);
return socket;
}
bool Enum::matches(const bNodeSocket &socket) const
{
if (!this->matches_common_data(socket)) {
return false;
}
if (socket.type != SOCK_ENUM) {
return false;
}
return true;
}
EnumBuilder &EnumBuilder::static_items(const EnumPropertyItem *items)
{
BLI_assert(items != nullptr);
decl_->inferencing_info_.items = std::make_shared<EnumItems>(items, nullptr);
return *this;
}
EnumBuilder &EnumBuilder::dynamic_items(std::shared_ptr<EnumItems> items)
{
decl_->inferencing_info_.items = std::move(items);
return *this;
}
EnumBuilder &EnumBuilder::inference_items(const int output_index)
{
decl_->inferencing_info_.inference_index = output_index;
return *this;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name #IDSocketDeclaration
* \{ */

View File

@@ -483,14 +483,6 @@ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype
return -1;
}
}
case SOCK_ENUM: {
switch (from) {
case SOCK_ENUM:
return 1;
default:
return -1;
}
}
default:
return -1;
}