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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-03-16 16:51:11 +0300
committerHans Goudey <h.goudey@me.com>2022-03-16 16:51:11 +0300
commit943b919fe807b53558631bcbc688c2d712d6b0cc (patch)
treec1c141866f50eb1f28e1875195395c8582898cc2
parentcb267cec5552c17092a99999e4e352bf266b578f (diff)
Geometry Nodes: Remove legacy node code
This commit removes the implementations of legacy nodes, their type definitions, and related code that becomes unused. Now that we have two releases that included the legacy nodes, there is not much reason to include them still. Removing the code means refactoring will be easier, and old code doesn't have to be tested and maintained. After this commit, the legacy nodes will be undefined in the UI, so 3.0 or 3.1 should be used to convert files to the fields system. The net change is 12184 lines removed! The tooltip for legacy nodes mentioned that we would remove them before 4.0, which was purposefully a bit vague to allow us this flexibility. In a poll in a devtalk post showed that the majority of people were okay with removing the nodes. https://devtalk.blender.org/t/geometry-nodes-backward-compatibility-poll/20199 Differential Revision: https://developer.blender.org/D14353
-rw-r--r--source/blender/blenkernel/BKE_node.h41
-rw-r--r--source/blender/blenkernel/intern/node.cc69
-rw-r--r--source/blender/blenloader/intern/versioning_290.c103
-rw-r--r--source/blender/blenloader/intern/versioning_300.c218
-rw-r--r--source/blender/editors/space_node/link_drag_search.cc3
-rw-r--r--source/blender/editors/space_node/node_add.cc107
-rw-r--r--source/blender/editors/space_node/node_draw.cc4
-rw-r--r--source/blender/editors/space_node/node_intern.hh2
-rw-r--r--source/blender/editors/space_node/node_ops.cc2
-rw-r--r--source/blender/editors/space_node/node_view.cc86
-rw-r--r--source/blender/editors/space_node/space_node.cc11
-rw-r--r--source/blender/makesdna/DNA_node_types.h248
-rw-r--r--source/blender/makesrna/intern/rna_color.c12
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c1092
-rw-r--r--source/blender/modifiers/intern/MOD_nodes.cc14
-rw-r--r--source/blender/modifiers/intern/MOD_nodes_evaluator.cc14
-rw-r--r--source/blender/nodes/NOD_function.h2
-rw-r--r--source/blender/nodes/NOD_geometry.h41
-rw-r--r--source/blender/nodes/NOD_geometry_nodes_eval_log.hh1
-rw-r--r--source/blender/nodes/NOD_static_types.h44
-rw-r--r--source/blender/nodes/function/CMakeLists.txt2
-rw-r--r--source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc74
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt42
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc23
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh37
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc228
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc267
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc123
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc137
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc345
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc179
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc208
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc151
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc422
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc308
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc245
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc237
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc333
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_remove.cc61
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc124
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc157
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc515
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc559
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc335
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc207
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc60
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc126
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc131
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc294
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc384
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc351
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc726
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc77
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc83
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc64
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc657
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc268
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc223
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc126
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc165
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc97
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc266
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc313
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc80
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc132
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc162
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc26
67 files changed, 30 insertions, 12214 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 904f06f2734..3e964b038c4 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1363,37 +1363,13 @@ struct TexResult;
* \{ */
#define GEO_NODE_TRIANGULATE 1000
-#define GEO_NODE_LEGACY_EDGE_SPLIT 1001
#define GEO_NODE_TRANSFORM 1002
#define GEO_NODE_MESH_BOOLEAN 1003
-#define GEO_NODE_LEGACY_POINT_DISTRIBUTE 1004
-#define GEO_NODE_LEGACY_POINT_INSTANCE 1005
-#define GEO_NODE_LEGACY_SUBDIVISION_SURFACE 1006
#define GEO_NODE_OBJECT_INFO 1007
-#define GEO_NODE_LEGACY_ATTRIBUTE_RANDOMIZE 1008
-#define GEO_NODE_LEGACY_ATTRIBUTE_MATH 1009
#define GEO_NODE_JOIN_GEOMETRY 1010
-#define GEO_NODE_LEGACY_ATTRIBUTE_FILL 1011
-#define GEO_NODE_LEGACY_ATTRIBUTE_MIX 1012
-#define GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP 1013
-#define GEO_NODE_LEGACY_POINT_SEPARATE 1014
-#define GEO_NODE_LEGACY_ATTRIBUTE_COMPARE 1015
-#define GEO_NODE_LEGACY_POINT_ROTATE 1016
-#define GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_MATH 1017
-#define GEO_NODE_LEGACY_ALIGN_ROTATION_TO_VECTOR 1018
-#define GEO_NODE_LEGACY_POINT_TRANSLATE 1019
-#define GEO_NODE_LEGACY_POINT_SCALE 1020
-#define GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE 1021
-#define GEO_NODE_LEGACY_POINTS_TO_VOLUME 1022
#define GEO_NODE_COLLECTION_INFO 1023
#define GEO_NODE_IS_VIEWPORT 1024
-#define GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY 1025
-#define GEO_NODE_LEGACY_VOLUME_TO_MESH 1026
-#define GEO_NODE_LEGACY_ATTRIBUTE_COMBINE_XYZ 1027
-#define GEO_NODE_LEGACY_ATTRIBUTE_SEPARATE_XYZ 1028
#define GEO_NODE_SUBDIVIDE_MESH 1029
-#define GEO_NODE_LEGACY_ATTRIBUTE_REMOVE 1030
-#define GEO_NODE_LEGACY_ATTRIBUTE_CONVERT 1031
#define GEO_NODE_MESH_PRIMITIVE_CUBE 1032
#define GEO_NODE_MESH_PRIMITIVE_CIRCLE 1033
#define GEO_NODE_MESH_PRIMITIVE_UV_SPHERE 1034
@@ -1402,28 +1378,15 @@ struct TexResult;
#define GEO_NODE_MESH_PRIMITIVE_CONE 1037
#define GEO_NODE_MESH_PRIMITIVE_LINE 1038
#define GEO_NODE_MESH_PRIMITIVE_GRID 1039
-#define GEO_NODE_LEGACY_ATTRIBUTE_MAP_RANGE 1040
-#define GEO_NODE_LEGACY_ATTRIBUTE_CLAMP 1041
#define GEO_NODE_BOUNDING_BOX 1042
#define GEO_NODE_SWITCH 1043
-#define GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER 1044
#define GEO_NODE_CURVE_TO_MESH 1045
-#define GEO_NODE_LEGACY_ATTRIBUTE_CURVE_MAP 1046
#define GEO_NODE_RESAMPLE_CURVE 1047
-#define GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_ROTATE 1048
-#define GEO_NODE_LEGACY_MATERIAL_ASSIGN 1049
#define GEO_NODE_INPUT_MATERIAL 1050
#define GEO_NODE_REPLACE_MATERIAL 1051
-#define GEO_NODE_LEGACY_MESH_TO_CURVE 1052
-#define GEO_NODE_LEGACY_DELETE_GEOMETRY 1053
#define GEO_NODE_CURVE_LENGTH 1054
-#define GEO_NODE_LEGACY_SELECT_BY_MATERIAL 1055
#define GEO_NODE_CONVEX_HULL 1056
-#define GEO_NODE_LEGACY_CURVE_TO_POINTS 1057
-#define GEO_NODE_LEGACY_CURVE_REVERSE 1058
#define GEO_NODE_SEPARATE_COMPONENTS 1059
-#define GEO_NODE_LEGACY_CURVE_SUBDIVIDE 1060
-#define GEO_NODE_LEGACY_RAYCAST 1061
#define GEO_NODE_CURVE_PRIMITIVE_STAR 1062
#define GEO_NODE_CURVE_PRIMITIVE_SPIRAL 1063
#define GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER 1064
@@ -1431,12 +1394,8 @@ struct TexResult;
#define GEO_NODE_CURVE_PRIMITIVE_CIRCLE 1066
#define GEO_NODE_VIEWER 1067
#define GEO_NODE_CURVE_PRIMITIVE_LINE 1068
-#define GEO_NODE_LEGACY_CURVE_ENDPOINTS 1069
#define GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL 1070
#define GEO_NODE_TRIM_CURVE 1071
-#define GEO_NODE_LEGACY_CURVE_SET_HANDLES 1072
-#define GEO_NODE_LEGACY_CURVE_SPLINE_TYPE 1073
-#define GEO_NODE_LEGACY_CURVE_SELECT_HANDLES 1074
#define GEO_NODE_FILL_CURVE 1075
#define GEO_NODE_INPUT_POSITION 1076
#define GEO_NODE_SET_POSITION 1077
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 9a573919165..83eb831b177 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -532,13 +532,6 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
ELEM(node->type, SH_NODE_CURVE_VEC, SH_NODE_CURVE_RGB, SH_NODE_CURVE_FLOAT)) {
BKE_curvemapping_blend_write(writer, (const CurveMapping *)node->storage);
}
- else if ((ntree->type == NTREE_GEOMETRY) &&
- (node->type == GEO_NODE_LEGACY_ATTRIBUTE_CURVE_MAP)) {
- BLO_write_struct_by_name(writer, node->typeinfo->storagename, node->storage);
- NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
- BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_vec);
- BKE_curvemapping_blend_write(writer, (const CurveMapping *)data->curve_rgb);
- }
else if (ntree->type == NTREE_SHADER && (node->type == SH_NODE_SCRIPT)) {
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
if (nss->bytecode) {
@@ -715,18 +708,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
BKE_curvemapping_blend_read(reader, (CurveMapping *)node->storage);
break;
}
- case GEO_NODE_LEGACY_ATTRIBUTE_CURVE_MAP: {
- NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
- BLO_read_data_address(reader, &data->curve_vec);
- if (data->curve_vec) {
- BKE_curvemapping_blend_read(reader, data->curve_vec);
- }
- BLO_read_data_address(reader, &data->curve_rgb);
- if (data->curve_rgb) {
- BKE_curvemapping_blend_read(reader, data->curve_rgb);
- }
- break;
- }
case SH_NODE_SCRIPT: {
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
BLO_read_data_address(reader, &nss->bytecode);
@@ -3616,15 +3597,13 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
tnode->flag &= ~NODE_ACTIVE;
- if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) ||
- (node->typeinfo->type == GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE)) {
+ if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE)) {
tnode->flag &= ~NODE_ACTIVE_TEXTURE;
}
}
node->flag |= NODE_ACTIVE;
- if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE) ||
- (node->typeinfo->type == GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE)) {
+ if ((node->typeinfo->nclass == NODE_CLASS_TEXTURE)) {
node->flag |= NODE_ACTIVE_TEXTURE;
}
}
@@ -4692,45 +4671,10 @@ static void registerGeometryNodes()
{
register_node_type_geo_group();
- register_node_type_geo_legacy_attribute_proximity();
- register_node_type_geo_legacy_attribute_randomize();
- register_node_type_geo_legacy_attribute_remove();
- register_node_type_geo_legacy_attribute_transfer();
- register_node_type_geo_legacy_curve_endpoints();
- register_node_type_geo_legacy_curve_reverse();
- register_node_type_geo_legacy_curve_set_handles();
- register_node_type_geo_legacy_curve_spline_type();
- register_node_type_geo_legacy_curve_subdivide();
- register_node_type_geo_legacy_curve_to_points();
- register_node_type_geo_legacy_delete_geometry();
- register_node_type_geo_legacy_edge_split();
- register_node_type_geo_legacy_material_assign();
- register_node_type_geo_legacy_mesh_to_curve();
- register_node_type_geo_legacy_points_to_volume();
- register_node_type_geo_legacy_raycast();
- register_node_type_geo_legacy_select_by_handle_type();
- register_node_type_geo_legacy_select_by_material();
- register_node_type_geo_legacy_subdivision_surface();
- register_node_type_geo_legacy_volume_to_mesh();
-
register_node_type_geo_accumulate_field();
- register_node_type_geo_align_rotation_to_vector();
register_node_type_geo_attribute_capture();
- register_node_type_geo_attribute_clamp();
- register_node_type_geo_attribute_color_ramp();
- register_node_type_geo_attribute_combine_xyz();
- register_node_type_geo_attribute_compare();
- register_node_type_geo_attribute_convert();
- register_node_type_geo_attribute_curve_map();
register_node_type_geo_attribute_domain_size();
- register_node_type_geo_attribute_fill();
- register_node_type_geo_attribute_map_range();
- register_node_type_geo_attribute_math();
- register_node_type_geo_attribute_mix();
- register_node_type_geo_attribute_separate_xyz();
register_node_type_geo_attribute_statistic();
- register_node_type_geo_attribute_vector_math();
- register_node_type_geo_attribute_vector_rotate();
register_node_type_geo_boolean();
register_node_type_geo_bounding_box();
register_node_type_geo_collection_info();
@@ -4811,12 +4755,6 @@ static void registerGeometryNodes()
register_node_type_geo_mesh_to_curve();
register_node_type_geo_mesh_to_points();
register_node_type_geo_object_info();
- register_node_type_geo_point_distribute();
- register_node_type_geo_point_instance();
- register_node_type_geo_point_rotate();
- register_node_type_geo_point_scale();
- register_node_type_geo_point_separate();
- register_node_type_geo_point_translate();
register_node_type_geo_points_to_vertices();
register_node_type_geo_points_to_volume();
register_node_type_geo_proximity();
@@ -4824,7 +4762,6 @@ static void registerGeometryNodes()
register_node_type_geo_realize_instances();
register_node_type_geo_remove_attribute();
register_node_type_geo_rotate_instances();
- register_node_type_geo_sample_texture();
register_node_type_geo_scale_elements();
register_node_type_geo_scale_instances();
register_node_type_geo_separate_components();
@@ -4855,8 +4792,6 @@ static void registerGeometryNodes()
static void registerFunctionNodes()
{
- register_node_type_fn_legacy_random_float();
-
register_node_type_fn_align_euler_to_vector();
register_node_type_fn_boolean_math();
register_node_type_fn_compare();
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 3ae26dea767..079d69be4d9 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -1510,27 +1510,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 292, 9)) {
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_LEGACY_ATTRIBUTE_MATH && node->storage == NULL) {
- const int old_use_attibute_a = (1 << 0);
- const int old_use_attibute_b = (1 << 1);
- NodeAttributeMath *data = MEM_callocN(sizeof(NodeAttributeMath), "NodeAttributeMath");
- data->operation = NODE_MATH_ADD;
- data->input_type_a = (node->custom2 & old_use_attibute_a) ?
- GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE :
- GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- data->input_type_b = (node->custom2 & old_use_attibute_b) ?
- GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE :
- GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node->storage = data;
- }
- }
- }
- }
- FOREACH_NODETREE_END;
-
/* Default properties editors to auto outliner sync. */
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
@@ -1668,39 +1647,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- if (!MAIN_VERSION_ATLEAST(bmain, 293, 3)) {
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type != NTREE_GEOMETRY) {
- continue;
- }
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_LEGACY_POINT_INSTANCE && node->storage == NULL) {
- NodeGeometryPointInstance *data = (NodeGeometryPointInstance *)MEM_callocN(
- sizeof(NodeGeometryPointInstance), __func__);
- data->instance_type = node->custom1;
- data->flag = (node->custom2 ? 0 : GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION);
- node->storage = data;
- }
- }
- }
- FOREACH_NODETREE_END;
- }
-
- if (!MAIN_VERSION_ATLEAST(bmain, 293, 4)) {
- /* Add support for all operations to the "Attribute Math" node. */
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_LEGACY_ATTRIBUTE_MATH) {
- NodeAttributeMath *data = (NodeAttributeMath *)node->storage;
- data->input_type_c = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- }
- }
- }
- }
- FOREACH_NODETREE_END;
- }
-
if (!MAIN_VERSION_ATLEAST(bmain, 293, 5)) {
/* Change Nishita sky model Altitude unit. */
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
@@ -1744,24 +1690,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
FOREACH_NODETREE_END;
}
- if (!MAIN_VERSION_ATLEAST(bmain, 293, 8)) {
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type != NTREE_GEOMETRY) {
- continue;
- }
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_LEGACY_ATTRIBUTE_RANDOMIZE && node->storage == NULL) {
- NodeAttributeRandomize *data = (NodeAttributeRandomize *)MEM_callocN(
- sizeof(NodeAttributeRandomize), __func__);
- data->data_type = node->custom1;
- data->operation = GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE;
- node->storage = data;
- }
- }
- }
- FOREACH_NODETREE_END;
- }
-
if (!MAIN_VERSION_ATLEAST(bmain, 293, 9)) {
if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "bokeh_overblur")) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
@@ -1784,23 +1712,9 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- version_node_socket_name(ntree, GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY, "Result", "Distance");
- }
- }
- FOREACH_NODETREE_END;
}
if (!MAIN_VERSION_ATLEAST(bmain, 293, 10)) {
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- version_node_socket_name(
- ntree, GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY, "Location", "Position");
- }
- }
- FOREACH_NODETREE_END;
-
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
/* Fix old scene with too many samples that were not being used.
* Now they are properly used and might produce a huge slowdown.
@@ -1886,16 +1800,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
light->volume_fac = 1.0f;
}
}
-
- LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
- if (ntree->type == NTREE_GEOMETRY) {
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_LEGACY_ATTRIBUTE_FILL) {
- node->custom2 = ATTR_DOMAIN_AUTO;
- }
- }
- }
- }
}
if (!MAIN_VERSION_ATLEAST(bmain, 293, 15)) {
@@ -1940,13 +1844,6 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 293, 18)) {
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- version_node_socket_name(ntree, GEO_NODE_LEGACY_VOLUME_TO_MESH, "Grid", "Density");
- }
- }
- FOREACH_NODETREE_END;
-
if (!DNA_struct_elem_find(fd->filesdna, "bArmature", "float", "axes_position")) {
/* Convert the axes draw position to its old default (tip of bone). */
LISTBASE_FOREACH (struct bArmature *, arm, &bmain->armatures) {
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index eead735b305..5b1964aa35c 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -527,7 +527,6 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree)
GEO_NODE_TRIM_CURVE,
GEO_NODE_REPLACE_MATERIAL,
GEO_NODE_SUBDIVIDE_MESH,
- GEO_NODE_LEGACY_ATTRIBUTE_REMOVE,
GEO_NODE_TRIANGULATE)) {
bNodeSocket *geometry_socket = node->inputs.first;
add_realize_instances_before_socket(ntree, node, geometry_socket);
@@ -600,30 +599,6 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 3)) {
- /* Use new texture socket in Attribute Sample Texture node. */
- LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
- if (ntree->type != NTREE_GEOMETRY) {
- continue;
- }
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type != GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE) {
- continue;
- }
- if (node->id == NULL) {
- continue;
- }
- LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
- if (socket->type == SOCK_TEXTURE) {
- bNodeSocketValueTexture *socket_value = (bNodeSocketValueTexture *)
- socket->default_value;
- socket_value->value = (Tex *)node->id;
- break;
- }
- }
- node->id = NULL;
- }
- }
-
sort_linked_ids(bmain);
assert_sorted_ids(bmain);
}
@@ -951,141 +926,6 @@ static bNodeSocket *do_version_replace_float_size_with_vector(bNodeTree *ntree,
return new_socket;
}
-static bool geometry_node_is_293_legacy(const short node_type)
-{
- switch (node_type) {
- /* Not legacy: No attribute inputs or outputs. */
- case GEO_NODE_TRIANGULATE:
- case GEO_NODE_TRANSFORM:
- case GEO_NODE_MESH_BOOLEAN:
- case GEO_NODE_IS_VIEWPORT:
- case GEO_NODE_SUBDIVIDE_MESH:
- case GEO_NODE_MESH_PRIMITIVE_CUBE:
- case GEO_NODE_MESH_PRIMITIVE_CIRCLE:
- case GEO_NODE_MESH_PRIMITIVE_UV_SPHERE:
- case GEO_NODE_MESH_PRIMITIVE_CYLINDER:
- case GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE:
- case GEO_NODE_MESH_PRIMITIVE_CONE:
- case GEO_NODE_MESH_PRIMITIVE_LINE:
- case GEO_NODE_MESH_PRIMITIVE_GRID:
- case GEO_NODE_BOUNDING_BOX:
- case GEO_NODE_RESAMPLE_CURVE:
- case GEO_NODE_INPUT_MATERIAL:
- case GEO_NODE_REPLACE_MATERIAL:
- case GEO_NODE_CURVE_LENGTH:
- case GEO_NODE_CONVEX_HULL:
- case GEO_NODE_SEPARATE_COMPONENTS:
- case GEO_NODE_CURVE_PRIMITIVE_STAR:
- case GEO_NODE_CURVE_PRIMITIVE_SPIRAL:
- case GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER:
- case GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT:
- case GEO_NODE_CURVE_PRIMITIVE_CIRCLE:
- case GEO_NODE_VIEWER:
- case GEO_NODE_CURVE_PRIMITIVE_LINE:
- case GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL:
- case GEO_NODE_FILL_CURVE:
- case GEO_NODE_TRIM_CURVE:
- case GEO_NODE_CURVE_TO_MESH:
- return false;
-
- /* Not legacy: Newly added with fields patch. */
- case GEO_NODE_INPUT_POSITION:
- case GEO_NODE_SET_POSITION:
- case GEO_NODE_INPUT_INDEX:
- case GEO_NODE_INPUT_NORMAL:
- case GEO_NODE_CAPTURE_ATTRIBUTE:
- return false;
-
- /* Maybe legacy: Might need special attribute handling, depending on design. */
- case GEO_NODE_SWITCH:
- case GEO_NODE_JOIN_GEOMETRY:
- case GEO_NODE_LEGACY_ATTRIBUTE_REMOVE:
- case GEO_NODE_OBJECT_INFO:
- case GEO_NODE_COLLECTION_INFO:
- return false;
-
- /* Maybe legacy: Special case for grid names? Or finish patch from level set branch to
- * generate a mesh for all grids in the volume. */
- case GEO_NODE_LEGACY_VOLUME_TO_MESH:
- return false;
-
- /* Legacy: Transferred *all* attributes before, will not transfer all built-ins now. */
- case GEO_NODE_LEGACY_CURVE_ENDPOINTS:
- case GEO_NODE_LEGACY_CURVE_TO_POINTS:
- return true;
-
- /* Legacy: Attribute operation completely replaced by field nodes. */
- case GEO_NODE_LEGACY_ATTRIBUTE_RANDOMIZE:
- case GEO_NODE_LEGACY_ATTRIBUTE_MATH:
- case GEO_NODE_LEGACY_ATTRIBUTE_FILL:
- case GEO_NODE_LEGACY_ATTRIBUTE_MIX:
- case GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP:
- case GEO_NODE_LEGACY_ATTRIBUTE_COMPARE:
- case GEO_NODE_LEGACY_POINT_ROTATE:
- case GEO_NODE_LEGACY_ALIGN_ROTATION_TO_VECTOR:
- case GEO_NODE_LEGACY_POINT_SCALE:
- case GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE:
- case GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_ROTATE:
- case GEO_NODE_LEGACY_ATTRIBUTE_CURVE_MAP:
- case GEO_NODE_LEGACY_ATTRIBUTE_MAP_RANGE:
- case GEO_NODE_LEGACY_ATTRIBUTE_CLAMP:
- case GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_MATH:
- case GEO_NODE_LEGACY_ATTRIBUTE_COMBINE_XYZ:
- case GEO_NODE_LEGACY_ATTRIBUTE_SEPARATE_XYZ:
- return true;
-
- /* Legacy: Replaced by field node depending on another geometry. */
- case GEO_NODE_LEGACY_RAYCAST:
- case GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER:
- case GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY:
- return true;
-
- /* Legacy: Simple selection attribute input. */
- case GEO_NODE_LEGACY_MESH_TO_CURVE:
- case GEO_NODE_LEGACY_POINT_SEPARATE:
- case GEO_NODE_LEGACY_CURVE_SELECT_HANDLES:
- case GEO_NODE_LEGACY_CURVE_SPLINE_TYPE:
- case GEO_NODE_LEGACY_CURVE_REVERSE:
- case GEO_NODE_LEGACY_MATERIAL_ASSIGN:
- case GEO_NODE_LEGACY_CURVE_SET_HANDLES:
- return true;
-
- /* Legacy: More complex attribute inputs or outputs. */
- case GEO_NODE_LEGACY_SUBDIVISION_SURFACE: /* Used "crease" attribute. */
- case GEO_NODE_LEGACY_EDGE_SPLIT: /* Needs selection input version. */
- case GEO_NODE_LEGACY_DELETE_GEOMETRY: /* Needs field input, domain drop-down. */
- case GEO_NODE_LEGACY_CURVE_SUBDIVIDE: /* Needs field count input. */
- case GEO_NODE_LEGACY_POINTS_TO_VOLUME: /* Needs field radius input. */
- case GEO_NODE_LEGACY_SELECT_BY_MATERIAL: /* Output anonymous attribute. */
- case GEO_NODE_LEGACY_POINT_TRANSLATE: /* Needs field inputs. */
- case GEO_NODE_LEGACY_POINT_INSTANCE: /* Needs field inputs. */
- case GEO_NODE_LEGACY_POINT_DISTRIBUTE: /* Needs field input, remove max for random mode. */
- case GEO_NODE_LEGACY_ATTRIBUTE_CONVERT: /* Attribute Capture, Store Attribute. */
- return true;
- }
- return false;
-}
-
-static void version_geometry_nodes_change_legacy_names(bNodeTree *ntree)
-{
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (geometry_node_is_293_legacy(node->type)) {
- if (strstr(node->idname, "Legacy")) {
- /* Make sure we haven't changed this idname already, better safe than sorry. */
- continue;
- }
-
- char temp_idname[sizeof(node->idname)];
- BLI_strncpy(temp_idname, node->idname, sizeof(node->idname));
-
- BLI_snprintf(node->idname,
- sizeof(node->idname),
- "GeometryNodeLegacy%s",
- temp_idname + strlen("GeometryNode"));
- }
- }
-}
-
static bool seq_transform_origin_set(Sequence *seq, void *UNUSED(user_data))
{
StripTransform *transform = seq->strip->transform;
@@ -1873,24 +1713,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 19)) {
- /* Add node storage for subdivision surface node. */
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == GEO_NODE_LEGACY_SUBDIVISION_SURFACE) {
- if (node->storage == NULL) {
- NodeGeometrySubdivisionSurface *data = MEM_callocN(
- sizeof(NodeGeometrySubdivisionSurface), __func__);
- data->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
- data->boundary_smooth = SUBSURF_BOUNDARY_SMOOTH_ALL;
- node->storage = data;
- }
- }
- }
- }
- }
- FOREACH_NODETREE_END;
-
/* Disable Fade Inactive Overlay by default as it is redundant after introducing flash on
* mode transfer. */
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
@@ -2091,30 +1913,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
-
- /* Deprecate the random float node in favor of the random value node. */
- LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
- if (ntree->type != NTREE_GEOMETRY) {
- continue;
- }
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type != FN_NODE_LEGACY_RANDOM_FLOAT) {
- continue;
- }
- if (strstr(node->idname, "Legacy")) {
- /* Make sure we haven't changed this idname already. */
- continue;
- }
-
- char temp_idname[sizeof(node->idname)];
- BLI_strncpy(temp_idname, node->idname, sizeof(node->idname));
-
- BLI_snprintf(node->idname,
- sizeof(node->idname),
- "FunctionNodeLegacy%s",
- temp_idname + strlen("FunctionNode"));
- }
- }
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 29)) {
@@ -2141,12 +1939,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
-
- LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
- if (ntree->type == NTREE_GEOMETRY) {
- version_geometry_nodes_change_legacy_names(ntree);
- }
- }
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 31)) {
@@ -2304,7 +2096,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
version_node_id(ntree, FN_NODE_SLICE_STRING, "FunctionNodeSliceString");
version_geometry_nodes_set_position_node_offset(ntree);
- version_node_id(ntree, GEO_NODE_LEGACY_VOLUME_TO_MESH, "GeometryNodeLegacyVolumeToMesh");
}
/* Add storage to viewer node. */
@@ -2637,14 +2428,5 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
*/
{
/* Keep this block, even when empty. */
-
- /* Deprecate the attribute remove node. It was hidden and is replaced by a version without a
- * multi-input socket. */
- LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
- if (ntree->type == NTREE_GEOMETRY) {
- version_node_id(
- ntree, GEO_NODE_LEGACY_ATTRIBUTE_REMOVE, "GeometryNodeLegacyAttributeRemove");
- }
- }
}
}
diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc
index ccd3333fcc5..c524de2c55d 100644
--- a/source/blender/editors/space_node/link_drag_search.cc
+++ b/source/blender/editors/space_node/link_drag_search.cc
@@ -121,9 +121,6 @@ static void gather_socket_link_operations(bNodeTree &node_tree,
Vector<SocketLinkOperation> &search_link_ops)
{
NODE_TYPES_BEGIN (node_type) {
- if (StringRef(node_type->idname).find("Legacy") != StringRef::not_found) {
- continue;
- }
const char *disabled_hint;
if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) {
continue;
diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc
index 30bd0fb528b..7fb15d69ab5 100644
--- a/source/blender/editors/space_node/node_add.cc
+++ b/source/blender/editors/space_node/node_add.cc
@@ -517,113 +517,6 @@ void NODE_OT_add_object(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Add Node Texture Operator
- * \{ */
-
-static Tex *node_add_texture_get_and_poll_texture_node_tree(Main *bmain, wmOperator *op)
-{
- if (RNA_struct_property_is_set(op->ptr, "session_uuid")) {
- const uint32_t session_uuid = (uint32_t)RNA_int_get(op->ptr, "session_uuid");
- return (Tex *)BKE_libblock_find_session_uuid(bmain, ID_TE, session_uuid);
- }
-
- char name[MAX_ID_NAME - 2];
- RNA_string_get(op->ptr, "name", name);
- return (Tex *)BKE_libblock_find_name(bmain, ID_TE, name);
-}
-
-static int node_add_texture_exec(bContext *C, wmOperator *op)
-{
- Main *bmain = CTX_data_main(C);
- SpaceNode *snode = CTX_wm_space_node(C);
- bNodeTree *ntree = snode->edittree;
- Tex *texture;
-
- if (!(texture = node_add_texture_get_and_poll_texture_node_tree(bmain, op))) {
- return OPERATOR_CANCELLED;
- }
-
- ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
-
- bNode *texture_node = node_add_node(*C,
- nullptr,
- GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE,
- snode->runtime->cursor[0],
- snode->runtime->cursor[1]);
- if (!texture_node) {
- BKE_report(op->reports, RPT_WARNING, "Could not add texture node");
- return OPERATOR_CANCELLED;
- }
-
- texture_node->id = &texture->id;
- id_us_plus(&texture->id);
-
- nodeSetActive(ntree, texture_node);
- ED_node_tree_propagate_change(C, bmain, ntree);
- DEG_relations_tag_update(bmain);
-
- return OPERATOR_FINISHED;
-}
-
-static int node_add_texture_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- ARegion *region = CTX_wm_region(C);
- SpaceNode *snode = CTX_wm_space_node(C);
-
- /* Convert mouse coordinates to v2d space. */
- UI_view2d_region_to_view(&region->v2d,
- event->mval[0],
- event->mval[1],
- &snode->runtime->cursor[0],
- &snode->runtime->cursor[1]);
-
- snode->runtime->cursor[0] /= UI_DPI_FAC;
- snode->runtime->cursor[1] /= UI_DPI_FAC;
-
- return node_add_texture_exec(C, op);
-}
-
-static bool node_add_texture_poll(bContext *C)
-{
- const SpaceNode *snode = CTX_wm_space_node(C);
- return ED_operator_node_editable(C) && ELEM(snode->nodetree->type, NTREE_GEOMETRY) &&
- !UI_but_active_drop_name(C);
-}
-
-void NODE_OT_add_texture(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Add Node Texture";
- ot->description = "Add a texture to the current node editor";
- ot->idname = "NODE_OT_add_texture";
-
- /* callbacks */
- ot->exec = node_add_texture_exec;
- ot->invoke = node_add_texture_invoke;
- ot->poll = node_add_texture_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- RNA_def_string(
- ot->srna, "name", "Texture", MAX_ID_NAME - 2, "Name", "Data-block name to assign");
- prop = RNA_def_int(ot->srna,
- "session_uuid",
- 0,
- INT32_MIN,
- INT32_MAX,
- "Session UUID",
- "Session UUID of the data-block to assign",
- INT32_MIN,
- INT32_MAX);
- RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Add Node Collection Operator
* \{ */
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index e638816e3fc..e221fac5ef9 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -1418,8 +1418,6 @@ static int node_error_type_to_icon(const geo_log::NodeWarningType type)
return ICON_ERROR;
case geo_log::NodeWarningType::Info:
return ICON_INFO;
- case geo_log::NodeWarningType::Legacy:
- return ICON_ERROR;
}
BLI_assert(false);
@@ -1430,8 +1428,6 @@ static uint8_t node_error_type_priority(const geo_log::NodeWarningType type)
{
switch (type) {
case geo_log::NodeWarningType::Error:
- return 4;
- case geo_log::NodeWarningType::Legacy:
return 3;
case geo_log::NodeWarningType::Warning:
return 2;
diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh
index 319f97e57f5..cd40573607d 100644
--- a/source/blender/editors/space_node/node_intern.hh
+++ b/source/blender/editors/space_node/node_intern.hh
@@ -178,7 +178,6 @@ bool space_node_view_flag(
void NODE_OT_view_all(wmOperatorType *ot);
void NODE_OT_view_selected(wmOperatorType *ot);
-void NODE_OT_geometry_node_view_legacy(wmOperatorType *ot);
void NODE_OT_backimage_move(wmOperatorType *ot);
void NODE_OT_backimage_zoom(wmOperatorType *ot);
@@ -241,7 +240,6 @@ void NODE_OT_add_reroute(wmOperatorType *ot);
void NODE_OT_add_group(wmOperatorType *ot);
void NODE_OT_add_object(wmOperatorType *ot);
void NODE_OT_add_collection(wmOperatorType *ot);
-void NODE_OT_add_texture(wmOperatorType *ot);
void NODE_OT_add_file(wmOperatorType *ot);
void NODE_OT_add_mask(wmOperatorType *ot);
void NODE_OT_new_node_tree(wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.cc b/source/blender/editors/space_node/node_ops.cc
index e9903299300..ce000aba1da 100644
--- a/source/blender/editors/space_node/node_ops.cc
+++ b/source/blender/editors/space_node/node_ops.cc
@@ -37,7 +37,6 @@ void node_operatortypes()
WM_operatortype_append(NODE_OT_view_all);
WM_operatortype_append(NODE_OT_view_selected);
- WM_operatortype_append(NODE_OT_geometry_node_view_legacy);
WM_operatortype_append(NODE_OT_mute_toggle);
WM_operatortype_append(NODE_OT_hide_toggle);
@@ -79,7 +78,6 @@ void node_operatortypes()
WM_operatortype_append(NODE_OT_add_group);
WM_operatortype_append(NODE_OT_add_object);
WM_operatortype_append(NODE_OT_add_collection);
- WM_operatortype_append(NODE_OT_add_texture);
WM_operatortype_append(NODE_OT_add_file);
WM_operatortype_append(NODE_OT_add_mask);
diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc
index 36fdcf37fd7..f5f5a9e6f67 100644
--- a/source/blender/editors/space_node/node_view.cc
+++ b/source/blender/editors/space_node/node_view.cc
@@ -686,90 +686,4 @@ void NODE_OT_backimage_sample(wmOperatorType *ot)
/** \} */
-/* -------------------------------------------------------------------- */
-/** \name View Geometry Nodes Legacy Operator
- *
- * This operator should be removed when the 2.93 legacy nodes are removed.
- * \{ */
-
-static int space_node_view_geometry_nodes_legacy(bContext *C, SpaceNode *snode, wmOperator *op)
-{
- ARegion *region = CTX_wm_region(C);
-
- /* Only use the node editor's active node tree. Otherwise this will be too complicated. */
- bNodeTree *node_tree = snode->nodetree;
- if (node_tree == nullptr || node_tree->type != NTREE_GEOMETRY) {
- return OPERATOR_CANCELLED;
- }
-
- bool found_legacy_node = false;
- LISTBASE_FOREACH_BACKWARD (bNode *, node, &node_tree->nodes) {
- StringRef idname{node->idname};
- if (idname.find("Legacy") == StringRef::not_found) {
- node->flag &= ~NODE_SELECT;
- }
- else {
- found_legacy_node = true;
- node->flag |= NODE_SELECT;
- }
- }
-
- if (!found_legacy_node) {
- WM_report(RPT_INFO, "Legacy node not found, may be in nested node group");
- }
-
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- if (space_node_view_flag(*C, *snode, *region, NODE_SELECT, smooth_viewtx)) {
- return OPERATOR_FINISHED;
- }
- return OPERATOR_CANCELLED;
-}
-
-static int geometry_node_view_legacy_exec(bContext *C, wmOperator *op)
-{
- /* Allow running this operator directly in a specific node editor. */
- if (SpaceNode *snode = CTX_wm_space_node(C)) {
- return space_node_view_geometry_nodes_legacy(C, snode, op);
- }
-
- /* Since the operator is meant to be called from a button in the modifier panel, the node tree
- * must be found from the screen, using the largest node editor if there is more than one. */
- if (ScrArea *area = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_NODE, 0)) {
- if (SpaceNode *snode = static_cast<SpaceNode *>(area->spacedata.first)) {
- ScrArea *old_area = CTX_wm_area(C);
- ARegion *old_region = CTX_wm_region(C);
-
- /* Override the context since it is used by the View2D panning code. */
- CTX_wm_area_set(C, area);
- CTX_wm_region_set(C, static_cast<ARegion *>(area->regionbase.last));
- const int result = space_node_view_geometry_nodes_legacy(C, snode, op);
- CTX_wm_area_set(C, old_area);
- CTX_wm_region_set(C, old_region);
- return result;
- }
- }
-
- return OPERATOR_CANCELLED;
-}
-
-static bool geometry_node_view_legacy_poll(bContext *C)
-{
- /* Allow direct execution in a node editor, but also affecting any visible node editor. */
- return ED_operator_node_active(C) || BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_NODE, 0);
-}
-
-void NODE_OT_geometry_node_view_legacy(wmOperatorType *ot)
-{
- ot->name = "View Deprecated Geometry Nodes";
- ot->idname = "NODE_OT_geometry_node_view_legacy";
- ot->description = "Select and view legacy geometry nodes in the node editor";
-
- ot->exec = geometry_node_view_legacy_exec;
- ot->poll = geometry_node_view_legacy_poll;
-
- ot->flag = OPTYPE_INTERNAL;
-}
-
-/** \} */
-
} // namespace blender::ed::space_node
diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc
index a1fa0517c63..82b850653be 100644
--- a/source/blender/editors/space_node/space_node.cc
+++ b/source/blender/editors/space_node/space_node.cc
@@ -622,11 +622,6 @@ static bool node_collection_drop_poll(bContext *UNUSED(C),
return WM_drag_is_ID_type(drag, ID_GR);
}
-static bool node_texture_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
-{
- return WM_drag_is_ID_type(drag, ID_TE);
-}
-
static bool node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
@@ -687,12 +682,6 @@ static void node_dropboxes()
WM_drag_free_imported_drag_ID,
nullptr);
WM_dropbox_add(lb,
- "NODE_OT_add_texture",
- node_texture_drop_poll,
- node_id_drop_copy,
- WM_drag_free_imported_drag_ID,
- nullptr);
- WM_dropbox_add(lb,
"NODE_OT_add_group",
node_group_drop_poll,
node_group_drop_copy,
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 5bd44868741..609862eff4f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1210,53 +1210,6 @@ typedef struct NodeMapRange {
char _pad[5];
} NodeMapRange;
-typedef struct NodeAttributeClamp {
- /* CustomDataType. */
- uint8_t data_type;
-
- /* NodeClampOperation. */
- uint8_t operation;
-} NodeAttributeClamp;
-
-typedef struct NodeAttributeCompare {
- /* FloatCompareOperation. */
- uint8_t operation;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_a;
- uint8_t input_type_b;
-
- char _pad[5];
-} NodeAttributeCompare;
-
-typedef struct NodeAttributeMapRange {
- /* GeometryNodeAttributeDataType */
- uint8_t data_type;
-
- /* NodeMapRangeType. */
- uint8_t interpolation_type;
-} NodeAttributeMapRange;
-
-typedef struct NodeAttributeMath {
- /* NodeMathOperation. */
- uint8_t operation;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_a;
- uint8_t input_type_b;
- uint8_t input_type_c;
-} NodeAttributeMath;
-
-typedef struct NodeAttributeMix {
- /* e.g. MA_RAMP_BLEND. */
- uint8_t blend_type;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_factor;
- uint8_t input_type_a;
- uint8_t input_type_b;
-} NodeAttributeMix;
-
typedef struct NodeRandomValue {
/* CustomDataType. */
uint8_t data_type;
@@ -1269,51 +1222,6 @@ typedef struct NodeAccumulateField {
uint8_t domain;
} NodeAccumulateField;
-typedef struct NodeAttributeRandomize {
- /* CustomDataType. */
- uint8_t data_type;
- /* AttributeDomain. */
- uint8_t domain;
- /* GeometryNodeAttributeRandomizeMode. */
- uint8_t operation;
- char _pad[1];
-} NodeAttributeRandomize;
-
-typedef struct NodeAttributeVectorMath {
- /* NodeVectorMathOperation */
- uint8_t operation;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_a;
- uint8_t input_type_b;
- uint8_t input_type_c;
-} NodeAttributeVectorMath;
-
-typedef struct NodeAttributeVectorRotate {
- /* GeometryNodeAttributeVectorRotateMode */
- uint8_t mode;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_vector;
- uint8_t input_type_center;
- uint8_t input_type_axis;
- uint8_t input_type_angle;
- uint8_t input_type_rotation;
- char _pad[2];
-} NodeAttributeVectorRotate;
-
-typedef struct NodeAttributeColorRamp {
- ColorBand color_ramp;
-} NodeAttributeColorRamp;
-
-typedef struct NodeAttributeCurveMap {
- /* CustomDataType. */
- uint8_t data_type;
- char _pad[7];
- CurveMapping *curve_vec;
- CurveMapping *curve_rgb;
-} NodeAttributeCurveMap;
-
typedef struct NodeInputBool {
uint8_t boolean;
} NodeInputBool;
@@ -1334,40 +1242,6 @@ typedef struct NodeInputString {
char *string;
} NodeInputString;
-typedef struct NodeGeometryRotatePoints {
- /* GeometryNodeRotatePointsType */
- uint8_t type;
- /* GeometryNodeRotatePointsSpace */
- uint8_t space;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_axis;
- uint8_t input_type_angle;
- uint8_t input_type_rotation;
- char _pad[3];
-} NodeGeometryRotatePoints;
-
-typedef struct NodeGeometryAlignRotationToVector {
- /* GeometryNodeAlignRotationToVectorAxis */
- uint8_t axis;
- /* GeometryNodeAlignRotationToVectorPivotAxis */
- uint8_t pivot_axis;
-
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type_factor;
- uint8_t input_type_vector;
-} NodeGeometryAlignRotationToVector;
-
-typedef struct NodeGeometryPointScale {
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type;
-} NodeGeometryPointScale;
-
-typedef struct NodeGeometryPointTranslate {
- /* GeometryNodeAttributeInputMode */
- uint8_t input_type;
-} NodeGeometryPointTranslate;
-
typedef struct NodeGeometryExtrudeMesh {
/* GeometryNodeExtrudeMeshMode */
uint8_t mode;
@@ -1378,13 +1252,6 @@ typedef struct NodeGeometryObjectInfo {
uint8_t transform_space;
} NodeGeometryObjectInfo;
-typedef struct NodeGeometryPointInstance {
- /* GeometryNodePointInstanceType. */
- uint8_t instance_type;
- /* GeometryNodePointInstanceFlag. */
- uint8_t flag;
-} NodeGeometryPointInstance;
-
typedef struct NodeGeometryPointsToVolume {
/* GeometryNodePointsToVolumeResolutionMode */
uint8_t resolution_mode;
@@ -1397,11 +1264,6 @@ typedef struct NodeGeometryCollectionInfo {
uint8_t transform_space;
} NodeGeometryCollectionInfo;
-typedef struct NodeGeometryAttributeProximity {
- /* GeometryNodeAttributeProximityTargetType. */
- uint8_t target_geometry_element;
-} NodeGeometryAttributeProximity;
-
typedef struct NodeGeometryProximity {
/* GeometryNodeProximityTargetType. */
uint8_t target_element;
@@ -1412,27 +1274,6 @@ typedef struct NodeGeometryVolumeToMesh {
uint8_t resolution_mode;
} NodeGeometryVolumeToMesh;
-typedef struct NodeAttributeCombineXYZ {
- /* GeometryNodeAttributeInputMode. */
- uint8_t input_type_x;
- uint8_t input_type_y;
- uint8_t input_type_z;
-
- char _pad[1];
-} NodeAttributeCombineXYZ;
-
-typedef struct NodeAttributeSeparateXYZ {
- /* GeometryNodeAttributeInputMode. */
- uint8_t input_type;
-} NodeAttributeSeparateXYZ;
-
-typedef struct NodeAttributeConvert {
- /* CustomDataType. */
- int8_t data_type;
- /* AttributeDomain. */
- int8_t domain;
-} NodeAttributeConvert;
-
typedef struct NodeGeometrySubdivisionSurface {
/* eSubsurfUVSmooth. */
uint8_t uv_smooth;
@@ -1521,11 +1362,6 @@ typedef struct NodeGeometryCurveResample {
uint8_t mode;
} NodeGeometryCurveResample;
-typedef struct NodeGeometryCurveSubdivide {
- /* GeometryNodeAttributeInputMode (integer or attribute). */
- uint8_t cuts_type;
-} NodeGeometryCurveSubdivide;
-
typedef struct NodeGeometryCurveFillet {
/* GeometryNodeCurveFilletMode. */
uint8_t mode;
@@ -1546,13 +1382,6 @@ typedef struct NodeGeometryCurveSample {
uint8_t mode;
} NodeGeometryCurveSample;
-typedef struct NodeGeometryAttributeTransfer {
- /* AttributeDomain. */
- int8_t domain;
- /* GeometryNodeAttributeTransferMapMode. */
- uint8_t mapping;
-} NodeGeometryAttributeTransfer;
-
typedef struct NodeGeometryTransferAttribute {
/* CustomDataType. */
int8_t data_type;
@@ -2080,12 +1909,6 @@ typedef enum NodeShaderOutputTarget {
/* Geometry Nodes */
-typedef enum GeometryNodeAttributeProximityTargetType {
- GEO_NODE_PROXIMITY_TARGET_POINTS = 0,
- GEO_NODE_PROXIMITY_TARGET_EDGES = 1,
- GEO_NODE_PROXIMITY_TARGET_FACES = 2,
-} GeometryNodeAttributeProximityTargetType;
-
typedef enum GeometryNodeProximityTargetType {
GEO_NODE_PROX_TARGET_POINTS = 0,
GEO_NODE_PROX_TARGET_EDGES = 1,
@@ -2134,30 +1957,6 @@ typedef enum GeometryNodeTriangulateQuads {
GEO_NODE_TRIANGULATE_QUAD_LONGEDGE = 4,
} GeometryNodeTriangulateQuads;
-typedef enum GeometryNodePointInstanceType {
- GEO_NODE_POINT_INSTANCE_TYPE_OBJECT = 0,
- GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION = 1,
- GEO_NODE_POINT_INSTANCE_TYPE_GEOMETRY = 2,
-} GeometryNodePointInstanceType;
-
-typedef enum GeometryNodePointInstanceFlag {
- GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION = (1 << 0),
-} GeometryNodePointInstanceFlag;
-
-typedef enum GeometryNodeAttributeInputMode {
- GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE = 0,
- GEO_NODE_ATTRIBUTE_INPUT_FLOAT = 1,
- GEO_NODE_ATTRIBUTE_INPUT_VECTOR = 2,
- GEO_NODE_ATTRIBUTE_INPUT_COLOR = 3,
- GEO_NODE_ATTRIBUTE_INPUT_BOOLEAN = 4,
- GEO_NODE_ATTRIBUTE_INPUT_INTEGER = 5,
-} GeometryNodeAttributeInputMode;
-
-typedef enum GeometryNodePointDistributeMode {
- GEO_NODE_POINT_DISTRIBUTE_RANDOM = 0,
- GEO_NODE_POINT_DISTRIBUTE_POISSON = 1,
-} GeometryNodePointDistributeMode;
-
typedef enum GeometryNodeDistributePointsOnFacesMode {
GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM = 0,
GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_POISSON = 1,
@@ -2169,54 +1968,16 @@ typedef enum GeometryNodeExtrudeMeshMode {
GEO_NODE_EXTRUDE_MESH_FACES = 2,
} GeometryNodeExtrudeMeshMode;
-typedef enum GeometryNodeRotatePointsType {
- GEO_NODE_POINT_ROTATE_TYPE_EULER = 0,
- GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE = 1,
-} GeometryNodeRotatePointsType;
-
-typedef enum FunctionNodeRotatePointsType {
+typedef enum FunctionNodeRotateEulerType {
FN_NODE_ROTATE_EULER_TYPE_EULER = 0,
FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE = 1,
-} FunctionNodeRotatePointsType;
-
-typedef enum GeometryNodeAttributeVectorRotateMode {
- GEO_NODE_VECTOR_ROTATE_TYPE_AXIS = 0,
- GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_X = 1,
- GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_Y = 2,
- GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_Z = 3,
- GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ = 4,
-} GeometryNodeAttributeVectorRotateMode;
-
-typedef enum GeometryNodeAttributeRandomizeMode {
- GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE = 0,
- GEO_NODE_ATTRIBUTE_RANDOMIZE_ADD = 1,
- GEO_NODE_ATTRIBUTE_RANDOMIZE_SUBTRACT = 2,
- GEO_NODE_ATTRIBUTE_RANDOMIZE_MULTIPLY = 3,
-} GeometryNodeAttributeRandomizeMode;
-
-typedef enum GeometryNodeRotatePointsSpace {
- GEO_NODE_POINT_ROTATE_SPACE_OBJECT = 0,
- GEO_NODE_POINT_ROTATE_SPACE_POINT = 1,
-} GeometryNodeRotatePointsSpace;
+} FunctionNodeRotateEulerType;
typedef enum FunctionNodeRotateEulerSpace {
FN_NODE_ROTATE_EULER_SPACE_OBJECT = 0,
FN_NODE_ROTATE_EULER_SPACE_LOCAL = 1,
} FunctionNodeRotateEulerSpace;
-typedef enum GeometryNodeAlignRotationToVectorAxis {
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_X = 0,
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_Y = 1,
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_Z = 2,
-} GeometryNodeAlignRotationToVectorAxis;
-
-typedef enum GeometryNodeAlignRotationToVectorPivotAxis {
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO = 0,
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_X = 1,
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Y = 2,
- GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Z = 3,
-} GeometryNodeAlignRotationToVectorPivotAxis;
-
typedef enum NodeAlignEulerToVectorAxis {
FN_NODE_ALIGN_EULER_TO_VECTOR_AXIS_X = 0,
FN_NODE_ALIGN_EULER_TO_VECTOR_AXIS_Y = 1,
@@ -2295,11 +2056,6 @@ typedef enum GeometryNodeCurveFilletMode {
GEO_NODE_CURVE_FILLET_POLY = 1,
} GeometryNodeCurveFilletMode;
-typedef enum GeometryNodeAttributeTransferMapMode {
- GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED = 0,
- GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER_NEAREST = 1,
-} GeometryNodeAttributeTransferMapMode;
-
typedef enum GeometryNodeAttributeTransferMode {
GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED = 0,
GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST = 1,
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 31b67d4eb19..373aec975c2 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -173,11 +173,7 @@ static char *rna_ColorRamp_path(PointerRNA *ptr)
char *node_path;
for (node = ntree->nodes.first; node; node = node->next) {
- if (ELEM(node->type,
- SH_NODE_VALTORGB,
- CMP_NODE_VALTORGB,
- TEX_NODE_VALTORGB,
- GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP)) {
+ if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
if (node->storage == ptr->data) {
/* all node color ramp properties called 'color_ramp'
* prepend path from ID to the node
@@ -304,11 +300,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
- if (ELEM(node->type,
- SH_NODE_VALTORGB,
- CMP_NODE_VALTORGB,
- TEX_NODE_VALTORGB,
- GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP)) {
+ if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
BKE_ntree_update_tag_node_property(ntree, node);
ED_node_tree_propagate_change(NULL, bmain, ntree);
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index f212b4a1d23..2c6a4f5adeb 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -461,30 +461,6 @@ const EnumPropertyItem rna_enum_node_filter_items[] = {
{0, NULL, 0, NULL, NULL},
};
-static const EnumPropertyItem rna_node_geometry_attribute_randomize_operation_items[] = {
- {GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE,
- "REPLACE_CREATE",
- ICON_NONE,
- "Replace/Create",
- "Replace the value and data type of an existing attribute, or create a new one"},
- {GEO_NODE_ATTRIBUTE_RANDOMIZE_ADD,
- "ADD",
- ICON_NONE,
- "Add",
- "Add the random values to the existing attribute values"},
- {GEO_NODE_ATTRIBUTE_RANDOMIZE_SUBTRACT,
- "SUBTRACT",
- ICON_NONE,
- "Subtract",
- "Subtract random values from the existing attribute values"},
- {GEO_NODE_ATTRIBUTE_RANDOMIZE_MULTIPLY,
- "MULTIPLY",
- ICON_NONE,
- "Multiply",
- "Multiply the existing attribute values with the random values"},
- {0, NULL, 0, NULL, NULL},
-};
-
static const EnumPropertyItem rna_node_geometry_curve_handle_type_items[] = {
{GEO_NODE_CURVE_HANDLE_FREE,
"FREE",
@@ -547,73 +523,8 @@ static EnumPropertyItem rna_node_geometry_mesh_circle_fill_type_items[] = {
};
#endif
-#define ITEM_ATTRIBUTE \
- { \
- GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE, "ATTRIBUTE", 0, "Attribute", "" \
- }
-#define ITEM_FLOAT \
- { \
- GEO_NODE_ATTRIBUTE_INPUT_FLOAT, "FLOAT", 0, "Float", "" \
- }
-#define ITEM_VECTOR \
- { \
- GEO_NODE_ATTRIBUTE_INPUT_VECTOR, "VECTOR", 0, "Vector", "" \
- }
-#define ITEM_COLOR \
- { \
- GEO_NODE_ATTRIBUTE_INPUT_COLOR, "COLOR", 0, "Color", "" \
- }
-#define ITEM_INTEGER \
- { \
- GEO_NODE_ATTRIBUTE_INPUT_INTEGER, "INTEGER", 0, "Integer", "" \
- }
-#define ITEM_BOOLEAN \
- { \
- GEO_NODE_ATTRIBUTE_INPUT_BOOLEAN, "BOOLEAN", 0, "Boolean", "" \
- }
-
-/* Used in both runtime and static code. */
-static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_any[] = {
- ITEM_ATTRIBUTE,
- ITEM_FLOAT,
- ITEM_VECTOR,
- ITEM_COLOR,
- ITEM_INTEGER,
- ITEM_BOOLEAN,
- {0, NULL, 0, NULL, NULL},
-};
-
#ifndef RNA_RUNTIME
-static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_vector[] = {
- ITEM_ATTRIBUTE,
- ITEM_VECTOR,
- {0, NULL, 0, NULL, NULL},
-};
-static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_float_vector[] = {
- ITEM_ATTRIBUTE,
- ITEM_FLOAT,
- ITEM_VECTOR,
- {0, NULL, 0, NULL, NULL},
-};
-static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_float[] = {
- ITEM_ATTRIBUTE,
- ITEM_FLOAT,
- {0, NULL, 0, NULL, NULL},
-};
-static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_int[] = {
- ITEM_ATTRIBUTE,
- ITEM_INTEGER,
- {0, NULL, 0, NULL, NULL},
-};
-static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_no_boolean[] = {
- ITEM_ATTRIBUTE,
- ITEM_FLOAT,
- ITEM_VECTOR,
- ITEM_COLOR,
- {0, NULL, 0, NULL, NULL},
-};
-
#endif
#undef ITEM_ATTRIBUTE
@@ -2170,31 +2081,6 @@ static const EnumPropertyItem *rna_FunctionNodeCompare_operation_itemf(bContext
}
}
-static bool attribute_clamp_type_supported(const EnumPropertyItem *item)
-{
- return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_INT32, CD_PROP_COLOR);
-}
-
-static const EnumPropertyItem *rna_GeometryNodeAttributeClamp_type_itemf(bContext *UNUSED(C),
- PointerRNA *UNUSED(ptr),
- PropertyRNA *UNUSED(prop),
- bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_attribute_type_items, attribute_clamp_type_supported);
-}
-
-static bool attribute_random_type_supported(const EnumPropertyItem *item)
-{
- return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_BOOL, CD_PROP_INT32);
-}
-static const EnumPropertyItem *rna_GeometryNodeAttributeRandom_type_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_attribute_type_items, attribute_random_type_supported);
-}
-
static bool random_value_type_supported(const EnumPropertyItem *item)
{
return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_BOOL, CD_PROP_INT32);
@@ -2222,49 +2108,6 @@ static const EnumPropertyItem *rna_GeoNodeAccumulateField_type_itemf(bContext *U
return itemf_function_check(rna_enum_attribute_type_items, accumulate_field_type_supported);
}
-static const EnumPropertyItem *rna_GeometryNodeAttributeRandomize_operation_itemf(
- bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
-{
- bNode *node = ptr->data;
- const NodeAttributeRandomize *node_storage = (NodeAttributeRandomize *)node->storage;
- const CustomDataType data_type = (CustomDataType)node_storage->data_type;
-
- EnumPropertyItem *item_array = NULL;
- int items_len = 0;
- for (const EnumPropertyItem *item = rna_node_geometry_attribute_randomize_operation_items;
- item->identifier != NULL;
- item++) {
- if (data_type == CD_PROP_BOOL) {
- if (item->value == GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- }
- else {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- }
- RNA_enum_item_end(&item_array, &items_len);
-
- *r_free = true;
- return item_array;
-}
-
-static void rna_GeometryNodeAttributeRandomize_data_type_update(Main *bmain,
- Scene *scene,
- PointerRNA *ptr)
-{
- bNode *node = ptr->data;
- NodeAttributeRandomize *node_storage = (NodeAttributeRandomize *)node->storage;
-
- /* The boolean data type has no extra operations besides,
- * replace, so make sure the enum value is set properly. */
- if (node_storage->data_type == CD_PROP_BOOL) {
- node_storage->operation = GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE;
- }
-
- rna_Node_socket_update(bmain, scene, ptr);
-}
-
static void rna_GeometryNodeCompare_data_type_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNode *node = ptr->data;
@@ -2289,37 +2132,18 @@ static void rna_GeometryNodeCompare_data_type_update(Main *bmain, Scene *scene,
rna_Node_socket_update(bmain, scene, ptr);
}
-static bool attribute_convert_type_supported(const EnumPropertyItem *item)
-{
- return ELEM(item->value,
- CD_AUTO_FROM_NAME,
- CD_PROP_FLOAT,
- CD_PROP_FLOAT2,
- CD_PROP_FLOAT3,
- CD_PROP_COLOR,
- CD_PROP_BOOL,
- CD_PROP_INT32);
-}
-static const EnumPropertyItem *rna_GeometryNodeAttributeConvert_type_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_attribute_type_with_auto_items,
- attribute_convert_type_supported);
-}
-
-static bool attribute_fill_type_supported(const EnumPropertyItem *item)
+static bool generic_attribute_type_supported(const EnumPropertyItem *item)
{
return ELEM(
item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL, CD_PROP_INT32);
}
-static const EnumPropertyItem *rna_GeometryNodeAttributeFill_type_itemf(bContext *UNUSED(C),
+static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext *UNUSED(C),
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
*r_free = true;
- return itemf_function_check(rna_enum_attribute_type_items, attribute_fill_type_supported);
+ return itemf_function_check(rna_enum_attribute_type_items, generic_attribute_type_supported);
}
static bool transfer_attribute_type_supported(const EnumPropertyItem *item)
@@ -2327,7 +2151,6 @@ static bool transfer_attribute_type_supported(const EnumPropertyItem *item)
return ELEM(
item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL, CD_PROP_INT32);
}
-
static const EnumPropertyItem *rna_NodeGeometryTransferAttribute_type_itemf(
bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
{
@@ -2346,122 +2169,6 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeStatistic_type_itemf(
return itemf_function_check(rna_enum_attribute_type_items, attribute_statistic_type_supported);
}
-/**
- * This bit of ugly code makes sure the float / attribute option shows up instead of
- * vector / attribute if the node uses an operation that uses a float for input B or C.
- */
-static const EnumPropertyItem *rna_GeometryNodeAttributeVectorMath_input_type_b_itemf(
- bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
-{
- bNode *node = ptr->data;
- NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
-
- EnumPropertyItem *item_array = NULL;
- int items_len = 0;
- for (const EnumPropertyItem *item = rna_node_geometry_attribute_input_type_items_any;
- item->identifier != NULL;
- item++) {
- if (item->value == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- else if (item->value == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) {
- if (node_storage->operation == NODE_VECTOR_MATH_SCALE) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- }
- else if (item->value == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) {
- if (node_storage->operation != NODE_VECTOR_MATH_SCALE) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- }
- }
- RNA_enum_item_end(&item_array, &items_len);
-
- *r_free = true;
- return item_array;
-}
-
-static const EnumPropertyItem *rna_GeometryNodeAttributeVectorMath_input_type_c_itemf(
- bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
-{
- bNode *node = ptr->data;
- NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
-
- EnumPropertyItem *item_array = NULL;
- int items_len = 0;
- for (const EnumPropertyItem *item = rna_node_geometry_attribute_input_type_items_any;
- item->identifier != NULL;
- item++) {
- if (item->value == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- else if (item->value == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) {
- if (node_storage->operation == NODE_VECTOR_MATH_REFRACT) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- }
- else if (item->value == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) {
- if (node_storage->operation != NODE_VECTOR_MATH_REFRACT) {
- RNA_enum_item_add(&item_array, &items_len, item);
- }
- }
- }
- RNA_enum_item_end(&item_array, &items_len);
-
- *r_free = true;
- return item_array;
-}
-
-static void rna_GeometryNodeAttributeVectorMath_operation_update(Main *bmain,
- Scene *scene,
- PointerRNA *ptr)
-{
- bNode *node = ptr->data;
- NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
-
- const NodeVectorMathOperation operation = (NodeVectorMathOperation)node_storage->operation;
-
- /* The scale operation can't use a vector input, so reset
- * the input type enum in case it's set to vector. */
- if (operation == NODE_VECTOR_MATH_SCALE) {
- if (node_storage->input_type_b == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) {
- node_storage->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- }
- }
-
- /* Scale is also the only operation that uses the float input type, so a
- * a check is also necessary for the other direction. */
- if (operation != NODE_VECTOR_MATH_SCALE) {
- if (node_storage->input_type_b == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) {
- node_storage->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- }
- }
-
- rna_Node_socket_update(bmain, scene, ptr);
-}
-
-static bool attribute_map_range_type_supported(const EnumPropertyItem *item)
-{
- return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3);
-}
-static const EnumPropertyItem *rna_GeometryNodeAttributeMapRange_type_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_attribute_type_items, attribute_map_range_type_supported);
-}
-
-static bool attribute_curve_map_type_supported(const EnumPropertyItem *item)
-{
- return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR);
-}
-static const EnumPropertyItem *rna_GeometryNodeAttributeCurveMap_type_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
-{
- *r_free = true;
- return itemf_function_check(rna_enum_attribute_type_items, attribute_curve_map_type_supported);
-}
-
static StructRNA *rna_ShaderNode_register(Main *bmain,
ReportList *reports,
void *data,
@@ -9636,71 +9343,6 @@ static void def_fn_random_value(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_attribute_randomize(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeRandomize", "storage");
-
- prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "data_type");
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeRandom_type_itemf");
- RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
- RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
- RNA_def_property_update(
- prop, NC_NODE | NA_EDITED, "rna_GeometryNodeAttributeRandomize_data_type_update");
-
- prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "operation");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_randomize_operation_items);
- RNA_def_property_enum_funcs(
- prop, NULL, NULL, "rna_GeometryNodeAttributeRandomize_operation_itemf");
- RNA_def_property_enum_default(prop, GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE);
- RNA_def_property_ui_text(prop, "Operation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_attribute_fill(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
- RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
- RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
-
- prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "custom2");
- RNA_def_property_enum_items(prop, rna_enum_attribute_domain_with_auto_items);
- RNA_def_property_enum_default(prop, ATTR_DOMAIN_AUTO);
- RNA_def_property_ui_text(prop, "Domain", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-}
-
-static void def_geo_attribute_convert(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeConvert", "storage");
-
- prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_with_auto_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeConvert_type_itemf");
- RNA_def_property_enum_default(prop, CD_AUTO_FROM_NAME);
- RNA_def_property_ui_text(prop, "Data Type", "The data type to save the result attribute with");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
-
- prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_attribute_domain_with_auto_items);
- RNA_def_property_enum_default(prop, ATTR_DOMAIN_AUTO);
- RNA_def_property_ui_text(prop, "Domain", "The geometry domain to save the result attribute in");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-}
-
static void def_geo_attribute_statistic(StructRNA *srna)
{
PropertyRNA *prop;
@@ -9724,229 +9366,6 @@ static void def_geo_attribute_statistic(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
-static void def_geo_attribute_math(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeMath", "storage");
-
- prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "operation");
- RNA_def_property_enum_items(prop, rna_enum_node_math_items);
- RNA_def_property_enum_default(prop, NODE_MATH_ADD);
- RNA_def_property_ui_text(prop, "Operation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_a", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_a");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type A", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_b", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_b");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type B", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_c", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_c");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type C", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_attribute_vector_math(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeVectorMath", "storage");
-
- prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "operation");
- RNA_def_property_enum_items(prop, rna_enum_node_vec_math_items);
- RNA_def_property_ui_text(prop, "Operation", "");
- RNA_def_property_update(
- prop, NC_NODE | NA_EDITED, "rna_GeometryNodeAttributeVectorMath_operation_update");
-
- prop = RNA_def_property(srna, "input_type_a", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_a");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type A", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_b", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_b");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_any);
- RNA_def_property_enum_funcs(
- prop, NULL, NULL, "rna_GeometryNodeAttributeVectorMath_input_type_b_itemf");
- RNA_def_property_ui_text(prop, "Input Type B", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_c", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_c");
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_any);
- RNA_def_property_enum_funcs(
- prop, NULL, NULL, "rna_GeometryNodeAttributeVectorMath_input_type_c_itemf");
- RNA_def_property_ui_text(prop, "Input Type C", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_attribute_map_range(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeMapRange", "storage");
-
- prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "data_type");
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeMapRange_type_itemf");
- RNA_def_property_ui_text(prop, "Data Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "interpolation_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "interpolation_type");
- RNA_def_property_enum_items(prop, rna_enum_node_map_range_items);
- RNA_def_property_ui_text(prop, "Interpolation Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
-}
-
-static void def_geo_point_instance(StructRNA *srna)
-{
- static const EnumPropertyItem instance_type_items[] = {
- {GEO_NODE_POINT_INSTANCE_TYPE_OBJECT,
- "OBJECT",
- ICON_NONE,
- "Object",
- "Instance an individual object on all points"},
- {GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION,
- "COLLECTION",
- ICON_NONE,
- "Collection",
- "Instance an entire collection on all points"},
- {GEO_NODE_POINT_INSTANCE_TYPE_GEOMETRY,
- "GEOMETRY",
- ICON_NONE,
- "Geometry",
- "Copy geometry to all points"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
- RNA_def_struct_sdna_from(srna, "NodeGeometryPointInstance", "storage");
-
- prop = RNA_def_property(srna, "instance_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "instance_type");
- RNA_def_property_enum_items(prop, instance_type_items);
- RNA_def_property_enum_default(prop, GEO_NODE_POINT_INSTANCE_TYPE_OBJECT);
- RNA_def_property_ui_text(prop, "Instance Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "use_whole_collection", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION);
- RNA_def_property_ui_text(prop, "Whole Collection", "Instance entire collection on each point");
- RNA_def_property_update(prop, 0, "rna_Node_socket_update");
-}
-
-static void def_geo_attribute_mix(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeMix", "storage");
-
- prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_ramp_blend_items);
- RNA_def_property_enum_default(prop, MA_RAMP_BLEND);
- RNA_def_property_ui_text(prop, "Blending Mode", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "input_type_factor", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Factor", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_a", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_no_boolean);
- RNA_def_property_ui_text(prop, "Input Type A", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_b", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_no_boolean);
- RNA_def_property_ui_text(prop, "Input Type B", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_attribute_clamp(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeClamp", "storage");
-
- prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_bitflag_sdna(prop, NULL, "data_type");
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeClamp_type_itemf");
- RNA_def_property_ui_text(prop, "Data Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_node_clamp_items);
- RNA_def_property_enum_default(prop, NODE_CLAMP_MINMAX);
- RNA_def_property_ui_text(prop, "Operation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-}
-
-static void def_geo_attribute_attribute_compare(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeCompare", "storage");
-
- prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_node_float_compare_items);
- RNA_def_property_enum_default(prop, NODE_COMPARE_GREATER_THAN);
- RNA_def_property_ui_text(prop, "Operation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_a", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_no_boolean);
- RNA_def_property_ui_text(prop, "Input Type A", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_b", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_no_boolean);
- RNA_def_property_ui_text(prop, "Input Type B", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_point_distribute(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- static const EnumPropertyItem rna_node_geometry_point_distribute_method_items[] = {
- {GEO_NODE_POINT_DISTRIBUTE_RANDOM,
- "RANDOM",
- 0,
- "Random",
- "Distribute points randomly on the surface"},
- {GEO_NODE_POINT_DISTRIBUTE_POISSON,
- "POISSON",
- 0,
- "Poisson Disk",
- "Distribute the points randomly on the surface while taking a minimum distance between "
- "points into account"},
- {0, NULL, 0, NULL, NULL},
- };
-
- prop = RNA_def_property(srna, "distribute_method", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "custom1");
- RNA_def_property_enum_items(prop, rna_node_geometry_point_distribute_method_items);
- RNA_def_property_enum_default(prop, GEO_NODE_POINT_DISTRIBUTE_RANDOM);
- RNA_def_property_ui_text(prop, "Distribution Method", "Method to use for scattering points");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_extrude_mesh(StructRNA *srna)
{
PropertyRNA *prop;
@@ -9995,97 +9414,6 @@ static void def_geo_distribute_points_on_faces(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_attribute_color_ramp(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeColorRamp", "storage");
-
- prop = RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "ColorRamp");
- RNA_def_property_ui_text(prop, "Color Ramp", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-}
-
-static void def_geo_attribute_curve_map(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeCurveMap", "storage");
-
- prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "data_type");
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeCurveMap_type_itemf");
- RNA_def_property_ui_text(prop, "Data Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "curve_vec", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "CurveMapping");
- RNA_def_property_ui_text(prop, "Mapping", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "curve_rgb", PROP_POINTER, PROP_NONE);
- RNA_def_property_struct_type(prop, "CurveMapping");
- RNA_def_property_ui_text(prop, "Mapping", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-}
-
-static void def_geo_attribute_vector_rotate(StructRNA *srna)
-{
- static const EnumPropertyItem rotate_mode_items[] = {
- {GEO_NODE_VECTOR_ROTATE_TYPE_AXIS,
- "AXIS_ANGLE",
- 0,
- "Axis Angle",
- "Rotate a point using axis angle"},
- {GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_X, "X_AXIS", 0, "X Axis", "Rotate a point using X axis"},
- {GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_Y, "Y_AXIS", 0, "Y Axis", "Rotate a point using Y axis"},
- {GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_Z, "Z_AXIS", 0, "Z Axis", "Rotate a point using Z axis"},
- {GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ,
- "EULER_XYZ",
- 0,
- "Euler",
- "Rotate a point using XYZ order"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeVectorRotate", "storage");
-
- prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "mode");
- RNA_def_property_enum_items(prop, rotate_mode_items);
- RNA_def_property_ui_text(prop, "Mode", "Type of rotation");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
-
- prop = RNA_def_property(srna, "input_type_vector", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Vector", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_center", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Center", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_axis", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Axis", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_angle", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Angle", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_rotation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Rotation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_curve_spline_type(StructRNA *srna)
{
static const EnumPropertyItem type_items[] = {
@@ -10121,24 +9449,6 @@ static void def_geo_curve_set_handle_type(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_legacy_curve_set_handles(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryCurveSetHandles", "storage");
-
- prop = RNA_def_property(srna, "handle_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "handle_type");
- RNA_def_property_enum_items(prop, rna_node_geometry_curve_handle_type_items);
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_curve_handle_side_items);
- RNA_def_property_ui_text(prop, "Mode", "Whether to update left and right handles");
- RNA_def_property_flag(prop, PROP_ENUM_FLAG);
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_curve_set_handle_positions(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10151,24 +9461,6 @@ static void def_geo_curve_set_handle_positions(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_curve_select_handles(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryCurveSelectHandles", "storage");
-
- prop = RNA_def_property(srna, "handle_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "handle_type");
- RNA_def_property_enum_items(prop, rna_node_geometry_curve_handle_type_items);
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_curve_handle_side_items);
- RNA_def_property_ui_text(prop, "Mode", "Whether to check the type of left and right handles");
- RNA_def_property_flag(prop, PROP_ENUM_FLAG);
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_curve_handle_type_selection(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10266,66 +9558,6 @@ static void def_geo_curve_primitive_line(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_point_rotate(StructRNA *srna)
-{
- static const EnumPropertyItem type_items[] = {
- {GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE,
- "AXIS_ANGLE",
- ICON_NONE,
- "Axis Angle",
- "Rotate around an axis by an angle"},
- {GEO_NODE_POINT_ROTATE_TYPE_EULER,
- "EULER",
- ICON_NONE,
- "Euler",
- "Rotate around the X, Y, and Z axes"},
- {0, NULL, 0, NULL, NULL},
- };
-
- static const EnumPropertyItem space_items[] = {
- {GEO_NODE_POINT_ROTATE_SPACE_OBJECT,
- "OBJECT",
- ICON_NONE,
- "Object",
- "Rotate points in the local space of the object"},
- {GEO_NODE_POINT_ROTATE_SPACE_POINT,
- "POINT",
- ICON_NONE,
- "Point",
- "Rotate every point in its local space (as defined by the 'rotation' attribute)"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryRotatePoints", "storage");
-
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, type_items);
- RNA_def_property_ui_text(prop, "Type", "Method used to describe the rotation");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, space_items);
- RNA_def_property_ui_text(prop, "Space", "Base orientation of the points");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "input_type_axis", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Axis", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_angle", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Angle", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_rotation", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Rotation", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_fn_rotate_euler(StructRNA *srna)
{
static const EnumPropertyItem type_items[] = {
@@ -10371,76 +9603,6 @@ static void def_fn_rotate_euler(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
-static void def_geo_align_rotation_to_vector(StructRNA *srna)
-{
- static const EnumPropertyItem axis_items[] = {
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_X,
- "X",
- ICON_NONE,
- "X",
- "Align the X axis with the vector"},
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_Y,
- "Y",
- ICON_NONE,
- "Y",
- "Align the Y axis with the vector"},
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_Z,
- "Z",
- ICON_NONE,
- "Z",
- "Align the Z axis with the vector"},
- {0, NULL, 0, NULL, NULL},
- };
-
- static const EnumPropertyItem pivot_axis_items[] = {
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO,
- "AUTO",
- ICON_NONE,
- "Auto",
- "Automatically detect the best rotation axis to rotate towards the vector"},
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_X,
- "X",
- ICON_NONE,
- "X",
- "Rotate around the local X axis"},
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Y,
- "Y",
- ICON_NONE,
- "Y",
- "Rotate around the local Y axis"},
- {GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_Z,
- "Z",
- ICON_NONE,
- "Z",
- "Rotate around the local Z axis"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryAlignRotationToVector", "storage");
-
- prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, axis_items);
- RNA_def_property_ui_text(prop, "Axis", "Axis to align to the vector");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "pivot_axis", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, pivot_axis_items);
- RNA_def_property_ui_text(prop, "Pivot Axis", "Axis to rotate around");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "input_type_factor", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Factor", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_vector", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Vector", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_fn_align_euler_to_vector(StructRNA *srna)
{
static const EnumPropertyItem axis_items[] = {
@@ -10501,30 +9663,6 @@ static void def_fn_align_euler_to_vector(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
-static void def_geo_point_scale(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryPointScale", "storage");
-
- prop = RNA_def_property(srna, "input_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float_vector);
- RNA_def_property_ui_text(prop, "Input Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_point_translate(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryPointTranslate", "storage");
-
- prop = RNA_def_property(srna, "input_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_object_info(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10555,37 +9693,6 @@ static void def_geo_object_info(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations");
}
-static void def_geo_legacy_points_to_volume(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- static EnumPropertyItem resolution_mode_items[] = {
- {GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT,
- "VOXEL_AMOUNT",
- 0,
- "Amount",
- "Specify the approximate number of voxels along the diagonal"},
- {GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE,
- "VOXEL_SIZE",
- 0,
- "Size",
- "Specify the voxel side length"},
- {0, NULL, 0, NULL, NULL},
- };
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryPointsToVolume", "storage");
-
- prop = RNA_def_property(srna, "resolution_mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, resolution_mode_items);
- RNA_def_property_ui_text(prop, "Resolution Mode", "How the voxel size is specified");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_radius", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Radius Input Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_points_to_volume(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10639,39 +9746,6 @@ static void def_geo_collection_info(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations");
}
-static void def_geo_legacy_attribute_proximity(StructRNA *srna)
-{
- static const EnumPropertyItem target_geometry_element[] = {
- {GEO_NODE_PROXIMITY_TARGET_POINTS,
- "POINTS",
- ICON_NONE,
- "Points",
- "Calculate proximity to the target's points (usually faster than the other two modes)"},
- {GEO_NODE_PROXIMITY_TARGET_EDGES,
- "EDGES",
- ICON_NONE,
- "Edges",
- "Calculate proximity to the target's edges"},
- {GEO_NODE_PROXIMITY_TARGET_FACES,
- "FACES",
- ICON_NONE,
- "Faces",
- "Calculate proximity to the target's faces"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryAttributeProximity", "storage");
-
- prop = RNA_def_property(srna, "target_geometry_element", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, target_geometry_element);
- RNA_def_property_enum_default(prop, GEO_NODE_PROXIMITY_TARGET_FACES);
- RNA_def_property_ui_text(
- prop, "Target Geometry", "Element of the target geometry to calculate the distance from");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_proximity(StructRNA *srna)
{
static const EnumPropertyItem target_element_items[] = {
@@ -10736,40 +9810,6 @@ static void def_geo_volume_to_mesh(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_attribute_combine_xyz(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeCombineXYZ", "storage");
-
- prop = RNA_def_property(srna, "input_type_x", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type X", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_y", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Y", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_z", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Z", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
-static void def_geo_attribute_separate_xyz(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeAttributeSeparateXYZ", "storage");
-
- prop = RNA_def_property(srna, "input_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_mesh_circle(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10936,18 +9976,6 @@ static void def_geo_curve_resample(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_legacy_curve_subdivide(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryCurveSubdivide", "storage");
-
- prop = RNA_def_property(srna, "cuts_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_int);
- RNA_def_property_ui_text(prop, "Cuts Type", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_curve_fillet(StructRNA *srna)
{
PropertyRNA *prop;
@@ -10974,38 +10002,6 @@ static void def_geo_curve_fillet(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_legacy_curve_to_points(StructRNA *srna)
-{
- PropertyRNA *prop;
-
- static EnumPropertyItem mode_items[] = {
- {GEO_NODE_CURVE_RESAMPLE_EVALUATED,
- "EVALUATED",
- 0,
- "Evaluated",
- "Create points from the curve's evaluated points, based on the resolution attribute for "
- "NURBS and Bezier splines"},
- {GEO_NODE_CURVE_RESAMPLE_COUNT,
- "COUNT",
- 0,
- "Count",
- "Sample each spline by evenly distributing the specified number of points"},
- {GEO_NODE_CURVE_RESAMPLE_LENGTH,
- "LENGTH",
- 0,
- "Length",
- "Sample each spline by splitting it into segments with the specified length"},
- {0, NULL, 0, NULL, NULL},
- };
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryCurveToPoints", "storage");
-
- prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, mode_items);
- RNA_def_property_ui_text(prop, "Mode", "How to generate points from the input curve");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_curve_to_points(StructRNA *srna)
{
PropertyRNA *prop;
@@ -11100,40 +10096,6 @@ static void def_geo_curve_trim(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
-static void def_geo_attribute_transfer(StructRNA *srna)
-{
- static EnumPropertyItem mapping_items[] = {
- {GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED,
- "NEAREST_FACE_INTERPOLATED",
- 0,
- "Nearest Face Interpolated",
- "Transfer the attribute from the nearest face on a surface (loose points and edges are "
- "ignored)"},
- {GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER_NEAREST,
- "NEAREST",
- 0,
- "Nearest",
- "Transfer the element from the nearest element (using face and edge centers for the "
- "distance computation)"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryAttributeTransfer", "storage");
-
- prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_attribute_domain_with_auto_items);
- RNA_def_property_enum_default(prop, ATTR_DOMAIN_AUTO);
- RNA_def_property_ui_text(prop, "Domain", "The geometry domain to save the result attribute in");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, mapping_items);
- RNA_def_property_ui_text(prop, "Mapping", "Mapping between geometries");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-}
-
static void def_geo_transfer_attribute(StructRNA *srna)
{
static EnumPropertyItem mapping_items[] = {
@@ -11194,42 +10156,6 @@ static void def_geo_input_material(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
-static void def_geo_legacy_raycast(StructRNA *srna)
-{
- static EnumPropertyItem mapping_items[] = {
- {GEO_NODE_RAYCAST_INTERPOLATED,
- "INTERPOLATED",
- 0,
- "Interpolated",
- "Interpolate the attribute from the corners of the hit face"},
- {GEO_NODE_RAYCAST_NEAREST,
- "NEAREST",
- 0,
- "Nearest",
- "Use the attribute value of the closest mesh element"},
- {0, NULL, 0, NULL, NULL},
- };
-
- PropertyRNA *prop;
-
- RNA_def_struct_sdna_from(srna, "NodeGeometryRaycast", "storage");
-
- prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, mapping_items);
- RNA_def_property_ui_text(prop, "Mapping", "Mapping from the target geometry to hit points");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
-
- prop = RNA_def_property(srna, "input_type_ray_direction", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
- RNA_def_property_ui_text(prop, "Input Type Ray Direction", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-
- prop = RNA_def_property(srna, "input_type_ray_length", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float);
- RNA_def_property_ui_text(prop, "Input Type Ray Length", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
-}
-
static void def_geo_raycast(StructRNA *srna)
{
static EnumPropertyItem mapping_items[] = {
@@ -11257,7 +10183,7 @@ static void def_geo_raycast(StructRNA *srna)
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf");
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
@@ -11289,7 +10215,7 @@ static void def_geo_store_named_attribute(StructRNA *srna)
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf");
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
@@ -11309,7 +10235,7 @@ static void def_geo_input_named_attribute(StructRNA *srna)
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf");
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
RNA_def_property_ui_text(prop, "Data Type", "The data type used to read the attribute values");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
@@ -11323,7 +10249,7 @@ static void def_geo_attribute_capture(StructRNA *srna)
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf");
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
@@ -11550,7 +10476,7 @@ static void def_geo_viewer(StructRNA *srna)
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf");
RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
RNA_def_property_ui_text(prop, "Data Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
@@ -11580,7 +10506,7 @@ static void def_geo_field_at_index(StructRNA *srna)
prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom2");
RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeFill_type_itemf");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf");
RNA_def_property_ui_text(prop, "Data Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
}
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index 7cf425c6e27..0b3d9a6a8ad 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -1607,29 +1607,17 @@ static void panel_draw(const bContext *C, Panel *panel)
}
/* Draw node warnings. */
- bool has_legacy_node = false;
if (nmd->runtime_eval_log != nullptr) {
const geo_log::ModifierLog &log = *static_cast<geo_log::ModifierLog *>(nmd->runtime_eval_log);
log.foreach_node_log([&](const geo_log::NodeLog &node_log) {
for (const geo_log::NodeWarning &warning : node_log.warnings()) {
- if (warning.type == geo_log::NodeWarningType::Legacy) {
- has_legacy_node = true;
- }
- else if (warning.type != geo_log::NodeWarningType::Info) {
+ if (warning.type != geo_log::NodeWarningType::Info) {
uiItemL(layout, warning.message.c_str(), ICON_ERROR);
}
}
});
}
- if (has_legacy_node) {
- uiLayout *row = uiLayoutRow(layout, false);
- uiItemL(row, TIP_("Node tree has legacy node"), ICON_ERROR);
- uiLayout *sub = uiLayoutRow(row, false);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
- uiItemO(sub, "", ICON_VIEWZOOM, "NODE_OT_geometry_node_view_legacy");
- }
-
modifier_panel_end(layout, ptr);
}
diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
index c4aa023faa6..3733b3f69ad 100644
--- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
+++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc
@@ -980,15 +980,11 @@ class GeometryNodesEvaluator {
void execute_geometry_node(const DNode node, NodeState &node_state, NodeTaskRunState *run_state)
{
+ using Clock = std::chrono::steady_clock;
const bNode &bnode = *node->bnode();
NodeParamsProvider params_provider{*this, node, node_state, run_state};
GeoNodeExecParams params{params_provider};
- if (node->idname().find("Legacy") != StringRef::not_found) {
- params.error_message_add(geo_log::NodeWarningType::Legacy,
- TIP_("Legacy node will be removed before Blender 4.0"));
- }
- using Clock = std::chrono::steady_clock;
Clock::time_point begin = Clock::now();
bnode.typeinfo->geometry_node_execute(params);
Clock::time_point end = Clock::now();
@@ -1004,14 +1000,6 @@ class GeometryNodesEvaluator {
NodeState &node_state,
NodeTaskRunState *run_state)
{
- if (node->idname().find("Legacy") != StringRef::not_found) {
- /* Create geometry nodes params just for creating an error message. */
- NodeParamsProvider params_provider{*this, node, node_state, run_state};
- GeoNodeExecParams params{params_provider};
- params.error_message_add(geo_log::NodeWarningType::Legacy,
- TIP_("Legacy node will be removed before Blender 4.0"));
- }
-
LinearAllocator<> &allocator = local_allocators_.local();
bool any_input_is_field = false;
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index a33cdc1b64c..cde4b67e120 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -6,8 +6,6 @@
extern "C" {
#endif
-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_compare(void);
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index be21dd4b88f..064112b7efd 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -15,45 +15,11 @@ void register_node_tree_type_geo(void);
void register_node_type_geo_group(void);
void register_node_type_geo_custom_group(bNodeType *ntype);
-void register_node_type_geo_legacy_attribute_proximity(void);
-void register_node_type_geo_legacy_attribute_randomize(void);
-void register_node_type_geo_legacy_attribute_transfer(void);
-void register_node_type_geo_legacy_curve_endpoints(void);
-void register_node_type_geo_legacy_curve_reverse(void);
-void register_node_type_geo_legacy_curve_set_handles(void);
-void register_node_type_geo_legacy_curve_spline_type(void);
-void register_node_type_geo_legacy_curve_subdivide(void);
-void register_node_type_geo_legacy_curve_to_points(void);
-void register_node_type_geo_legacy_delete_geometry(void);
-void register_node_type_geo_legacy_edge_split(void);
-void register_node_type_geo_legacy_material_assign(void);
-void register_node_type_geo_legacy_mesh_to_curve(void);
-void register_node_type_geo_legacy_points_to_volume(void);
-void register_node_type_geo_legacy_raycast(void);
-void register_node_type_geo_legacy_select_by_handle_type(void);
-void register_node_type_geo_legacy_select_by_material(void);
-void register_node_type_geo_legacy_subdivision_surface(void);
-void register_node_type_geo_legacy_volume_to_mesh(void);
-
void register_node_type_geo_accumulate_field(void);
-void register_node_type_geo_align_rotation_to_vector(void);
void register_node_type_geo_attribute_capture(void);
-void register_node_type_geo_attribute_clamp(void);
-void register_node_type_geo_attribute_color_ramp(void);
-void register_node_type_geo_attribute_combine_xyz(void);
-void register_node_type_geo_attribute_compare(void);
-void register_node_type_geo_attribute_convert(void);
-void register_node_type_geo_attribute_curve_map(void);
void register_node_type_geo_attribute_domain_size(void);
-void register_node_type_geo_attribute_fill(void);
-void register_node_type_geo_attribute_map_range(void);
-void register_node_type_geo_attribute_math(void);
-void register_node_type_geo_attribute_mix(void);
-void register_node_type_geo_legacy_attribute_remove(void);
void register_node_type_geo_attribute_separate_xyz(void);
void register_node_type_geo_attribute_statistic(void);
-void register_node_type_geo_attribute_vector_math(void);
-void register_node_type_geo_attribute_vector_rotate(void);
void register_node_type_geo_boolean(void);
void register_node_type_geo_bounding_box(void);
void register_node_type_geo_collection_info(void);
@@ -134,12 +100,6 @@ void register_node_type_geo_mesh_subdivide(void);
void register_node_type_geo_mesh_to_curve(void);
void register_node_type_geo_mesh_to_points(void);
void register_node_type_geo_object_info(void);
-void register_node_type_geo_point_distribute(void);
-void register_node_type_geo_point_instance(void);
-void register_node_type_geo_point_rotate(void);
-void register_node_type_geo_point_scale(void);
-void register_node_type_geo_point_separate(void);
-void register_node_type_geo_point_translate(void);
void register_node_type_geo_points_to_vertices(void);
void register_node_type_geo_points_to_volume(void);
void register_node_type_geo_proximity(void);
@@ -147,7 +107,6 @@ void register_node_type_geo_raycast(void);
void register_node_type_geo_realize_instances(void);
void register_node_type_geo_remove_attribute(void);
void register_node_type_geo_rotate_instances(void);
-void register_node_type_geo_sample_texture(void);
void register_node_type_geo_scale_elements(void);
void register_node_type_geo_scale_instances(void);
void register_node_type_geo_select_by_handle_type(void);
diff --git a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
index 7ef149d5dc5..113a7efb0a5 100644
--- a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
+++ b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
@@ -144,7 +144,6 @@ enum class NodeWarningType {
Error,
Warning,
Info,
- Legacy,
};
struct NodeWarning {
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 97a6b8a6e63..0e1f181eff1 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -254,8 +254,6 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_NOISE, 0, "TEX_NO
DefNode(TextureNode, TEX_NODE_PROC+TEX_STUCCI, 0, "TEX_STUCCI", TexStucci, "Stucci", "" )
DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DISTNOISE", TexDistNoise, "Distorted Noise", "" )
-DefNode(FunctionNode, FN_NODE_LEGACY_RANDOM_FLOAT, 0, "LEGACY_RANDOM_FLOAT", LegacyRandomFloat, "Random Float", "")
-
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, def_compare, "COMPARE", Compare, "Compare", "")
@@ -273,48 +271,6 @@ DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Sli
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ALIGN_ROTATION_TO_VECTOR, def_geo_align_rotation_to_vector, "LEGACY_ALIGN_ROTATION_TO_VECTOR", LegacyAlignRotationToVector, "Align Rotation to Vector", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_CLAMP, def_geo_attribute_clamp, "LEGACY_ATTRIBUTE_CLAMP", LegacyAttributeClamp, "Attribute Clamp", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP, def_geo_attribute_color_ramp, "LEGACY_ATTRIBUTE_COLOR_RAMP", LegacyAttributeColorRamp, "Attribute Color Ramp", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_COMBINE_XYZ, def_geo_attribute_combine_xyz, "LEGACY_ATTRIBUTE_COMBINE_XYZ", LegacyAttributeCombineXYZ, "Attribute Combine XYZ", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_COMPARE, def_geo_attribute_attribute_compare, "LEGACY_ATTRIBUTE_COMPARE", LegacyAttributeCompare, "Attribute Compare", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_CONVERT, def_geo_attribute_convert, "LEGACY_ATTRIBUTE_CONVERT", LegacyAttributeConvert, "Attribute Convert", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_CURVE_MAP, def_geo_attribute_curve_map, "LEGACY_ATTRIBUTE_CURVE_MAP", LegacyAttributeCurveMap, "Attribute Curve Map", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_FILL, def_geo_attribute_fill, "LEGACY_ATTRIBUTE_FILL", LegacyAttributeFill, "Attribute Fill", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_MAP_RANGE, def_geo_attribute_map_range, "LEGACY_ATTRIBUTE_MAP_RANGE", LegacyAttributeMapRange, "Attribute Map Range", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_MATH, def_geo_attribute_math, "LEGACY_ATTRIBUTE_MATH", LegacyAttributeMath, "Attribute Math", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_MIX, def_geo_attribute_mix, "LEGACY_ATTRIBUTE_MIX", LegacyAttributeMix, "Attribute Mix", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY, def_geo_legacy_attribute_proximity, "LEGACY_ATTRIBUTE_PROXIMITY", LegacyAttributeProximity, "Attribute Proximity", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_RANDOMIZE, def_geo_attribute_randomize, "LEGACY_ATTRIBUTE_RANDOMIZE", LegacyAttributeRandomize, "Attribute Randomize", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_REMOVE, 0, "LEGACY_ATTRIBUTE_REMOVE", LegacyAttributeRemove, "Attribute Remove", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE, 0, "LEGACY_ATTRIBUTE_SAMPLE_TEXTURE", LegacyAttributeSampleTexture, "Attribute Sample Texture", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_SEPARATE_XYZ, def_geo_attribute_separate_xyz, "LEGACY_ATTRIBUTE_SEPARATE_XYZ", LegacyAttributeSeparateXYZ, "Attribute Separate XYZ", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER, def_geo_attribute_transfer, "LEGACY_ATTRIBUTE_TRANSFER", LegacyAttributeTransfer, "Attribute Transfer", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_MATH, def_geo_attribute_vector_math, "LEGACY_ATTRIBUTE_VECTOR_MATH", LegacyAttributeVectorMath, "Attribute Vector Math", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_ROTATE, def_geo_attribute_vector_rotate, "LEGACY_ATTRIBUTE_VECTOR_ROTATE", LegacyAttributeVectorRotate, "Attribute Vector Rotate", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_ENDPOINTS, 0, "LEGACY_CURVE_ENDPOINTS", LegacyCurveEndpoints, "Curve Endpoints", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_REVERSE, 0, "LEGACY_CURVE_REVERSE", LegacyCurveReverse, "Curve Reverse", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_SELECT_HANDLES, def_geo_curve_select_handles, "LEGACY_CURVE_SELECT_HANDLES", LegacyCurveSelectHandles, "Select by Handle Type", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_SET_HANDLES, def_geo_legacy_curve_set_handles, "LEGACY_CURVE_SET_HANDLES", LegacyCurveSetHandles, "Set Handle Type", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_SPLINE_TYPE, def_geo_curve_spline_type, "LEGACY_CURVE_SPLINE_TYPE", LegacyCurveSplineType, "Set Spline Type", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_SUBDIVIDE, def_geo_legacy_curve_subdivide, "LEGACY_CURVE_SUBDIVIDE", LegacyCurveSubdivide, "Curve Subdivide", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_CURVE_TO_POINTS, def_geo_legacy_curve_to_points, "LEGACY_CURVE_TO_POINTS", LegacyCurveToPoints, "Curve to Points", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_DELETE_GEOMETRY, 0, "LEGACY_DELETE_GEOMETRY", LegacyDeleteGeometry, "Delete Geometry", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_EDGE_SPLIT, 0, "LEGACY_EDGE_SPLIT", LegacyEdgeSplit, "Edge Split", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_MATERIAL_ASSIGN, 0, "LEGACY_MATERIAL_ASSIGN", LegacyMaterialAssign, "Material Assign", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_MESH_TO_CURVE, 0, "LEGACY_MESH_TO_CURVE", LegacyMeshToCurve, "Mesh to Curve", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINT_DISTRIBUTE, def_geo_point_distribute, "LEGACY_POINT_DISTRIBUTE", LegacyPointDistribute, "Point Distribute", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINT_INSTANCE, def_geo_point_instance, "LEGACY_POINT_INSTANCE", LegacyPointInstance, "Point Instance", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINT_ROTATE, def_geo_point_rotate, "LEGACY_POINT_ROTATE", LegacyRotatePoints, "Point Rotate", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINT_SCALE, def_geo_point_scale, "LEGACY_POINT_SCALE", LegacyPointScale, "Point Scale", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINT_SEPARATE, 0, "LEGACY_POINT_SEPARATE", LegacyPointSeparate, "Point Separate", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINT_TRANSLATE, def_geo_point_translate, "LEGACY_POINT_TRANSLATE", LegacyPointTranslate, "Point Translate", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_POINTS_TO_VOLUME, def_geo_legacy_points_to_volume, "LEGACY_POINTS_TO_VOLUME", LegacyPointsToVolume, "Points to Volume", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_RAYCAST, def_geo_legacy_raycast, "LEGACY_RAYCAST", LegacyRaycast, "Raycast", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_SELECT_BY_MATERIAL, 0, "LEGACY_SELECT_BY_MATERIAL", LegacySelectByMaterial, "Select by Material", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "LEGACY_SUBDIVISION_SURFACE", LegacySubdivisionSurface, "Subdivision Surface", "")
-DefNode(GeometryNode, GEO_NODE_LEGACY_VOLUME_TO_MESH, def_geo_volume_to_mesh, "LEGACY_VOLUME_TO_MESH", LegacyVolumeToMesh, "Volume to Mesh", "")
-
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC", AttributeStatistic, "Attribute Statistic", "")
DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "")
diff --git a/source/blender/nodes/function/CMakeLists.txt b/source/blender/nodes/function/CMakeLists.txt
index 7ffc5c71b66..6ccc4c7bf5c 100644
--- a/source/blender/nodes/function/CMakeLists.txt
+++ b/source/blender/nodes/function/CMakeLists.txt
@@ -18,8 +18,6 @@ set(INC
set(SRC
- nodes/legacy/node_fn_random_float.cc
-
nodes/node_fn_align_euler_to_vector.cc
nodes/node_fn_boolean_math.cc
nodes/node_fn_compare.cc
diff --git a/source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc b/source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc
deleted file mode 100644
index a34cfe578d0..00000000000
--- a/source/blender/nodes/function/nodes/legacy/node_fn_random_float.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "node_function_util.hh"
-
-#include "BLI_hash.h"
-
-namespace blender::nodes::node_fn_random_float_cc {
-
-static void fn_node_legacy_random_float_declare(NodeDeclarationBuilder &b)
-{
- b.is_function_node();
- b.add_input<decl::Float>(N_("Min")).min(-10000.0f).max(10000.0f);
- b.add_input<decl::Float>(N_("Max")).default_value(1.0f).min(-10000.0f).max(10000.0f);
- b.add_input<decl::Int>(N_("Seed")).min(-10000).max(10000);
- b.add_output<decl::Float>(N_("Value"));
-}
-
-class RandomFloatFunction : public blender::fn::MultiFunction {
- public:
- RandomFloatFunction()
- {
- static blender::fn::MFSignature signature = create_signature();
- this->set_signature(&signature);
- }
-
- static blender::fn::MFSignature create_signature()
- {
- blender::fn::MFSignatureBuilder signature{"Random float"};
- signature.single_input<float>("Min");
- signature.single_input<float>("Max");
- signature.single_input<int>("Seed");
- signature.single_output<float>("Value");
- return signature.build();
- }
-
- void call(blender::IndexMask mask,
- blender::fn::MFParams params,
- blender::fn::MFContext UNUSED(context)) const override
- {
- const blender::VArray<float> &min_values = params.readonly_single_input<float>(0, "Min");
- const blender::VArray<float> &max_values = params.readonly_single_input<float>(1, "Max");
- const blender::VArray<int> &seeds = params.readonly_single_input<int>(2, "Seed");
- blender::MutableSpan<float> values = params.uninitialized_single_output<float>(3, "Value");
-
- for (int64_t i : mask) {
- const float min_value = min_values[i];
- const float max_value = max_values[i];
- const int seed = seeds[i];
- const float value = BLI_hash_int_01(static_cast<uint32_t>(seed));
- values[i] = value * (max_value - min_value) + min_value;
- }
- }
-};
-
-static void fn_node_legacy_random_float_build_multi_function(
- blender::nodes::NodeMultiFunctionBuilder &builder)
-{
- static RandomFloatFunction fn;
- builder.set_matching_fn(fn);
-}
-
-} // namespace blender::nodes::node_fn_random_float_cc
-
-void register_node_type_fn_legacy_random_float()
-{
- namespace file_ns = blender::nodes::node_fn_random_float_cc;
-
- static bNodeType ntype;
-
- fn_node_type_base(&ntype, FN_NODE_LEGACY_RANDOM_FLOAT, "Random Float", 0);
- ntype.declare = file_ns::fn_node_legacy_random_float_declare;
- ntype.build_multi_function = file_ns::fn_node_legacy_random_float_build_multi_function;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 0e99d8ad646..3e6d7c6b408 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -25,48 +25,6 @@ set(INC
set(SRC
- nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc
- nodes/legacy/node_geo_legacy_attribute_clamp.cc
- nodes/legacy/node_geo_legacy_attribute_color_ramp.cc
- nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc
- nodes/legacy/node_geo_legacy_attribute_compare.cc
- nodes/legacy/node_geo_legacy_attribute_convert.cc
- nodes/legacy/node_geo_legacy_attribute_curve_map.cc
- nodes/legacy/node_geo_legacy_attribute_fill.cc
- nodes/legacy/node_geo_legacy_attribute_map_range.cc
- nodes/legacy/node_geo_legacy_attribute_math.cc
- nodes/legacy/node_geo_legacy_attribute_mix.cc
- nodes/legacy/node_geo_legacy_attribute_proximity.cc
- nodes/legacy/node_geo_legacy_attribute_randomize.cc
- nodes/legacy/node_geo_legacy_attribute_remove.cc
- nodes/legacy/node_geo_legacy_attribute_sample_texture.cc
- nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc
- nodes/legacy/node_geo_legacy_attribute_transfer.cc
- nodes/legacy/node_geo_legacy_attribute_vector_math.cc
- nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc
- nodes/legacy/node_geo_legacy_curve_endpoints.cc
- nodes/legacy/node_geo_legacy_curve_reverse.cc
- nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc
- nodes/legacy/node_geo_legacy_curve_set_handles.cc
- nodes/legacy/node_geo_legacy_curve_spline_type.cc
- nodes/legacy/node_geo_legacy_curve_subdivide.cc
- nodes/legacy/node_geo_legacy_curve_to_points.cc
- nodes/legacy/node_geo_legacy_delete_geometry.cc
- nodes/legacy/node_geo_legacy_edge_split.cc
- nodes/legacy/node_geo_legacy_material_assign.cc
- nodes/legacy/node_geo_legacy_mesh_to_curve.cc
- nodes/legacy/node_geo_legacy_point_distribute.cc
- nodes/legacy/node_geo_legacy_point_instance.cc
- nodes/legacy/node_geo_legacy_point_rotate.cc
- nodes/legacy/node_geo_legacy_point_scale.cc
- nodes/legacy/node_geo_legacy_point_separate.cc
- nodes/legacy/node_geo_legacy_point_translate.cc
- nodes/legacy/node_geo_legacy_points_to_volume.cc
- nodes/legacy/node_geo_legacy_raycast.cc
- nodes/legacy/node_geo_legacy_select_by_material.cc
- nodes/legacy/node_geo_legacy_subdivision_surface.cc
- nodes/legacy/node_geo_legacy_volume_to_mesh.cc
-
nodes/node_geo_accumulate_field.cc
nodes/node_geo_attribute_capture.cc
nodes/node_geo_attribute_domain_size.cc
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index fc1c73d2851..7f9ec329efd 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -14,29 +14,6 @@
namespace blender::nodes {
-using bke::GeometryInstanceGroup;
-
-void update_attribute_input_socket_availabilities(bNodeTree &ntree,
- bNode &node,
- const StringRef name,
- const GeometryNodeAttributeInputMode mode,
- const bool name_is_available)
-{
- const GeometryNodeAttributeInputMode mode_ = (GeometryNodeAttributeInputMode)mode;
- LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) {
- if (name == socket->name) {
- const bool socket_is_available =
- name_is_available &&
- ((socket->type == SOCK_STRING && mode_ == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) ||
- (socket->type == SOCK_FLOAT && mode_ == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) ||
- (socket->type == SOCK_INT && mode_ == GEO_NODE_ATTRIBUTE_INPUT_INTEGER) ||
- (socket->type == SOCK_VECTOR && mode_ == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) ||
- (socket->type == SOCK_RGBA && mode_ == GEO_NODE_ATTRIBUTE_INPUT_COLOR));
- nodeSetSocketAvailability(&ntree, socket, socket_is_available);
- }
- }
-}
-
std::optional<CustomDataType> node_data_type_to_custom_data_type(const eNodeSocketDatatype type)
{
switch (type) {
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 101613acc21..5b7211e44b4 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -28,21 +28,6 @@ bool geo_node_poll_default(struct bNodeType *ntype,
const char **r_disabled_hint);
namespace blender::nodes {
-/**
- * Update the availability of a group of input sockets with the same name,
- * used for switching between attribute inputs or single values.
- *
- * \param mode: Controls which socket of the group to make available.
- * \param name_is_available: If false, make all sockets with this name unavailable.
- */
-void update_attribute_input_socket_availabilities(bNodeTree &ntree,
- bNode &node,
- const StringRef name,
- GeometryNodeAttributeInputMode mode,
- bool name_is_available = true);
-
-Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &component,
- AttributeDomain domain);
void transform_mesh(Mesh &mesh,
const float3 translation,
@@ -93,28 +78,6 @@ void separate_geometry(GeometrySet &geometry_set,
bool invert,
bool &r_is_error);
-struct CurveToPointsResults {
- int result_size;
- MutableSpan<float3> positions;
- MutableSpan<float> radii;
- MutableSpan<float> tilts;
-
- Map<AttributeIDRef, GMutableSpan> point_attributes;
-
- MutableSpan<float3> tangents;
- MutableSpan<float3> normals;
- MutableSpan<float3> rotations;
-};
-/**
- * Create references for all result point cloud attributes to simplify accessing them later on.
- */
-CurveToPointsResults curve_to_points_create_result_attributes(PointCloudComponent &points,
- const CurveEval &curve);
-
-void curve_create_default_rotation_attribute(Span<float3> tangents,
- Span<float3> normals,
- MutableSpan<float3> rotations);
-
std::optional<CustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type);
std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket);
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc
deleted file mode 100644
index eefcfcb2880..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc
+++ /dev/null
@@ -1,228 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_math_rotation.h"
-#include "BLI_task.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_align_rotation_to_vector_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Factor"));
- b.add_input<decl::Float>(N_("Factor"), "Factor_001")
- .default_value(1.0f)
- .min(0.0f)
- .max(1.0f)
- .subtype(PROP_FACTOR);
- b.add_input<decl::String>(N_("Vector"));
- b.add_input<decl::Vector>(N_("Vector"), "Vector_001")
- .default_value({0.0, 0.0, 1.0})
- .subtype(PROP_ANGLE);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "axis", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "pivot_axis", 0, IFACE_("Pivot"), ICON_NONE);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_factor", 0, IFACE_("Factor"), ICON_NONE);
- uiItemR(col, ptr, "input_type_vector", 0, IFACE_("Vector"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometryAlignRotationToVector *node_storage = MEM_cnew<NodeGeometryAlignRotationToVector>(
- __func__);
-
- node_storage->axis = GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_X;
- node_storage->input_type_factor = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node_storage->input_type_vector = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
-
- node->storage = node_storage;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryAlignRotationToVector *node_storage = (NodeGeometryAlignRotationToVector *)
- node->storage;
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Factor", (GeometryNodeAttributeInputMode)node_storage->input_type_factor);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Vector", (GeometryNodeAttributeInputMode)node_storage->input_type_vector);
-}
-
-static void align_rotations_auto_pivot(const VArray<float3> &vectors,
- const VArray<float> &factors,
- const float3 local_main_axis,
- const MutableSpan<float3> rotations)
-{
- threading::parallel_for(IndexRange(vectors.size()), 128, [&](IndexRange range) {
- for (const int i : range) {
- const float3 vector = vectors[i];
- if (is_zero_v3(vector)) {
- continue;
- }
-
- float old_rotation[3][3];
- eul_to_mat3(old_rotation, rotations[i]);
- float3 old_axis;
- mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
-
- const float3 new_axis = math::normalize(vector);
- float3 rotation_axis = math::cross_high_precision(old_axis, new_axis);
- if (is_zero_v3(rotation_axis)) {
- /* The vectors are linearly dependent, so we fall back to another axis. */
- rotation_axis = math::cross_high_precision(old_axis, float3(1, 0, 0));
- if (is_zero_v3(rotation_axis)) {
- /* This is now guaranteed to not be zero. */
- rotation_axis = math::cross_high_precision(old_axis, float3(0, 1, 0));
- }
- }
-
- const float full_angle = angle_normalized_v3v3(old_axis, new_axis);
- const float angle = factors[i] * full_angle;
-
- float rotation[3][3];
- axis_angle_to_mat3(rotation, rotation_axis, angle);
-
- float new_rotation_matrix[3][3];
- mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
-
- float3 new_rotation;
- mat3_to_eul(new_rotation, new_rotation_matrix);
-
- rotations[i] = new_rotation;
- }
- });
-}
-
-static void align_rotations_fixed_pivot(const VArray<float3> &vectors,
- const VArray<float> &factors,
- const float3 local_main_axis,
- const float3 local_pivot_axis,
- const MutableSpan<float3> rotations)
-{
- if (local_main_axis == local_pivot_axis) {
- /* Can't compute any meaningful rotation angle in this case. */
- return;
- }
-
- threading::parallel_for(IndexRange(vectors.size()), 128, [&](IndexRange range) {
- for (const int i : range) {
- const float3 vector = vectors[i];
- if (is_zero_v3(vector)) {
- continue;
- }
-
- float old_rotation[3][3];
- eul_to_mat3(old_rotation, rotations[i]);
- float3 old_axis;
- mul_v3_m3v3(old_axis, old_rotation, local_main_axis);
- float3 pivot_axis;
- mul_v3_m3v3(pivot_axis, old_rotation, local_pivot_axis);
-
- float full_angle = angle_signed_on_axis_v3v3_v3(vector, old_axis, pivot_axis);
- if (full_angle > M_PI) {
- /* Make sure the point is rotated as little as possible. */
- full_angle -= 2.0f * M_PI;
- }
- const float angle = factors[i] * full_angle;
-
- float rotation[3][3];
- axis_angle_to_mat3(rotation, pivot_axis, angle);
-
- float new_rotation_matrix[3][3];
- mul_m3_m3m3(new_rotation_matrix, rotation, old_rotation);
-
- float3 new_rotation;
- mat3_to_eul(new_rotation, new_rotation_matrix);
-
- rotations[i] = new_rotation;
- }
- });
-}
-
-static void align_rotations_on_component(GeometryComponent &component,
- const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- const NodeGeometryAlignRotationToVector &storage = *(const NodeGeometryAlignRotationToVector *)
- node.storage;
-
- OutputAttribute_Typed<float3> rotations = component.attribute_try_get_for_output<float3>(
- "rotation", ATTR_DOMAIN_POINT, {0, 0, 0});
- if (!rotations) {
- return;
- }
-
- VArray<float> factors = params.get_input_attribute<float>(
- "Factor", component, ATTR_DOMAIN_POINT, 1.0f);
- VArray<float3> vectors = params.get_input_attribute<float3>(
- "Vector", component, ATTR_DOMAIN_POINT, {0, 0, 1});
-
- float3 local_main_axis{0, 0, 0};
- local_main_axis[storage.axis] = 1;
- if (storage.pivot_axis == GEO_NODE_ALIGN_ROTATION_TO_VECTOR_PIVOT_AXIS_AUTO) {
- align_rotations_auto_pivot(vectors, factors, local_main_axis, rotations.as_span());
- }
- else {
- float3 local_pivot_axis{0, 0, 0};
- local_pivot_axis[storage.pivot_axis - 1] = 1;
- align_rotations_fixed_pivot(
- vectors, factors, local_main_axis, local_pivot_axis, rotations.as_span());
- }
-
- rotations.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- align_rotations_on_component(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- align_rotations_on_component(geometry_set.get_component_for_write<PointCloudComponent>(),
- params);
- }
- if (geometry_set.has<CurveComponent>()) {
- align_rotations_on_component(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_align_rotation_to_vector_cc
-
-void register_node_type_geo_align_rotation_to_vector()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_align_rotation_to_vector_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype,
- GEO_NODE_LEGACY_ALIGN_ROTATION_TO_VECTOR,
- "Align Rotation to Vector",
- NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(&ntype,
- "NodeGeometryAlignRotationToVector",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc
deleted file mode 100644
index 71cc2332c78..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_clamp_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute"));
- b.add_input<decl::String>(N_("Result"));
- b.add_input<decl::Vector>(N_("Min"));
- b.add_input<decl::Vector>(N_("Max")).default_value({1.0f, 1.0f, 1.0f});
- b.add_input<decl::Float>(N_("Min"), "Min_001");
- b.add_input<decl::Float>(N_("Max"), "Max_001").default_value(1.0f);
- b.add_input<decl::Int>(N_("Min"), "Min_002").min(-100000).max(100000);
- b.add_input<decl::Int>(N_("Max"), "Max_002").default_value(100).min(-100000).max(100000);
- b.add_input<decl::Color>(N_("Min"), "Min_003").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_input<decl::Color>(N_("Max"), "Max_003").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeClamp *data = MEM_cnew<NodeAttributeClamp>(__func__);
- data->data_type = CD_PROP_FLOAT;
- data->operation = NODE_CLAMP_MINMAX;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- bNodeSocket *sock_min_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 3);
- bNodeSocket *sock_max_vector = sock_min_vector->next;
- bNodeSocket *sock_min_float = sock_max_vector->next;
- bNodeSocket *sock_max_float = sock_min_float->next;
- bNodeSocket *sock_min_int = sock_max_float->next;
- bNodeSocket *sock_max_int = sock_min_int->next;
- bNodeSocket *sock_min_color = sock_max_int->next;
- bNodeSocket *sock_max_color = sock_min_color->next;
-
- const NodeAttributeClamp &storage = *(const NodeAttributeClamp *)node->storage;
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- nodeSetSocketAvailability(ntree, sock_min_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_max_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_min_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_max_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_min_int, data_type == CD_PROP_INT32);
- nodeSetSocketAvailability(ntree, sock_max_int, data_type == CD_PROP_INT32);
- nodeSetSocketAvailability(ntree, sock_min_color, data_type == CD_PROP_COLOR);
- nodeSetSocketAvailability(ntree, sock_max_color, data_type == CD_PROP_COLOR);
-}
-
-template<typename T> T clamp_value(const T val, const T min, const T max);
-
-template<> inline float clamp_value(const float val, const float min, const float max)
-{
- return std::min(std::max(val, min), max);
-}
-
-template<> inline int clamp_value(const int val, const int min, const int max)
-{
- return std::min(std::max(val, min), max);
-}
-
-template<> inline float3 clamp_value(const float3 val, const float3 min, const float3 max)
-{
- float3 tmp;
- tmp.x = std::min(std::max(val.x, min.x), max.x);
- tmp.y = std::min(std::max(val.y, min.y), max.y);
- tmp.z = std::min(std::max(val.z, min.z), max.z);
- return tmp;
-}
-
-template<>
-inline ColorGeometry4f clamp_value(const ColorGeometry4f val,
- const ColorGeometry4f min,
- const ColorGeometry4f max)
-{
- ColorGeometry4f tmp;
- tmp.r = std::min(std::max(val.r, min.r), max.r);
- tmp.g = std::min(std::max(val.g, min.g), max.g);
- tmp.b = std::min(std::max(val.b, min.b), max.b);
- tmp.a = std::min(std::max(val.a, min.a), max.a);
- return tmp;
-}
-
-template<typename T>
-static void clamp_attribute(const VArray<T> &inputs,
- const MutableSpan<T> outputs,
- const T min,
- const T max)
-{
- for (const int i : IndexRange(outputs.size())) {
- outputs[i] = clamp_value<T>(inputs[i], min, max);
- }
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- StringRef source_name,
- StringRef result_name)
-{
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
- std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name);
- if (source_info) {
- return source_info->domain;
- }
- return ATTR_DOMAIN_POINT;
-}
-
-static void clamp_attribute(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const std::string attribute_name = params.get_input<std::string>("Attribute");
- const std::string result_name = params.get_input<std::string>("Result");
-
- if (attribute_name.empty() || result_name.empty()) {
- return;
- }
-
- if (!component.attribute_exists(attribute_name)) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("No attribute with name \"") + attribute_name + "\"");
- return;
- }
-
- const NodeAttributeClamp &storage = *(const NodeAttributeClamp *)params.node().storage;
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- const AttributeDomain domain = get_result_domain(component, attribute_name, result_name);
- const int operation = static_cast<int>(storage.operation);
-
- GVArray attribute_input = component.attribute_try_get_for_read(
- attribute_name, domain, data_type);
-
- OutputAttribute attribute_result = component.attribute_try_get_for_output_only(
- result_name, domain, data_type);
-
- if (!attribute_result) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("Could not find or create attribute with name \"") +
- result_name + "\"");
- return;
- }
-
- switch (data_type) {
- case CD_PROP_FLOAT3: {
- float3 min = params.get_input<float3>("Min");
- float3 max = params.get_input<float3>("Max");
- if (operation == NODE_CLAMP_RANGE) {
- if (min.x > max.x) {
- std::swap(min.x, max.x);
- }
- if (min.y > max.y) {
- std::swap(min.y, max.y);
- }
- if (min.z > max.z) {
- std::swap(min.z, max.z);
- }
- }
- MutableSpan<float3> results = attribute_result.as_span<float3>();
- clamp_attribute<float3>(attribute_input.typed<float3>(), results, min, max);
- break;
- }
- case CD_PROP_FLOAT: {
- const float min = params.get_input<float>("Min_001");
- const float max = params.get_input<float>("Max_001");
- MutableSpan<float> results = attribute_result.as_span<float>();
- if (operation == NODE_CLAMP_RANGE && min > max) {
- clamp_attribute<float>(attribute_input.typed<float>(), results, max, min);
- }
- else {
- clamp_attribute<float>(attribute_input.typed<float>(), results, min, max);
- }
- break;
- }
- case CD_PROP_INT32: {
- const int min = params.get_input<int>("Min_002");
- const int max = params.get_input<int>("Max_002");
- MutableSpan<int> results = attribute_result.as_span<int>();
- if (operation == NODE_CLAMP_RANGE && min > max) {
- clamp_attribute<int>(attribute_input.typed<int>(), results, max, min);
- }
- else {
- clamp_attribute<int>(attribute_input.typed<int>(), results, min, max);
- }
- break;
- }
- case CD_PROP_COLOR: {
- ColorGeometry4f min = params.get_input<ColorGeometry4f>("Min_003");
- ColorGeometry4f max = params.get_input<ColorGeometry4f>("Max_003");
- if (operation == NODE_CLAMP_RANGE) {
- if (min.r > max.r) {
- std::swap(min.r, max.r);
- }
- if (min.g > max.g) {
- std::swap(min.g, max.g);
- }
- if (min.b > max.b) {
- std::swap(min.b, max.b);
- }
- if (min.a > max.a) {
- std::swap(min.a, max.a);
- }
- }
- MutableSpan<ColorGeometry4f> results = attribute_result.as_span<ColorGeometry4f>();
- clamp_attribute<ColorGeometry4f>(
- attribute_input.typed<ColorGeometry4f>(), results, min, max);
- break;
- }
- default: {
- BLI_assert(false);
- break;
- }
- }
-
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- clamp_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- clamp_attribute(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- clamp_attribute(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_clamp_cc
-
-void register_node_type_geo_attribute_clamp()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_clamp_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_CLAMP, "Attribute Clamp", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_storage(
- &ntype, "NodeAttributeClamp", node_free_standard_storage, node_copy_standard_storage);
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc
deleted file mode 100644
index 5a5cadaea12..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-
-#include "BKE_colorband.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_color_ramp_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute"));
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiTemplateColorRamp(layout, ptr, "color_ramp", false);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeAttributeColorRamp *node_storage = MEM_cnew<NodeAttributeColorRamp>(__func__);
- BKE_colorband_init(&node_storage->color_ramp, true);
- node->storage = node_storage;
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- StringRef input_name,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the input attribute's domain if it exists. */
- std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(input_name);
- if (source_info) {
- return source_info->domain;
- }
-
- return ATTR_DOMAIN_POINT;
-}
-
-static void execute_on_component(const GeoNodeExecParams &params, GeometryComponent &component)
-{
- const bNode &bnode = params.node();
- NodeAttributeColorRamp *node_storage = (NodeAttributeColorRamp *)bnode.storage;
- const std::string result_name = params.get_input<std::string>("Result");
- const std::string input_name = params.get_input<std::string>("Attribute");
-
- /* Always output a color attribute for now. We might want to allow users to customize.
- * Using the type of an existing attribute could work, but does not have a real benefit
- * currently. */
- const AttributeDomain result_domain = get_result_domain(component, input_name, result_name);
-
- OutputAttribute_Typed<ColorGeometry4f> attribute_result =
- component.attribute_try_get_for_output_only<ColorGeometry4f>(result_name, result_domain);
- if (!attribute_result) {
- return;
- }
-
- VArray<float> attribute_in = component.attribute_get_for_read<float>(
- input_name, result_domain, 0.0f);
-
- MutableSpan<ColorGeometry4f> results = attribute_result.as_span();
-
- ColorBand *color_ramp = &node_storage->color_ramp;
- threading::parallel_for(IndexRange(attribute_in.size()), 512, [&](IndexRange range) {
- for (const int i : range) {
- BKE_colorband_evaluate(color_ramp, attribute_in[i], results[i]);
- }
- });
-
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
- }
- if (geometry_set.has<PointCloudComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<PointCloudComponent>());
- }
- if (geometry_set.has<CurveComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<CurveComponent>());
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_color_ramp_cc
-
-void register_node_type_geo_attribute_color_ramp()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_color_ramp_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP, "Attribute Color Ramp", NODE_CLASS_ATTRIBUTE);
- node_type_storage(
- &ntype, "NodeAttributeColorRamp", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc
deleted file mode 100644
index ec6c65aa8bc..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_combine_xyz_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("X"));
- b.add_input<decl::Float>(N_("X"), "X_001");
- b.add_input<decl::String>(N_("Y"));
- b.add_input<decl::Float>(N_("Y"), "Y_001");
- b.add_input<decl::String>(N_("Z"));
- b.add_input<decl::Float>(N_("Z"), "Z_001");
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_x", 0, IFACE_("X"), ICON_NONE);
- uiItemR(col, ptr, "input_type_y", 0, IFACE_("Y"), ICON_NONE);
- uiItemR(col, ptr, "input_type_z", 0, IFACE_("Z"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeCombineXYZ *data = MEM_cnew<NodeAttributeCombineXYZ>(__func__);
-
- data->input_type_x = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- data->input_type_y = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- data->input_type_z = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeAttributeCombineXYZ *node_storage = (NodeAttributeCombineXYZ *)node->storage;
- update_attribute_input_socket_availabilities(
- *ntree, *node, "X", (GeometryNodeAttributeInputMode)node_storage->input_type_x);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Y", (GeometryNodeAttributeInputMode)node_storage->input_type_y);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Z", (GeometryNodeAttributeInputMode)node_storage->input_type_z);
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the highest priority domain from existing input attributes, or the default. */
- return params.get_highest_priority_input_domain({"X", "Y", "Z"}, component, ATTR_DOMAIN_POINT);
-}
-
-static void combine_attributes(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const std::string result_name = params.get_input<std::string>("Result");
- if (result_name.empty()) {
- return;
- }
- const AttributeDomain result_domain = get_result_domain(component, params, result_name);
-
- OutputAttribute_Typed<float3> attribute_result =
- component.attribute_try_get_for_output_only<float3>(result_name, result_domain);
- if (!attribute_result) {
- return;
- }
- VArray<float> attribute_x = params.get_input_attribute<float>(
- "X", component, result_domain, 0.0f);
- VArray<float> attribute_y = params.get_input_attribute<float>(
- "Y", component, result_domain, 0.0f);
- VArray<float> attribute_z = params.get_input_attribute<float>(
- "Z", component, result_domain, 0.0f);
-
- for (const int i : IndexRange(attribute_result->size())) {
- const float x = attribute_x[i];
- const float y = attribute_y[i];
- const float z = attribute_z[i];
- attribute_result->set(i, {x, y, z});
- }
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- combine_attributes(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- combine_attributes(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- combine_attributes(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_combine_xyz_cc
-
-void register_node_type_geo_attribute_combine_xyz()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_combine_xyz_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype,
- GEO_NODE_LEGACY_ATTRIBUTE_COMBINE_XYZ,
- "Attribute Combine XYZ",
- NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeAttributeCombineXYZ", node_free_standard_storage, node_copy_standard_storage);
-
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc
deleted file mode 100644
index 2136a07e58e..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc
+++ /dev/null
@@ -1,345 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "NOD_math_functions.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_compare_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("A"));
- b.add_input<decl::Float>(N_("A"), "A_001");
- b.add_input<decl::Vector>(N_("A"), "A_002");
- b.add_input<decl::Color>(N_("A"), "A_003").default_value({0.5, 0.5, 0.5, 1.0});
- b.add_input<decl::String>(N_("B"));
- b.add_input<decl::Float>(N_("B"), "B_001");
- b.add_input<decl::Vector>(N_("B"), "B_002");
- b.add_input<decl::Color>(N_("B"), "B_003").default_value({0.5, 0.5, 0.5, 1.0});
- b.add_input<decl::Float>(N_("Threshold")).default_value(0.01f).min(0.0f);
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "input_type_a", 0, IFACE_("A"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeCompare *data = MEM_cnew<NodeAttributeCompare>(__func__);
- data->operation = NODE_COMPARE_GREATER_THAN;
- data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node->storage = data;
-}
-
-static bool operation_tests_equality(const NodeAttributeCompare &node_storage)
-{
- return ELEM(node_storage.operation, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL);
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeAttributeCompare *node_storage = (NodeAttributeCompare *)node->storage;
- update_attribute_input_socket_availabilities(
- *ntree, *node, "A", (GeometryNodeAttributeInputMode)node_storage->input_type_a);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "B", (GeometryNodeAttributeInputMode)node_storage->input_type_b);
-
- bNodeSocket *socket_threshold = (bNodeSocket *)BLI_findlink(&node->inputs, 9);
- nodeSetSocketAvailability(ntree, socket_threshold, operation_tests_equality(*node_storage));
-}
-
-static void do_math_operation(const VArray<float> &input_a,
- const VArray<float> &input_b,
- const NodeCompareOperation operation,
- MutableSpan<bool> span_result)
-{
- const int size = input_a.size();
-
- if (try_dispatch_float_math_fl_fl_to_bool(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- for (const int i : IndexRange(size)) {
- const float a = input_a[i];
- const float b = input_b[i];
- const bool out = math_function(a, b);
- span_result[i] = out;
- }
- })) {
- return;
- }
-
- /* The operation is not supported by this node currently. */
- BLI_assert(false);
-}
-
-static void do_equal_operation_float(const VArray<float> &input_a,
- const VArray<float> &input_b,
- const float threshold,
- MutableSpan<bool> span_result)
-{
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const float a = input_a[i];
- const float b = input_b[i];
- span_result[i] = compare_ff(a, b, threshold);
- }
-}
-
-static void do_equal_operation_float3(const VArray<float3> &input_a,
- const VArray<float3> &input_b,
- const float threshold,
- MutableSpan<bool> span_result)
-{
- const float threshold_squared = pow2f(threshold);
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const float3 a = input_a[i];
- const float3 b = input_b[i];
- span_result[i] = len_squared_v3v3(a, b) < threshold_squared;
- }
-}
-
-static void do_equal_operation_color4f(const VArray<ColorGeometry4f> &input_a,
- const VArray<ColorGeometry4f> &input_b,
- const float threshold,
- MutableSpan<bool> span_result)
-{
- const float threshold_squared = pow2f(threshold);
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const ColorGeometry4f a = input_a[i];
- const ColorGeometry4f b = input_b[i];
- span_result[i] = len_squared_v4v4(a, b) < threshold_squared;
- }
-}
-
-static void do_equal_operation_bool(const VArray<bool> &input_a,
- const VArray<bool> &input_b,
- const float UNUSED(threshold),
- MutableSpan<bool> span_result)
-{
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const bool a = input_a[i];
- const bool b = input_b[i];
- span_result[i] = a == b;
- }
-}
-
-static void do_not_equal_operation_float(const VArray<float> &input_a,
- const VArray<float> &input_b,
- const float threshold,
- MutableSpan<bool> span_result)
-{
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const float a = input_a[i];
- const float b = input_b[i];
- span_result[i] = !compare_ff(a, b, threshold);
- }
-}
-
-static void do_not_equal_operation_float3(const VArray<float3> &input_a,
- const VArray<float3> &input_b,
- const float threshold,
- MutableSpan<bool> span_result)
-{
- const float threshold_squared = pow2f(threshold);
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const float3 a = input_a[i];
- const float3 b = input_b[i];
- span_result[i] = len_squared_v3v3(a, b) >= threshold_squared;
- }
-}
-
-static void do_not_equal_operation_color4f(const VArray<ColorGeometry4f> &input_a,
- const VArray<ColorGeometry4f> &input_b,
- const float threshold,
- MutableSpan<bool> span_result)
-{
- const float threshold_squared = pow2f(threshold);
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const ColorGeometry4f a = input_a[i];
- const ColorGeometry4f b = input_b[i];
- span_result[i] = len_squared_v4v4(a, b) >= threshold_squared;
- }
-}
-
-static void do_not_equal_operation_bool(const VArray<bool> &input_a,
- const VArray<bool> &input_b,
- const float UNUSED(threshold),
- MutableSpan<bool> span_result)
-{
- const int size = input_a.size();
- for (const int i : IndexRange(size)) {
- const bool a = input_a[i];
- const bool b = input_b[i];
- span_result[i] = a != b;
- }
-}
-
-static CustomDataType get_data_type(GeometryComponent &component,
- const GeoNodeExecParams &params,
- const NodeAttributeCompare &node_storage)
-{
- if (operation_tests_equality(node_storage)) {
- /* Convert the input attributes to the same data type for the equality tests. Use the higher
- * complexity attribute type, otherwise information necessary to the comparison may be lost. */
- return bke::attribute_data_type_highest_complexity({
- params.get_input_attribute_data_type("A", component, CD_PROP_FLOAT),
- params.get_input_attribute_data_type("B", component, CD_PROP_FLOAT),
- });
- }
-
- /* Use float compare for every operation besides equality. */
- return CD_PROP_FLOAT;
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the highest priority domain from existing input attributes, or the default. */
- return params.get_highest_priority_input_domain({"A", "B"}, component, ATTR_DOMAIN_POINT);
-}
-
-static void attribute_compare_calc(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- NodeAttributeCompare *node_storage = (NodeAttributeCompare *)node.storage;
- const NodeCompareOperation operation = static_cast<NodeCompareOperation>(
- node_storage->operation);
- const std::string result_name = params.get_input<std::string>("Result");
-
- const AttributeDomain result_domain = get_result_domain(component, params, result_name);
-
- OutputAttribute_Typed<bool> attribute_result = component.attribute_try_get_for_output_only<bool>(
- result_name, result_domain);
- if (!attribute_result) {
- return;
- }
-
- const CustomDataType input_data_type = get_data_type(component, params, *node_storage);
-
- GVArray attribute_a = params.get_input_attribute(
- "A", component, result_domain, input_data_type, nullptr);
- GVArray attribute_b = params.get_input_attribute(
- "B", component, result_domain, input_data_type, nullptr);
-
- if (!attribute_a || !attribute_b) {
- /* Attribute wasn't found. */
- return;
- }
-
- MutableSpan<bool> result_span = attribute_result.as_span();
-
- /* Use specific types for correct equality operations, but for other operations we use implicit
- * conversions and float comparison. In other words, the comparison is not element-wise. */
- if (operation_tests_equality(*node_storage)) {
- const float threshold = params.get_input<float>("Threshold");
- if (operation == NODE_COMPARE_EQUAL) {
- if (input_data_type == CD_PROP_FLOAT) {
- do_equal_operation_float(
- attribute_a.typed<float>(), attribute_b.typed<float>(), threshold, result_span);
- }
- else if (input_data_type == CD_PROP_FLOAT3) {
- do_equal_operation_float3(
- attribute_a.typed<float3>(), attribute_b.typed<float3>(), threshold, result_span);
- }
- else if (input_data_type == CD_PROP_COLOR) {
- do_equal_operation_color4f(attribute_a.typed<ColorGeometry4f>(),
- attribute_b.typed<ColorGeometry4f>(),
- threshold,
- result_span);
- }
- else if (input_data_type == CD_PROP_BOOL) {
- do_equal_operation_bool(
- attribute_a.typed<bool>(), attribute_b.typed<bool>(), threshold, result_span);
- }
- }
- else if (operation == NODE_COMPARE_NOT_EQUAL) {
- if (input_data_type == CD_PROP_FLOAT) {
- do_not_equal_operation_float(
- attribute_a.typed<float>(), attribute_b.typed<float>(), threshold, result_span);
- }
- else if (input_data_type == CD_PROP_FLOAT3) {
- do_not_equal_operation_float3(
- attribute_a.typed<float3>(), attribute_b.typed<float3>(), threshold, result_span);
- }
- else if (input_data_type == CD_PROP_COLOR) {
- do_not_equal_operation_color4f(attribute_a.typed<ColorGeometry4f>(),
- attribute_b.typed<ColorGeometry4f>(),
- threshold,
- result_span);
- }
- else if (input_data_type == CD_PROP_BOOL) {
- do_not_equal_operation_bool(
- attribute_a.typed<bool>(), attribute_b.typed<bool>(), threshold, result_span);
- }
- }
- }
- else {
- do_math_operation(
- attribute_a.typed<float>(), attribute_b.typed<float>(), operation, result_span);
- }
-
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- attribute_compare_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- attribute_compare_calc(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- attribute_compare_calc(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_compare_cc
-
-void register_node_type_geo_attribute_compare()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_compare_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_COMPARE, "Attribute Compare", NODE_CLASS_ATTRIBUTE);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeAttributeCompare", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc
deleted file mode 100644
index 5ded4efd4f7..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_convert_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute"));
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "domain", 0, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "data_type", 0, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeConvert *data = MEM_cnew<NodeAttributeConvert>(__func__);
-
- data->data_type = CD_AUTO_FROM_NAME;
- data->domain = ATTR_DOMAIN_AUTO;
- node->storage = data;
-}
-
-static AttributeMetaData get_result_domain_and_type(const GeometryComponent &component,
- const StringRef source_name,
- const StringRef result_name)
-{
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return *result_info;
- }
- std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name);
- if (source_info) {
- return *source_info;
- }
- /* The node won't do anything in this case, but we still have to return a value. */
- return AttributeMetaData{ATTR_DOMAIN_POINT, CD_PROP_BOOL};
-}
-
-static bool conversion_can_be_skipped(const GeometryComponent &component,
- const StringRef source_name,
- const StringRef result_name,
- const AttributeDomain result_domain,
- const CustomDataType result_type)
-{
- if (source_name != result_name) {
- return false;
- }
- std::optional<AttributeMetaData> info = component.attribute_get_meta_data(result_name);
- if (!info) {
- return false;
- }
- if (info->domain != result_domain) {
- return false;
- }
- if (info->data_type != result_type) {
- return false;
- }
- return true;
-}
-
-static void attribute_convert_calc(GeometryComponent &component,
- const GeoNodeExecParams &params,
- const StringRef source_name,
- const StringRef result_name,
- const CustomDataType data_type,
- const AttributeDomain domain)
-{
- const AttributeMetaData auto_info = get_result_domain_and_type(
- component, source_name, result_name);
- const AttributeDomain result_domain = (domain == ATTR_DOMAIN_AUTO) ? auto_info.domain : domain;
- const CustomDataType result_type = (data_type == CD_AUTO_FROM_NAME) ? auto_info.data_type :
- data_type;
-
- if (conversion_can_be_skipped(component, source_name, result_name, result_domain, result_type)) {
- return;
- }
-
- GVArray source_attribute = component.attribute_try_get_for_read(
- source_name, result_domain, result_type);
- if (!source_attribute) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("No attribute with name \"") + source_name + "\"");
- return;
- }
-
- OutputAttribute result_attribute = component.attribute_try_get_for_output_only(
- result_name, result_domain, result_type);
- if (!result_attribute) {
- return;
- }
-
- GVArray_GSpan source_span{source_attribute};
- GMutableSpan result_span = result_attribute.as_span();
-
- BLI_assert(source_span.size() == result_span.size());
-
- const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(result_type);
- BLI_assert(cpp_type != nullptr);
-
- cpp_type->copy_assign_n(source_span.data(), result_span.data(), result_span.size());
- result_attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- const std::string result_name = params.extract_input<std::string>("Result");
- const std::string source_name = params.extract_input<std::string>("Attribute");
- const NodeAttributeConvert &node_storage = *(const NodeAttributeConvert *)params.node().storage;
- const CustomDataType data_type = static_cast<CustomDataType>(node_storage.data_type);
- const AttributeDomain domain = static_cast<AttributeDomain>(node_storage.domain);
-
- if (result_name.empty()) {
- params.set_default_remaining_outputs();
- return;
- }
-
- if (geometry_set.has<MeshComponent>()) {
- attribute_convert_calc(geometry_set.get_component_for_write<MeshComponent>(),
- params,
- source_name,
- result_name,
- data_type,
- domain);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- attribute_convert_calc(geometry_set.get_component_for_write<PointCloudComponent>(),
- params,
- source_name,
- result_name,
- data_type,
- domain);
- }
- if (geometry_set.has<CurveComponent>()) {
- attribute_convert_calc(geometry_set.get_component_for_write<CurveComponent>(),
- params,
- source_name,
- result_name,
- data_type,
- domain);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_convert_cc
-
-void register_node_type_geo_attribute_convert()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_convert_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_CONVERT, "Attribute Convert", NODE_CLASS_ATTRIBUTE);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(
- &ntype, "NodeAttributeConvert", node_free_standard_storage, node_copy_standard_storage);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc
deleted file mode 100644
index 800587e2157..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_blenlib.h"
-#include "BLI_task.hh"
-
-#include "BKE_colortools.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_curve_map_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute"));
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
- bNode *node = (bNode *)ptr->data;
- NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
- switch (data->data_type) {
- case CD_PROP_FLOAT:
- uiTemplateCurveMapping(layout, ptr, "curve_vec", 0, false, false, false, false);
- break;
- case CD_PROP_FLOAT3:
- uiTemplateCurveMapping(layout, ptr, "curve_vec", 'v', false, false, false, false);
- break;
- case CD_PROP_COLOR:
- uiTemplateCurveMapping(layout, ptr, "curve_rgb", 'c', false, false, false, false);
- break;
- }
-}
-
-static void node_free_storage(bNode *node)
-{
- if (node->storage) {
- NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
- BKE_curvemapping_free(data->curve_vec);
- BKE_curvemapping_free(data->curve_rgb);
- MEM_freeN(node->storage);
- }
-}
-
-static void node_copy_storage(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
-{
- dest_node->storage = MEM_dupallocN(src_node->storage);
- NodeAttributeCurveMap *src_data = (NodeAttributeCurveMap *)src_node->storage;
- NodeAttributeCurveMap *dest_data = (NodeAttributeCurveMap *)dest_node->storage;
- dest_data->curve_vec = BKE_curvemapping_copy(src_data->curve_vec);
- dest_data->curve_rgb = BKE_curvemapping_copy(src_data->curve_rgb);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeAttributeCurveMap *data = MEM_cnew<NodeAttributeCurveMap>(__func__);
-
- data->data_type = CD_PROP_FLOAT;
- data->curve_vec = BKE_curvemapping_add(4, -1.0f, -1.0f, 1.0f, 1.0f);
- data->curve_vec->cur = 3;
- data->curve_rgb = BKE_curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f);
- node->storage = data;
-}
-
-static void node_update(bNodeTree *UNUSED(ntree), bNode *node)
-{
- /* Set the active curve when data type is changed. */
- NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
- if (data->data_type == CD_PROP_FLOAT) {
- data->curve_vec->cur = 3;
- }
- else if (data->data_type == CD_PROP_FLOAT3) {
- data->curve_vec->cur = 0;
- }
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- StringRef input_name,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
- /* Otherwise use the input attribute's domain if it exists. */
- std::optional<AttributeMetaData> input_info = component.attribute_get_meta_data(input_name);
- if (input_info) {
- return input_info->domain;
- }
-
- return ATTR_DOMAIN_POINT;
-}
-
-static void execute_on_component(const GeoNodeExecParams &params, GeometryComponent &component)
-{
- const bNode &bnode = params.node();
- NodeAttributeCurveMap &node_storage = *(NodeAttributeCurveMap *)bnode.storage;
- const std::string result_name = params.get_input<std::string>("Result");
- const std::string input_name = params.get_input<std::string>("Attribute");
-
- const CustomDataType result_type = (CustomDataType)node_storage.data_type;
- const AttributeDomain result_domain = get_result_domain(component, input_name, result_name);
-
- OutputAttribute attribute_result = component.attribute_try_get_for_output_only(
- result_name, result_domain, result_type);
- if (!attribute_result) {
- return;
- }
-
- switch (result_type) {
- case CD_PROP_FLOAT: {
- const CurveMapping *cumap = (CurveMapping *)node_storage.curve_vec;
- VArray<float> attribute_in = component.attribute_get_for_read<float>(
- input_name, result_domain, float(0.0f));
- MutableSpan<float> results = attribute_result.as_span<float>();
- threading::parallel_for(attribute_in.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = BKE_curvemapping_evaluateF(cumap, 3, attribute_in[i]);
- }
- });
- break;
- }
- case CD_PROP_FLOAT3: {
- const CurveMapping *cumap = (CurveMapping *)node_storage.curve_vec;
- VArray<float3> attribute_in = component.attribute_get_for_read<float3>(
- input_name, result_domain, float3(0.0f));
- MutableSpan<float3> results = attribute_result.as_span<float3>();
- threading::parallel_for(attribute_in.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- BKE_curvemapping_evaluate3F(cumap, results[i], attribute_in[i]);
- }
- });
- break;
- }
- case CD_PROP_COLOR: {
- const CurveMapping *cumap = (CurveMapping *)node_storage.curve_rgb;
- VArray<ColorGeometry4f> attribute_in = component.attribute_get_for_read<ColorGeometry4f>(
- input_name, result_domain, ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f));
- MutableSpan<ColorGeometry4f> results = attribute_result.as_span<ColorGeometry4f>();
- threading::parallel_for(attribute_in.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- BKE_curvemapping_evaluateRGBF(cumap, results[i], attribute_in[i]);
- }
- });
- break;
- }
- default: {
- BLI_assert_unreachable();
- break;
- }
- }
-
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- const bNode &bnode = params.node();
- NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)bnode.storage;
- BKE_curvemapping_init(data->curve_vec);
- BKE_curvemapping_init(data->curve_rgb);
-
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
- }
- if (geometry_set.has<PointCloudComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<PointCloudComponent>());
- }
- if (geometry_set.has<CurveComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<CurveComponent>());
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_curve_map_cc
-
-void register_node_type_geo_attribute_curve_map()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_curve_map_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_CURVE_MAP, "Attribute Curve Map", NODE_CLASS_ATTRIBUTE);
- node_type_update(&ntype, file_ns::node_update);
- node_type_init(&ntype, file_ns::node_init);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_storage(
- &ntype, "NodeAttributeCurveMap", file_ns::node_free_storage, file_ns::node_copy_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc
deleted file mode 100644
index 21fe8e12e65..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_fill_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute")).is_attribute_name();
- b.add_input<decl::Vector>(N_("Value"), "Value");
- b.add_input<decl::Float>(N_("Value"), "Value_001");
- b.add_input<decl::Color>(N_("Value"), "Value_002");
- b.add_input<decl::Bool>(N_("Value"), "Value_003");
- b.add_input<decl::Int>(N_("Value"), "Value_004");
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- node->custom1 = CD_PROP_FLOAT;
- node->custom2 = ATTR_DOMAIN_AUTO;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- bNodeSocket *socket_value_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
- bNodeSocket *socket_value_float = socket_value_vector->next;
- bNodeSocket *socket_value_color4f = socket_value_float->next;
- bNodeSocket *socket_value_boolean = socket_value_color4f->next;
- bNodeSocket *socket_value_int32 = socket_value_boolean->next;
-
- const CustomDataType data_type = static_cast<CustomDataType>(node->custom1);
-
- nodeSetSocketAvailability(ntree, socket_value_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, socket_value_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, socket_value_color4f, data_type == CD_PROP_COLOR);
- nodeSetSocketAvailability(ntree, socket_value_boolean, data_type == CD_PROP_BOOL);
- nodeSetSocketAvailability(ntree, socket_value_int32, data_type == CD_PROP_INT32);
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component, const StringRef name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(name);
- if (result_info) {
- return result_info->domain;
- }
- return ATTR_DOMAIN_POINT;
-}
-
-static void fill_attribute(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const std::string attribute_name = params.get_input<std::string>("Attribute");
- if (attribute_name.empty()) {
- return;
- }
-
- const bNode &node = params.node();
- const CustomDataType data_type = static_cast<CustomDataType>(node.custom1);
- const AttributeDomain domain = static_cast<AttributeDomain>(node.custom2);
- const AttributeDomain result_domain = (domain == ATTR_DOMAIN_AUTO) ?
- get_result_domain(component, attribute_name) :
- domain;
-
- OutputAttribute attribute = component.attribute_try_get_for_output_only(
- attribute_name, result_domain, data_type);
- if (!attribute) {
- return;
- }
-
- switch (data_type) {
- case CD_PROP_FLOAT: {
- const float value = params.get_input<float>("Value_001");
- attribute->fill(&value);
- break;
- }
- case CD_PROP_FLOAT3: {
- const float3 value = params.get_input<float3>("Value");
- attribute->fill(&value);
- break;
- }
- case CD_PROP_COLOR: {
- const ColorGeometry4f value = params.get_input<ColorGeometry4f>("Value_002");
- attribute->fill(&value);
- break;
- }
- case CD_PROP_BOOL: {
- const bool value = params.get_input<bool>("Value_003");
- attribute->fill(&value);
- break;
- }
- case CD_PROP_INT32: {
- const int value = params.get_input<int>("Value_004");
- attribute->fill(&value);
- break;
- }
- default:
- break;
- }
-
- attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- fill_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- fill_attribute(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- fill_attribute(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_fill_cc
-
-void register_node_type_geo_attribute_fill()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_fill_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_FILL, "Attribute Fill", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- ntype.declare = file_ns::node_declare;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc
deleted file mode 100644
index 05440b09442..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_math_base_safe.h"
-#include "BLI_task.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_map_range_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute"));
- b.add_input<decl::String>(N_("Result"));
- b.add_input<decl::Float>(N_("From Min"));
- b.add_input<decl::Float>(N_("From Max")).default_value(1.0f);
- b.add_input<decl::Float>(N_("To Min"));
- b.add_input<decl::Float>(N_("To Max")).default_value(1.0f);
- b.add_input<decl::Float>(N_("Steps")).default_value(4.0f);
- b.add_input<decl::Vector>(N_("From Min"), "From Min_001");
- b.add_input<decl::Vector>(N_("From Max"), "From Max_001").default_value({1.0f, 1.0f, 1.0f});
- b.add_input<decl::Vector>(N_("To Min"), "To Min_001");
- b.add_input<decl::Vector>(N_("To Max"), "To Max_001").default_value({1.0f, 1.0f, 1.0f});
- b.add_input<decl::Vector>(N_("Steps"), "Steps_001").default_value({4.0f, 4.0f, 4.0f});
- b.add_input<decl::Bool>(N_("Clamp"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void fn_attribute_map_range_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "interpolation_type", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeAttributeMapRange *data = MEM_cnew<NodeAttributeMapRange>(__func__);
- data->data_type = CD_PROP_FLOAT;
- data->interpolation_type = NODE_MAP_RANGE_LINEAR;
-
- node->storage = data;
-}
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeAttributeMapRange &node_storage = *(NodeAttributeMapRange *)node->storage;
-
- bNodeSocket *sock_from_min_float = (bNodeSocket *)BLI_findlink(&node->inputs, 3);
- bNodeSocket *sock_from_max_float = sock_from_min_float->next;
- bNodeSocket *sock_to_min_float = sock_from_max_float->next;
- bNodeSocket *sock_to_max_float = sock_to_min_float->next;
- bNodeSocket *sock_steps_float = sock_to_max_float->next;
-
- bNodeSocket *sock_from_min_vector = sock_steps_float->next;
- bNodeSocket *sock_from_max_vector = sock_from_min_vector->next;
- bNodeSocket *sock_to_min_vector = sock_from_max_vector->next;
- bNodeSocket *sock_to_max_vector = sock_to_min_vector->next;
- bNodeSocket *sock_steps_vector = sock_to_max_vector->next;
-
- bNodeSocket *sock_clamp = sock_steps_vector->next;
-
- const CustomDataType data_type = static_cast<CustomDataType>(node_storage.data_type);
-
- nodeSetSocketAvailability(ntree,
- sock_clamp,
- node_storage.interpolation_type == NODE_MAP_RANGE_LINEAR ||
- node_storage.interpolation_type == NODE_MAP_RANGE_STEPPED);
-
- nodeSetSocketAvailability(ntree, sock_from_min_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_from_max_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_to_min_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_to_max_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree,
- sock_steps_float,
- data_type == CD_PROP_FLOAT &&
- node_storage.interpolation_type == NODE_MAP_RANGE_STEPPED);
-
- nodeSetSocketAvailability(ntree, sock_from_min_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_from_max_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_to_min_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_to_max_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree,
- sock_steps_vector,
- data_type == CD_PROP_FLOAT3 &&
- node_storage.interpolation_type == NODE_MAP_RANGE_STEPPED);
-}
-
-static float map_linear(const float value,
- const float min_from,
- const float max_from,
- const float min_to,
- const float max_to)
-{
- /* First we calculate a fraction that measures how far along
- * the [min_from, max_from] interval the value lies.
- *
- * value
- * min_from [------>|------------------------] max_from
- * factor (e.g. 0.25)
- *
- * Then to find where the value is mapped, we add the same fraction
- * of the [min_to, max_to] interval to min_to.
- *
- * min_to [--->|-----------] max_to
- * v
- * min_to + (max_to - min_to) * factor
- */
- const float factor = safe_divide(value - min_from, max_from - min_from);
- return min_to + factor * (max_to - min_to);
-}
-
-static float map_stepped(const float value,
- const float min_from,
- const float max_from,
- const float min_to,
- const float max_to,
- const float steps)
-{
- /* First the factor is calculated here in the same way as for the linear mapping.
- *
- * Then the factor is mapped to multiples of 1.0 / steps.
- * This is best understood with a few examples. Assume steps == 3.
- * ____________________________________
- * | factor | * 4.0 | floor() | / 3.0 |
- * |--------|-------|---------|-------|
- * | 0.0 | 0.0 | 0.0 | 0.0 |
- * | 0.1 | 0.4 | 0.0 | 0.0 |
- * | 0.25 | 1.0 | 1.0 | 0.333 |
- * | 0.45 | 1.8 | 1.0 | 0.333 |
- * | 0.5 | 2.0 | 2.0 | 0.666 |
- * | 0.55 | 2.2 | 2.0 | 0.666 |
- * | 0.999 | 3.999 | 3.0 | 1.0 |
- * | 1.0 | 4.0 | 4.0 | 1.333 |
- * ------------------------------------
- * Note that the factor is not always mapped the closest multiple of 1.0 /steps.
- */
- const float factor = safe_divide(value - min_from, max_from - min_from);
- const float factor_mapped = safe_divide(floorf(factor * (steps + 1.0f)), steps);
- return min_to + factor_mapped * (max_to - min_to);
-}
-
-static float smoothstep_polynomial(float x)
-{
- /* This polynomial is only meant to be used for the [0, 1] range. */
- return (3.0f - 2.0f * x) * (x * x);
-}
-
-static float map_smoothstep(const float value,
- const float min_from,
- const float max_from,
- const float min_to,
- const float max_to)
-{
- const float factor = safe_divide(value - min_from, max_from - min_from);
- const float factor_clamped = std::clamp(factor, 0.0f, 1.0f);
- const float factor_mapped = smoothstep_polynomial(factor_clamped);
- return min_to + factor_mapped * (max_to - min_to);
-}
-
-static float smootherstep_polynomial(float x)
-{
- /* This polynomial is only meant to be used for the [0, 1] range. */
- return x * x * x * (x * (x * 6.0f - 15.0f) + 10.0f);
-}
-
-static float map_smootherstep(const float value,
- const float min_from,
- const float max_from,
- const float min_to,
- const float max_to)
-{
- const float factor = safe_divide(value - min_from, max_from - min_from);
- const float factor_clamped = std::clamp(factor, 0.0f, 1.0f);
- const float factor_mapped = smootherstep_polynomial(factor_clamped);
- return min_to + factor_mapped * (max_to - min_to);
-}
-
-static void map_range_float(const VArray<float> &attribute_input,
- MutableSpan<float> results,
- const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- NodeAttributeMapRange &node_storage = *(NodeAttributeMapRange *)node.storage;
- const int interpolation_type = node_storage.interpolation_type;
- const float min_from = params.get_input<float>("From Min");
- const float max_from = params.get_input<float>("From Max");
- const float min_to = params.get_input<float>("To Min");
- const float max_to = params.get_input<float>("To Max");
-
- VArray_Span<float> span{attribute_input};
-
- switch (interpolation_type) {
- case NODE_MAP_RANGE_LINEAR: {
- threading::parallel_for(span.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = map_linear(span[i], min_from, max_from, min_to, max_to);
- }
- });
- break;
- }
- case NODE_MAP_RANGE_STEPPED: {
- const float steps = params.get_input<float>("Steps");
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = map_stepped(span[i], min_from, max_from, min_to, max_to, steps);
- }
- });
- break;
- }
- case NODE_MAP_RANGE_SMOOTHSTEP: {
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = map_smoothstep(span[i], min_from, max_from, min_to, max_to);
- }
- });
- break;
- }
- case NODE_MAP_RANGE_SMOOTHERSTEP: {
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = map_smootherstep(span[i], min_from, max_from, min_to, max_to);
- }
- });
- break;
- }
- }
-
- if (ELEM(interpolation_type, NODE_MAP_RANGE_LINEAR, NODE_MAP_RANGE_STEPPED) &&
- params.get_input<bool>("Clamp")) {
- /* Users can specify min_to > max_to, but clamping expects min < max. */
- const float clamp_min = min_to < max_to ? min_to : max_to;
- const float clamp_max = min_to < max_to ? max_to : min_to;
-
- threading::parallel_for(results.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = std::clamp(results[i], clamp_min, clamp_max);
- }
- });
- }
-}
-
-static void map_range_float3(const VArray<float3> &attribute_input,
- const MutableSpan<float3> results,
- const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- NodeAttributeMapRange &node_storage = *(NodeAttributeMapRange *)node.storage;
- const int interpolation_type = node_storage.interpolation_type;
- const float3 min_from = params.get_input<float3>("From Min_001");
- const float3 max_from = params.get_input<float3>("From Max_001");
- const float3 min_to = params.get_input<float3>("To Min_001");
- const float3 max_to = params.get_input<float3>("To Max_001");
-
- VArray_Span<float3> span{attribute_input};
-
- switch (interpolation_type) {
- case NODE_MAP_RANGE_LINEAR: {
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i].x = map_linear(span[i].x, min_from.x, max_from.x, min_to.x, max_to.x);
- results[i].y = map_linear(span[i].y, min_from.y, max_from.y, min_to.y, max_to.y);
- results[i].z = map_linear(span[i].z, min_from.z, max_from.z, min_to.z, max_to.z);
- }
- });
- break;
- }
- case NODE_MAP_RANGE_STEPPED: {
- const float3 steps = params.get_input<float3>("Steps_001");
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i].x = map_stepped(
- span[i].x, min_from.x, max_from.x, min_to.x, max_to.x, steps.x);
- results[i].y = map_stepped(
- span[i].y, min_from.y, max_from.y, min_to.y, max_to.y, steps.y);
- results[i].z = map_stepped(
- span[i].z, min_from.z, max_from.z, min_to.z, max_to.z, steps.z);
- }
- });
- break;
- }
- case NODE_MAP_RANGE_SMOOTHSTEP: {
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i].x = map_smoothstep(span[i].x, min_from.x, max_from.x, min_to.x, max_to.x);
- results[i].y = map_smoothstep(span[i].y, min_from.y, max_from.y, min_to.y, max_to.y);
- results[i].z = map_smoothstep(span[i].z, min_from.z, max_from.z, min_to.z, max_to.z);
- }
- });
- break;
- }
- case NODE_MAP_RANGE_SMOOTHERSTEP: {
- threading::parallel_for(span.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i].x = map_smootherstep(span[i].x, min_from.x, max_from.x, min_to.x, max_to.x);
- results[i].y = map_smootherstep(span[i].y, min_from.y, max_from.y, min_to.y, max_to.y);
- results[i].z = map_smootherstep(span[i].z, min_from.z, max_from.z, min_to.z, max_to.z);
- }
- });
- break;
- }
- }
-
- if (ELEM(interpolation_type, NODE_MAP_RANGE_LINEAR, NODE_MAP_RANGE_STEPPED) &&
- params.get_input<bool>("Clamp")) {
- /* Users can specify min_to > max_to, but clamping expects min < max. */
- float3 clamp_min;
- float3 clamp_max;
- clamp_min.x = min_to.x < max_to.x ? min_to.x : max_to.x;
- clamp_max.x = min_to.x < max_to.x ? max_to.x : min_to.x;
- clamp_min.y = min_to.y < max_to.y ? min_to.y : max_to.y;
- clamp_max.y = min_to.y < max_to.y ? max_to.y : min_to.y;
- clamp_min.z = min_to.z < max_to.z ? min_to.z : max_to.z;
- clamp_max.z = min_to.z < max_to.z ? max_to.z : min_to.z;
-
- for (int i : results.index_range()) {
- clamp_v3_v3v3(results[i], clamp_min, clamp_max);
- }
- }
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- StringRef source_name,
- StringRef result_name)
-{
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
- std::optional<AttributeMetaData> source_info = component.attribute_get_meta_data(source_name);
- if (source_info) {
- return source_info->domain;
- }
- return ATTR_DOMAIN_POINT;
-}
-
-static void map_range_attribute(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const std::string input_name = params.get_input<std::string>("Attribute");
- const std::string result_name = params.get_input<std::string>("Result");
-
- if (input_name.empty() || result_name.empty()) {
- return;
- }
-
- const bNode &node = params.node();
- NodeAttributeMapRange &node_storage = *(NodeAttributeMapRange *)node.storage;
- const CustomDataType data_type = static_cast<CustomDataType>(node_storage.data_type);
-
- const AttributeDomain domain = get_result_domain(component, input_name, result_name);
-
- GVArray attribute_input = component.attribute_try_get_for_read(input_name, domain, data_type);
-
- if (!attribute_input) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("No attribute with name \"") + input_name + "\"");
- return;
- }
-
- OutputAttribute attribute_result = component.attribute_try_get_for_output_only(
- result_name, domain, data_type);
- if (!attribute_result) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("Could not find or create attribute with name \"") +
- result_name + "\"");
- return;
- }
-
- switch (data_type) {
- case CD_PROP_FLOAT: {
- map_range_float(attribute_input.typed<float>(), attribute_result.as_span<float>(), params);
- break;
- }
- case CD_PROP_FLOAT3: {
- map_range_float3(
- attribute_input.typed<float3>(), attribute_result.as_span<float3>(), params);
- break;
- }
- default:
- BLI_assert_unreachable();
- }
-
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- if (geometry_set.has<MeshComponent>()) {
- map_range_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- map_range_attribute(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- map_range_attribute(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_map_range_cc
-
-void register_node_type_geo_attribute_map_range()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_map_range_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_MAP_RANGE, "Attribute Map Range", NODE_CLASS_ATTRIBUTE);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeAttributeMapRange", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.draw_buttons = file_ns::fn_attribute_map_range_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc
deleted file mode 100644
index 9e909ec749b..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc
+++ /dev/null
@@ -1,308 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-
-#include "RNA_enum_types.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "NOD_math_functions.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_math_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("A"));
- b.add_input<decl::Float>(N_("A"), "A_001");
- b.add_input<decl::String>(N_("B"));
- b.add_input<decl::Float>(N_("B"), "B_001");
- b.add_input<decl::String>(N_("C"));
- b.add_input<decl::Float>(N_("C"), "C_001");
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static bool operation_use_input_c(const NodeMathOperation operation)
-{
- return ELEM(operation,
- NODE_MATH_MULTIPLY_ADD,
- NODE_MATH_SMOOTH_MIN,
- NODE_MATH_SMOOTH_MAX,
- NODE_MATH_WRAP,
- NODE_MATH_COMPARE);
-}
-
-static bool operation_use_input_b(const NodeMathOperation operation)
-{
- switch (operation) {
- case NODE_MATH_ADD:
- case NODE_MATH_SUBTRACT:
- case NODE_MATH_MULTIPLY:
- case NODE_MATH_DIVIDE:
- case NODE_MATH_POWER:
- case NODE_MATH_LOGARITHM:
- case NODE_MATH_MINIMUM:
- case NODE_MATH_MAXIMUM:
- case NODE_MATH_LESS_THAN:
- case NODE_MATH_GREATER_THAN:
- case NODE_MATH_MODULO:
- case NODE_MATH_ARCTAN2:
- case NODE_MATH_SNAP:
- case NODE_MATH_WRAP:
- case NODE_MATH_COMPARE:
- case NODE_MATH_MULTIPLY_ADD:
- case NODE_MATH_PINGPONG:
- case NODE_MATH_SMOOTH_MIN:
- case NODE_MATH_SMOOTH_MAX:
- return true;
- case NODE_MATH_SINE:
- case NODE_MATH_COSINE:
- case NODE_MATH_TANGENT:
- case NODE_MATH_ARCSINE:
- case NODE_MATH_ARCCOSINE:
- case NODE_MATH_ARCTANGENT:
- case NODE_MATH_ROUND:
- case NODE_MATH_ABSOLUTE:
- case NODE_MATH_FLOOR:
- case NODE_MATH_CEIL:
- case NODE_MATH_FRACTION:
- case NODE_MATH_SQRT:
- case NODE_MATH_INV_SQRT:
- case NODE_MATH_SIGN:
- case NODE_MATH_EXPONENT:
- case NODE_MATH_RADIANS:
- case NODE_MATH_DEGREES:
- case NODE_MATH_SINH:
- case NODE_MATH_COSH:
- case NODE_MATH_TANH:
- case NODE_MATH_TRUNC:
- return false;
- }
- BLI_assert(false);
- return false;
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- bNode *node = (bNode *)ptr->data;
- NodeAttributeMath *node_storage = (NodeAttributeMath *)node->storage;
- NodeMathOperation operation = (NodeMathOperation)node_storage->operation;
-
- uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
-
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "input_type_a", 0, IFACE_("A"), ICON_NONE);
- if (operation_use_input_b(operation)) {
- uiItemR(layout, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
- }
- if (operation_use_input_c(operation)) {
- uiItemR(layout, ptr, "input_type_c", 0, IFACE_("C"), ICON_NONE);
- }
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeMath *data = MEM_cnew<NodeAttributeMath>(__func__);
-
- data->operation = NODE_MATH_ADD;
- data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- data->input_type_c = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node->storage = data;
-}
-
-static void geo_node_math_label(const bNodeTree *UNUSED(ntree),
- const bNode *node,
- char *label,
- int maxlen)
-{
- NodeAttributeMath &node_storage = *(NodeAttributeMath *)node->storage;
- const char *name;
- bool enum_label = RNA_enum_name(rna_enum_node_math_items, node_storage.operation, &name);
- if (!enum_label) {
- name = "Unknown";
- }
- BLI_strncpy(label, IFACE_(name), maxlen);
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeAttributeMath &node_storage = *(NodeAttributeMath *)node->storage;
- NodeMathOperation operation = static_cast<NodeMathOperation>(node_storage.operation);
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "A", (GeometryNodeAttributeInputMode)node_storage.input_type_a);
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "B",
- (GeometryNodeAttributeInputMode)node_storage.input_type_b,
- operation_use_input_b(operation));
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "C",
- (GeometryNodeAttributeInputMode)node_storage.input_type_c,
- operation_use_input_c(operation));
-}
-
-static void do_math_operation(const VArray<float> &span_a,
- const VArray<float> &span_b,
- const VArray<float> &span_c,
- MutableSpan<float> span_result,
- const NodeMathOperation operation)
-{
- bool success = try_dispatch_float_math_fl_fl_fl_to_fl(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(span_result.size()), 512, [&](IndexRange range) {
- for (const int i : range) {
- span_result[i] = math_function(span_a[i], span_b[i], span_c[i]);
- }
- });
- });
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation(const VArray<float> &span_a,
- const VArray<float> &span_b,
- MutableSpan<float> span_result,
- const NodeMathOperation operation)
-{
- bool success = try_dispatch_float_math_fl_fl_to_fl(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(span_result.size()), 1024, [&](IndexRange range) {
- for (const int i : range) {
- span_result[i] = math_function(span_a[i], span_b[i]);
- }
- });
- });
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation(const VArray<float> &span_input,
- MutableSpan<float> span_result,
- const NodeMathOperation operation)
-{
- bool success = try_dispatch_float_math_fl_to_fl(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(span_result.size()), 1024, [&](IndexRange range) {
- for (const int i : range) {
- span_result[i] = math_function(span_input[i]);
- }
- });
- });
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- const NodeMathOperation operation,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the highest priority domain from existing input attributes, or the default. */
- const AttributeDomain default_domain = ATTR_DOMAIN_POINT;
- if (operation_use_input_b(operation)) {
- if (operation_use_input_c(operation)) {
- return params.get_highest_priority_input_domain({"A", "B", "C"}, component, default_domain);
- }
- return params.get_highest_priority_input_domain({"A", "B"}, component, default_domain);
- }
- return params.get_highest_priority_input_domain({"A"}, component, default_domain);
-}
-
-static void attribute_math_calc(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- const NodeAttributeMath *node_storage = (const NodeAttributeMath *)node.storage;
- const NodeMathOperation operation = static_cast<NodeMathOperation>(node_storage->operation);
- const std::string result_name = params.get_input<std::string>("Result");
-
- /* The result type of this node is always float. */
- const AttributeDomain result_domain = get_result_domain(
- component, params, operation, result_name);
-
- OutputAttribute_Typed<float> attribute_result =
- component.attribute_try_get_for_output_only<float>(result_name, result_domain);
- if (!attribute_result) {
- return;
- }
-
- VArray<float> attribute_a = params.get_input_attribute<float>(
- "A", component, result_domain, 0.0f);
-
- MutableSpan<float> result_span = attribute_result.as_span();
-
- /* Note that passing the data with `get_internal_span<float>()` works
- * because the attributes were accessed with #CD_PROP_FLOAT. */
- if (operation_use_input_b(operation)) {
- VArray<float> attribute_b = params.get_input_attribute<float>(
- "B", component, result_domain, 0.0f);
- if (operation_use_input_c(operation)) {
- VArray<float> attribute_c = params.get_input_attribute<float>(
- "C", component, result_domain, 0.0f);
- do_math_operation(attribute_a, attribute_b, attribute_c, result_span, operation);
- }
- else {
- do_math_operation(attribute_a, attribute_b, result_span, operation);
- }
- }
- else {
- do_math_operation(attribute_a, result_span, operation);
- }
-
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- attribute_math_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- attribute_math_calc(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- attribute_math_calc(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_math_cc
-
-void register_node_type_geo_attribute_math()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_math_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_MATH, "Attribute Math", NODE_CLASS_ATTRIBUTE);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- ntype.labelfunc = file_ns::geo_node_math_label;
- node_type_update(&ntype, file_ns::node_update);
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(
- &ntype, "NodeAttributeMath", node_free_standard_storage, node_copy_standard_storage);
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc
deleted file mode 100644
index aab33e1ef01..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-
-#include "BKE_material.h"
-
-#include "DNA_material_types.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_mix_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Factor"));
- b.add_input<decl::Float>(N_("Factor"), "Factor_001")
- .default_value(0.5f)
- .min(0.0f)
- .max(1.0f)
- .subtype(PROP_FACTOR);
- b.add_input<decl::String>(N_("A"));
- b.add_input<decl::Float>(N_("A"), "A_001");
- b.add_input<decl::Vector>(N_("A"), "A_002");
- b.add_input<decl::Color>(N_("A"), "A_003").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_input<decl::String>(N_("B"));
- b.add_input<decl::Float>(N_("B"), "B_001");
- b.add_input<decl::Vector>(N_("B"), "B_002");
- b.add_input<decl::Color>(N_("B"), "B_003").default_value({0.5f, 0.5f, 0.5f, 1.0f});
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "blend_type", 0, "", ICON_NONE);
- uiLayout *col = uiLayoutColumn(layout, false);
- uiItemR(col, ptr, "input_type_factor", 0, IFACE_("Factor"), ICON_NONE);
- uiItemR(col, ptr, "input_type_a", 0, IFACE_("A"), ICON_NONE);
- uiItemR(col, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeAttributeMix *data = MEM_cnew<NodeAttributeMix>("attribute mix node");
- data->blend_type = MA_RAMP_BLEND;
- data->input_type_factor = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeAttributeMix *node_storage = (NodeAttributeMix *)node->storage;
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Factor", (GeometryNodeAttributeInputMode)node_storage->input_type_factor);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "A", (GeometryNodeAttributeInputMode)node_storage->input_type_a);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "B", (GeometryNodeAttributeInputMode)node_storage->input_type_b);
-}
-
-static void do_mix_operation_float(const int blend_mode,
- const VArray<float> &factors,
- const VArray<float> &inputs_a,
- const VArray<float> &inputs_b,
- VMutableArray<float> &results)
-{
- const int size = results.size();
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float factor = factors[i];
- float3 a{inputs_a[i]};
- const float3 b{inputs_b[i]};
- ramp_blend(blend_mode, a, factor, b);
- const float result = a.x;
- results.set(i, result);
- }
- });
-}
-
-static void do_mix_operation_float3(const int blend_mode,
- const VArray<float> &factors,
- const VArray<float3> &inputs_a,
- const VArray<float3> &inputs_b,
- VMutableArray<float3> &results)
-{
- const int size = results.size();
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float factor = factors[i];
- float3 a = inputs_a[i];
- const float3 b = inputs_b[i];
- ramp_blend(blend_mode, a, factor, b);
- results.set(i, a);
- }
- });
-}
-
-static void do_mix_operation_color4f(const int blend_mode,
- const VArray<float> &factors,
- const VArray<ColorGeometry4f> &inputs_a,
- const VArray<ColorGeometry4f> &inputs_b,
- VMutableArray<ColorGeometry4f> &results)
-{
- const int size = results.size();
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float factor = factors[i];
- ColorGeometry4f a = inputs_a[i];
- const ColorGeometry4f b = inputs_b[i];
- ramp_blend(blend_mode, a, factor, b);
- results.set(i, a);
- }
- });
-}
-
-static void do_mix_operation(const CustomDataType result_type,
- int blend_mode,
- const VArray<float> &attribute_factor,
- const GVArray &attribute_a,
- const GVArray &attribute_b,
- GVMutableArray &attribute_result)
-{
- if (result_type == CD_PROP_FLOAT) {
- VMutableArray<float> result = attribute_result.typed<float>();
- do_mix_operation_float(blend_mode,
- attribute_factor,
- attribute_a.typed<float>(),
- attribute_b.typed<float>(),
- result);
- }
- else if (result_type == CD_PROP_FLOAT3) {
- VMutableArray<float3> result = attribute_result.typed<float3>();
- do_mix_operation_float3(blend_mode,
- attribute_factor,
- attribute_a.typed<float3>(),
- attribute_b.typed<float3>(),
- result);
- }
- else if (result_type == CD_PROP_COLOR) {
- VMutableArray<ColorGeometry4f> result = attribute_result.typed<ColorGeometry4f>();
- do_mix_operation_color4f(blend_mode,
- attribute_factor,
- attribute_a.typed<ColorGeometry4f>(),
- attribute_b.typed<ColorGeometry4f>(),
- result);
- }
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the highest priority domain from existing input attributes, or the default. */
- return params.get_highest_priority_input_domain({"A", "B"}, component, ATTR_DOMAIN_POINT);
-}
-
-static void attribute_mix_calc(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- const NodeAttributeMix *node_storage = (const NodeAttributeMix *)node.storage;
- const std::string result_name = params.get_input<std::string>("Result");
-
- /* Use the highest complexity data type among the inputs and outputs, that way the node will
- * never "remove information". Use CD_PROP_BOOL as the lowest complexity data type, but in any
- * real situation it won't be returned. */
- const CustomDataType result_type = bke::attribute_data_type_highest_complexity({
- params.get_input_attribute_data_type("A", component, CD_PROP_BOOL),
- params.get_input_attribute_data_type("B", component, CD_PROP_BOOL),
- params.get_input_attribute_data_type("Result", component, CD_PROP_BOOL),
- });
-
- const AttributeDomain result_domain = get_result_domain(component, params, result_name);
-
- OutputAttribute attribute_result = component.attribute_try_get_for_output_only(
- result_name, result_domain, result_type);
- if (!attribute_result) {
- return;
- }
-
- VArray<float> attribute_factor = params.get_input_attribute<float>(
- "Factor", component, result_domain, 0.5f);
- GVArray attribute_a = params.get_input_attribute(
- "A", component, result_domain, result_type, nullptr);
- GVArray attribute_b = params.get_input_attribute(
- "B", component, result_domain, result_type, nullptr);
-
- do_mix_operation(result_type,
- node_storage->blend_type,
- attribute_factor,
- attribute_a,
- attribute_b,
- attribute_result.varray());
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- attribute_mix_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- attribute_mix_calc(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- attribute_mix_calc(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_mix_cc
-
-void register_node_type_geo_attribute_mix()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_mix_cc;
-
- static bNodeType ntype;
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_ATTRIBUTE_MIX, "Attribute Mix", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- ntype.declare = file_ns::node_declare;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_storage(
- &ntype, "NodeAttributeMix", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc
deleted file mode 100644
index a3af6200ab8..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc
+++ /dev/null
@@ -1,237 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-#include "BLI_timeit.hh"
-
-#include "DNA_mesh_types.h"
-
-#include "BKE_bvhutils.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_proximity_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Geometry>(N_("Target"));
- b.add_input<decl::String>(N_("Distance"));
- b.add_input<decl::String>(N_("Position"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "target_geometry_element", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometryAttributeProximity *node_storage = MEM_cnew<NodeGeometryAttributeProximity>(
- __func__);
-
- node_storage->target_geometry_element = GEO_NODE_PROXIMITY_TARGET_FACES;
- node->storage = node_storage;
-}
-
-static void calculate_mesh_proximity(const VArray<float3> &positions,
- const Mesh &mesh,
- const GeometryNodeAttributeProximityTargetType type,
- MutableSpan<float> r_distances,
- MutableSpan<float3> r_locations)
-{
- BVHTreeFromMesh bvh_data;
- switch (type) {
- case GEO_NODE_PROXIMITY_TARGET_POINTS:
- BKE_bvhtree_from_mesh_get(&bvh_data, &mesh, BVHTREE_FROM_VERTS, 2);
- break;
- case GEO_NODE_PROXIMITY_TARGET_EDGES:
- BKE_bvhtree_from_mesh_get(&bvh_data, &mesh, BVHTREE_FROM_EDGES, 2);
- break;
- case GEO_NODE_PROXIMITY_TARGET_FACES:
- BKE_bvhtree_from_mesh_get(&bvh_data, &mesh, BVHTREE_FROM_LOOPTRI, 2);
- break;
- }
-
- if (bvh_data.tree == nullptr) {
- return;
- }
-
- threading::parallel_for(positions.index_range(), 512, [&](IndexRange range) {
- BVHTreeNearest nearest;
- copy_v3_fl(nearest.co, FLT_MAX);
- nearest.index = -1;
-
- for (int i : range) {
- /* Use the distance to the last found point as upper bound to speedup the bvh lookup. */
- nearest.dist_sq = math::distance_squared(float3(nearest.co), positions[i]);
-
- BLI_bvhtree_find_nearest(
- bvh_data.tree, positions[i], &nearest, bvh_data.nearest_callback, &bvh_data);
-
- if (nearest.dist_sq < r_distances[i]) {
- r_distances[i] = nearest.dist_sq;
- if (!r_locations.is_empty()) {
- r_locations[i] = nearest.co;
- }
- }
- }
- });
-
- free_bvhtree_from_mesh(&bvh_data);
-}
-
-static void calculate_pointcloud_proximity(const VArray<float3> &positions,
- const PointCloud &pointcloud,
- MutableSpan<float> r_distances,
- MutableSpan<float3> r_locations)
-{
- BVHTreeFromPointCloud bvh_data;
- BKE_bvhtree_from_pointcloud_get(&bvh_data, &pointcloud, 2);
- if (bvh_data.tree == nullptr) {
- return;
- }
-
- threading::parallel_for(positions.index_range(), 512, [&](IndexRange range) {
- BVHTreeNearest nearest;
- copy_v3_fl(nearest.co, FLT_MAX);
- nearest.index = -1;
-
- for (int i : range) {
- /* Use the distance to the closest point in the mesh to speedup the pointcloud bvh lookup.
- * This is ok because we only need to find the closest point in the pointcloud if it's
- * closer than the mesh. */
- nearest.dist_sq = r_distances[i];
-
- BLI_bvhtree_find_nearest(
- bvh_data.tree, positions[i], &nearest, bvh_data.nearest_callback, &bvh_data);
-
- if (nearest.dist_sq < r_distances[i]) {
- r_distances[i] = nearest.dist_sq;
- if (!r_locations.is_empty()) {
- r_locations[i] = nearest.co;
- }
- }
- }
- });
-
- free_bvhtree_from_pointcloud(&bvh_data);
-}
-
-static void attribute_calc_proximity(GeometryComponent &component,
- GeometrySet &target,
- GeoNodeExecParams &params)
-{
- const std::string distance_name = params.get_input<std::string>("Distance");
- OutputAttribute_Typed<float> distance_attribute =
- component.attribute_try_get_for_output_only<float>(distance_name, ATTR_DOMAIN_POINT);
-
- const std::string location_name = params.get_input<std::string>("Position");
- OutputAttribute_Typed<float3> location_attribute =
- component.attribute_try_get_for_output_only<float3>(location_name, ATTR_DOMAIN_POINT);
-
- ReadAttributeLookup position_attribute = component.attribute_try_get_for_read("position");
- if (!position_attribute || (!distance_attribute && !location_attribute)) {
- return;
- }
- VArray<float3> positions = position_attribute.varray.typed<float3>();
- const NodeGeometryAttributeProximity &storage =
- *(const NodeGeometryAttributeProximity *)params.node().storage;
-
- Array<float> distances_internal;
- MutableSpan<float> distances;
- if (distance_attribute) {
- distances = distance_attribute.as_span();
- }
- else {
- /* Theoretically it would be possible to avoid using the distance array when it's not required
- * and there is only one component. However, this only adds an allocation and a single float
- * comparison per vertex, so it's likely not worth it. */
- distances_internal.reinitialize(positions.size());
- distances = distances_internal;
- }
- distances.fill(FLT_MAX);
- MutableSpan<float3> locations = location_attribute ? location_attribute.as_span() :
- MutableSpan<float3>();
-
- if (target.has_mesh()) {
- calculate_mesh_proximity(
- positions,
- *target.get_mesh_for_read(),
- static_cast<GeometryNodeAttributeProximityTargetType>(storage.target_geometry_element),
- distances,
- locations);
- }
-
- if (target.has_pointcloud() &&
- storage.target_geometry_element == GEO_NODE_PROXIMITY_TARGET_POINTS) {
- calculate_pointcloud_proximity(
- positions, *target.get_pointcloud_for_read(), distances, locations);
- }
-
- if (distance_attribute) {
- /* Squared distances are used above to speed up comparisons,
- * so do the square roots now if necessary for the output attribute. */
- threading::parallel_for(distances.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- distances[i] = std::sqrt(distances[i]);
- }
- });
- distance_attribute.save();
- }
- if (location_attribute) {
- location_attribute.save();
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- GeometrySet geometry_set_target = params.extract_input<GeometrySet>("Target");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- /* This isn't required. This node should be rewritten to handle instances
- * for the target geometry set. However, the generic BVH API complicates this. */
- geometry_set_target = geometry::realize_instances_legacy(geometry_set_target);
-
- if (geometry_set.has<MeshComponent>()) {
- attribute_calc_proximity(
- geometry_set.get_component_for_write<MeshComponent>(), geometry_set_target, params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- attribute_calc_proximity(
- geometry_set.get_component_for_write<PointCloudComponent>(), geometry_set_target, params);
- }
- if (geometry_set.has<CurveComponent>()) {
- attribute_calc_proximity(
- geometry_set.get_component_for_write<CurveComponent>(), geometry_set_target, params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_proximity_cc
-
-void register_node_type_geo_legacy_attribute_proximity()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_proximity_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_PROXIMITY, "Attribute Proximity", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(&ntype,
- "NodeGeometryAttributeProximity",
- node_free_standard_storage,
- node_copy_standard_storage);
-
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc
deleted file mode 100644
index 6a306229b8c..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_hash.h"
-#include "BLI_rand.hh"
-#include "BLI_task.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes {
-
-Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &component,
- const AttributeDomain domain)
-{
- const int domain_size = component.attribute_domain_size(domain);
-
- /* Hash the reserved name attribute "id" as a (hopefully) stable seed for each point. */
- GVArray hash_attribute = component.attribute_try_get_for_read("id", domain);
- Array<uint32_t> hashes(domain_size);
- if (hash_attribute) {
- BLI_assert(hashes.size() == hash_attribute.size());
- const CPPType &cpp_type = hash_attribute.type();
- BLI_assert(cpp_type.is_hashable());
- GVArray_GSpan items{hash_attribute};
- threading::parallel_for(hashes.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- hashes[i] = cpp_type.hash(items[i]);
- }
- });
- }
- else {
- /* If there is no "id" attribute for per-point variation, just create it here. */
- RandomNumberGenerator rng(0);
- for (const int i : hashes.index_range()) {
- hashes[i] = rng.get_uint32();
- }
- }
-
- return hashes;
-}
-
-} // namespace blender::nodes
-
-namespace blender::nodes::node_geo_legacy_attribute_randomize_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute"));
- b.add_input<decl::Vector>(N_("Min"));
- b.add_input<decl::Vector>(N_("Max")).default_value({1.0f, 1.0f, 1.0f});
- b.add_input<decl::Float>(N_("Min"), "Min_001");
- b.add_input<decl::Float>(N_("Max"), "Max_001").default_value(1.0f);
- b.add_input<decl::Int>(N_("Min"), "Min_002").min(-100000).max(100000);
- b.add_input<decl::Int>(N_("Max"), "Max_002").default_value(100).min(-100000).max(100000);
- b.add_input<decl::Int>(N_("Seed")).min(-10000).max(10000);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
- uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeRandomize *data = MEM_cnew<NodeAttributeRandomize>(__func__);
- data->data_type = CD_PROP_FLOAT;
- data->domain = ATTR_DOMAIN_POINT;
- data->operation = GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- bNodeSocket *sock_min_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
- bNodeSocket *sock_max_vector = sock_min_vector->next;
- bNodeSocket *sock_min_float = sock_max_vector->next;
- bNodeSocket *sock_max_float = sock_min_float->next;
- bNodeSocket *sock_min_int = sock_max_float->next;
- bNodeSocket *sock_max_int = sock_min_int->next;
-
- const NodeAttributeRandomize &storage = *(const NodeAttributeRandomize *)node->storage;
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- nodeSetSocketAvailability(ntree, sock_min_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_max_vector, data_type == CD_PROP_FLOAT3);
- nodeSetSocketAvailability(ntree, sock_min_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_max_float, data_type == CD_PROP_FLOAT);
- nodeSetSocketAvailability(ntree, sock_min_int, data_type == CD_PROP_INT32);
- nodeSetSocketAvailability(ntree, sock_max_int, data_type == CD_PROP_INT32);
-}
-
-template<typename T>
-T random_value_in_range(const uint32_t id, const uint32_t seed, const T min, const T max);
-
-template<>
-inline float random_value_in_range(const uint32_t id,
- const uint32_t seed,
- const float min,
- const float max)
-{
- return BLI_hash_int_2d_to_float(id, seed) * (max - min) + min;
-}
-
-template<>
-inline int random_value_in_range(const uint32_t id,
- const uint32_t seed,
- const int min,
- const int max)
-{
- return round_fl_to_int(
- random_value_in_range<float>(id, seed, static_cast<float>(min), static_cast<float>(max)));
-}
-
-template<>
-inline float3 random_value_in_range(const uint32_t id,
- const uint32_t seed,
- const float3 min,
- const float3 max)
-{
- const float x = BLI_hash_int_3d_to_float(seed, id, 435109);
- const float y = BLI_hash_int_3d_to_float(seed, id, 380867);
- const float z = BLI_hash_int_3d_to_float(seed, id, 1059217);
-
- return float3(x, y, z) * (max - min) + min;
-}
-
-template<typename T>
-static void randomize_attribute(MutableSpan<T> span,
- const T min,
- const T max,
- Span<uint32_t> ids,
- const uint32_t seed,
- const GeometryNodeAttributeRandomizeMode operation)
-{
- /* The operations could be templated too, but it doesn't make the code much shorter. */
- switch (operation) {
- case GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE:
- threading::parallel_for(span.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- const T random_value = random_value_in_range<T>(ids[i], seed, min, max);
- span[i] = random_value;
- }
- });
- break;
- case GEO_NODE_ATTRIBUTE_RANDOMIZE_ADD:
- threading::parallel_for(span.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- const T random_value = random_value_in_range<T>(ids[i], seed, min, max);
- span[i] = span[i] + random_value;
- }
- });
- break;
- case GEO_NODE_ATTRIBUTE_RANDOMIZE_SUBTRACT:
- threading::parallel_for(span.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- const T random_value = random_value_in_range<T>(ids[i], seed, min, max);
- span[i] = span[i] - random_value;
- }
- });
- break;
- case GEO_NODE_ATTRIBUTE_RANDOMIZE_MULTIPLY:
- threading::parallel_for(span.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- const T random_value = random_value_in_range<T>(ids[i], seed, min, max);
- span[i] = span[i] * random_value;
- }
- });
- break;
- default:
- BLI_assert(false);
- break;
- }
-}
-
-static void randomize_attribute_bool(MutableSpan<bool> span,
- Span<uint32_t> ids,
- const uint32_t seed,
- const GeometryNodeAttributeRandomizeMode operation)
-{
- BLI_assert(operation == GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE);
- UNUSED_VARS_NDEBUG(operation);
- threading::parallel_for(span.index_range(), 512, [&](IndexRange range) {
- for (const int i : range) {
- const bool random_value = BLI_hash_int_2d_to_float(ids[i], seed) > 0.5f;
- span[i] = random_value;
- }
- });
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- const StringRef name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the input domain chosen in the interface. */
- const bNode &node = params.node();
- return static_cast<AttributeDomain>(node.custom2);
-}
-
-static void randomize_attribute_on_component(GeometryComponent &component,
- const GeoNodeExecParams &params,
- StringRef attribute_name,
- const CustomDataType data_type,
- const GeometryNodeAttributeRandomizeMode operation,
- const int seed)
-{
- /* If the node is not in "replace / create" mode and the attribute
- * doesn't already exist, don't do the operation. */
- if (operation != GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE) {
- if (!component.attribute_exists(attribute_name)) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("No attribute with name \"") + attribute_name + "\"");
- return;
- }
- }
-
- const AttributeDomain domain = get_result_domain(component, params, attribute_name);
-
- OutputAttribute attribute = component.attribute_try_get_for_output(
- attribute_name, domain, data_type);
- if (!attribute) {
- return;
- }
-
- GMutableSpan span = attribute.as_span();
-
- Array<uint32_t> hashes = get_geometry_element_ids_as_uints(component, domain);
-
- switch (data_type) {
- case CD_PROP_FLOAT3: {
- const float3 min = params.get_input<float3>("Min");
- const float3 max = params.get_input<float3>("Max");
- randomize_attribute<float3>(span.typed<float3>(), min, max, hashes, seed, operation);
- break;
- }
- case CD_PROP_FLOAT: {
- const float min = params.get_input<float>("Min_001");
- const float max = params.get_input<float>("Max_001");
- randomize_attribute<float>(span.typed<float>(), min, max, hashes, seed, operation);
- break;
- }
- case CD_PROP_BOOL: {
- randomize_attribute_bool(span.typed<bool>(), hashes, seed, operation);
- break;
- }
- case CD_PROP_INT32: {
- const int min = params.get_input<int>("Min_002");
- const int max = params.get_input<int>("Max_002");
- randomize_attribute<int>(span.typed<int>(), min, max, hashes, seed, operation);
- break;
- }
- default: {
- BLI_assert(false);
- break;
- }
- }
-
- attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- const std::string attribute_name = params.get_input<std::string>("Attribute");
- if (attribute_name.empty()) {
- params.set_default_remaining_outputs();
- return;
- }
- const int seed = params.get_input<int>("Seed");
- const NodeAttributeRandomize &storage = *(const NodeAttributeRandomize *)params.node().storage;
- const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
- const GeometryNodeAttributeRandomizeMode operation =
- static_cast<GeometryNodeAttributeRandomizeMode>(storage.operation);
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- randomize_attribute_on_component(geometry_set.get_component_for_write<MeshComponent>(),
- params,
- attribute_name,
- data_type,
- operation,
- seed);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- randomize_attribute_on_component(geometry_set.get_component_for_write<PointCloudComponent>(),
- params,
- attribute_name,
- data_type,
- operation,
- seed);
- }
- if (geometry_set.has<CurveComponent>()) {
- randomize_attribute_on_component(geometry_set.get_component_for_write<CurveComponent>(),
- params,
- attribute_name,
- data_type,
- operation,
- seed);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_randomize_cc
-
-void register_node_type_geo_legacy_attribute_randomize()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_randomize_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_RANDOMIZE, "Attribute Randomize", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
-
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_storage(
- &ntype, "NodeAttributeRandomize", node_free_standard_storage, node_copy_standard_storage);
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_remove.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_remove.cc
deleted file mode 100644
index cc7118fd305..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_remove.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_remove_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Attribute")).multi_input();
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void remove_attribute(GeometryComponent &component,
- GeoNodeExecParams &params,
- Span<std::string> attribute_names)
-{
- for (std::string attribute_name : attribute_names) {
- if (attribute_name.empty()) {
- continue;
- }
-
- if (!component.attribute_try_delete(attribute_name)) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("Cannot delete attribute with name \"") + attribute_name +
- "\"");
- }
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- Vector<std::string> attribute_names = params.extract_multi_input<std::string>("Attribute");
-
- for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,
- GEO_COMPONENT_TYPE_POINT_CLOUD,
- GEO_COMPONENT_TYPE_CURVE,
- GEO_COMPONENT_TYPE_INSTANCES}) {
- if (geometry_set.has(type)) {
- remove_attribute(geometry_set.get_component_for_write(type), params, attribute_names);
- }
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_remove_cc
-
-void register_node_type_geo_legacy_attribute_remove()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_remove_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_REMOVE, "Attribute Remove", NODE_CLASS_ATTRIBUTE);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.declare = file_ns::node_declare;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc
deleted file mode 100644
index 42719d4bf1a..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_compiler_attrs.h"
-#include "BLI_task.hh"
-
-#include "DNA_texture_types.h"
-
-#include "BKE_texture.h"
-
-#include "RE_texture.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_sample_texture_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Texture>(N_("Texture")).hide_label();
- b.add_input<decl::String>(N_("Mapping"));
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const StringRef result_name,
- const StringRef map_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the name of the map attribute. */
- std::optional<AttributeMetaData> map_info = component.attribute_get_meta_data(map_name);
- if (map_info) {
- return map_info->domain;
- }
-
- /* The node won't execute in this case, but we still have to return a value. */
- return ATTR_DOMAIN_POINT;
-}
-
-static void execute_on_component(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- Tex *texture = params.get_input<Tex *>("Texture");
- if (texture == nullptr) {
- return;
- }
-
- const std::string result_attribute_name = params.get_input<std::string>("Result");
- const std::string mapping_name = params.get_input<std::string>("Mapping");
- if (!component.attribute_exists(mapping_name)) {
- return;
- }
-
- const AttributeDomain result_domain = get_result_domain(
- component, result_attribute_name, mapping_name);
-
- OutputAttribute_Typed<ColorGeometry4f> attribute_out =
- component.attribute_try_get_for_output_only<ColorGeometry4f>(result_attribute_name,
- result_domain);
- if (!attribute_out) {
- return;
- }
-
- VArray<float3> mapping_attribute = component.attribute_get_for_read<float3>(
- mapping_name, result_domain, {0, 0, 0});
-
- MutableSpan<ColorGeometry4f> colors = attribute_out.as_span();
- threading::parallel_for(IndexRange(mapping_attribute.size()), 128, [&](IndexRange range) {
- for (const int i : range) {
- TexResult texture_result = {0};
- const float3 position = mapping_attribute[i];
- /* For legacy reasons we have to map [0, 1] to [-1, 1] to support uv mappings. */
- const float3 remapped_position = position * 2.0f - float3(1.0f);
- BKE_texture_get_value(nullptr, texture, remapped_position, &texture_result, false);
- copy_v4_v4(colors[i], texture_result.trgba);
- }
- });
-
- attribute_out.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- execute_on_component(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- execute_on_component(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- execute_on_component(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_sample_texture_cc
-
-void register_node_type_geo_sample_texture()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_sample_texture_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype,
- GEO_NODE_LEGACY_ATTRIBUTE_SAMPLE_TEXTURE,
- "Attribute Sample Texture",
- NODE_CLASS_ATTRIBUTE);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc
deleted file mode 100644
index 85ffbf6679b..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_separate_xyz_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Vector"));
- b.add_input<decl::Vector>(N_("Vector"), "Vector_001");
- b.add_input<decl::String>(N_("Result X"));
- b.add_input<decl::String>(N_("Result Y"));
- b.add_input<decl::String>(N_("Result Z"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeSeparateXYZ *data = MEM_cnew<NodeAttributeSeparateXYZ>(__func__);
- data->input_type = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeAttributeSeparateXYZ *node_storage = (NodeAttributeSeparateXYZ *)node->storage;
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Vector", (GeometryNodeAttributeInputMode)node_storage->input_type);
-}
-
-static void extract_input(const int index, const Span<float3> &input, MutableSpan<float> result)
-{
- for (const int i : result.index_range()) {
- /* Get the component of the float3. (0: X, 1: Y, 2: Z). */
- const float component = input[i][index];
- result[i] = component;
- }
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- const StringRef name_x,
- const StringRef name_y,
- const StringRef name_z)
-{
- /* Use the highest priority domain from any existing attribute outputs. */
- Vector<AttributeDomain, 3> output_domains;
- std::optional<AttributeMetaData> info_x = component.attribute_get_meta_data(name_x);
- std::optional<AttributeMetaData> info_y = component.attribute_get_meta_data(name_y);
- std::optional<AttributeMetaData> info_z = component.attribute_get_meta_data(name_z);
- if (info_x) {
- output_domains.append(info_x->domain);
- }
- if (info_y) {
- output_domains.append(info_y->domain);
- }
- if (info_z) {
- output_domains.append(info_z->domain);
- }
- if (output_domains.size() > 0) {
- return bke::attribute_domain_highest_priority(output_domains);
- }
-
- /* Otherwise use the domain of the input attribute, or the default. */
- return params.get_highest_priority_input_domain({"Vector"}, component, ATTR_DOMAIN_POINT);
-}
-
-static void separate_attribute(GeometryComponent &component, const GeoNodeExecParams &params)
-{
- const std::string result_name_x = params.get_input<std::string>("Result X");
- const std::string result_name_y = params.get_input<std::string>("Result Y");
- const std::string result_name_z = params.get_input<std::string>("Result Z");
- if (result_name_x.empty() && result_name_y.empty() && result_name_z.empty()) {
- return;
- }
-
- /* The node is only for float3 to float conversions. */
- const AttributeDomain result_domain = get_result_domain(
- component, params, result_name_x, result_name_y, result_name_z);
-
- VArray<float3> attribute_input = params.get_input_attribute<float3>(
- "Vector", component, result_domain, {0, 0, 0});
- VArray_Span<float3> input_span{attribute_input};
-
- OutputAttribute_Typed<float> attribute_result_x =
- component.attribute_try_get_for_output_only<float>(result_name_x, result_domain);
- OutputAttribute_Typed<float> attribute_result_y =
- component.attribute_try_get_for_output_only<float>(result_name_y, result_domain);
- OutputAttribute_Typed<float> attribute_result_z =
- component.attribute_try_get_for_output_only<float>(result_name_z, result_domain);
-
- /* Only extract the components for the outputs with a given attribute. */
- if (attribute_result_x) {
- extract_input(0, input_span, attribute_result_x.as_span());
- attribute_result_x.save();
- }
- if (attribute_result_y) {
- extract_input(1, input_span, attribute_result_y.as_span());
- attribute_result_y.save();
- }
- if (attribute_result_z) {
- extract_input(2, input_span, attribute_result_z.as_span());
- attribute_result_z.save();
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- separate_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- separate_attribute(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- separate_attribute(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_separate_xyz_cc
-
-void register_node_type_geo_attribute_separate_xyz()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_separate_xyz_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype,
- GEO_NODE_LEGACY_ATTRIBUTE_SEPARATE_XYZ,
- "Attribute Separate XYZ",
- NODE_CLASS_ATTRIBUTE);
- ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeAttributeSeparateXYZ", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc
deleted file mode 100644
index 802feb88ce2..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc
+++ /dev/null
@@ -1,515 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_kdopbvh.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_pointcloud_types.h"
-
-#include "BKE_bvhutils.h"
-#include "BKE_mesh_runtime.h"
-#include "BKE_mesh_sample.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_transfer_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Geometry>(N_("Source Geometry"));
- b.add_input<decl::String>(N_("Source"));
- b.add_input<decl::String>(N_("Destination"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "domain", 0, IFACE_("Domain"), ICON_NONE);
- uiItemR(layout, ptr, "mapping", 0, IFACE_("Mapping"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryAttributeTransfer *data = MEM_cnew<NodeGeometryAttributeTransfer>(__func__);
- data->domain = ATTR_DOMAIN_AUTO;
- node->storage = data;
-}
-
-static void get_result_domain_and_data_type(const GeometrySet &src_geometry,
- const GeometryComponent &dst_component,
- const StringRef attribute_name,
- CustomDataType *r_data_type,
- AttributeDomain *r_domain)
-{
- Vector<CustomDataType> data_types;
- Vector<AttributeDomain> domains;
-
- const PointCloudComponent *pointcloud_component =
- src_geometry.get_component_for_read<PointCloudComponent>();
- if (pointcloud_component != nullptr) {
- std::optional<AttributeMetaData> meta_data = pointcloud_component->attribute_get_meta_data(
- attribute_name);
- if (meta_data.has_value()) {
- data_types.append(meta_data->data_type);
- domains.append(meta_data->domain);
- }
- }
-
- const MeshComponent *mesh_component = src_geometry.get_component_for_read<MeshComponent>();
- if (mesh_component != nullptr) {
- std::optional<AttributeMetaData> meta_data = mesh_component->attribute_get_meta_data(
- attribute_name);
- if (meta_data.has_value()) {
- data_types.append(meta_data->data_type);
- domains.append(meta_data->domain);
- }
- }
-
- *r_data_type = bke::attribute_data_type_highest_complexity(data_types);
-
- if (dst_component.type() == GEO_COMPONENT_TYPE_POINT_CLOUD) {
- *r_domain = ATTR_DOMAIN_POINT;
- }
- else {
- *r_domain = bke::attribute_domain_highest_priority(domains);
- }
-}
-
-static void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
- const VArray<float3> &positions,
- const MutableSpan<int> r_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(positions.size() == r_indices.size() || r_indices.is_empty());
- BLI_assert(positions.size() == r_distances_sq.size() || r_distances_sq.is_empty());
- BLI_assert(positions.size() == r_positions.size() || r_positions.is_empty());
-
- for (const int i : positions.index_range()) {
- BVHTreeNearest nearest;
- nearest.dist_sq = FLT_MAX;
- const float3 position = positions[i];
- BLI_bvhtree_find_nearest(
- tree_data.tree, position, &nearest, tree_data.nearest_callback, &tree_data);
- if (!r_indices.is_empty()) {
- r_indices[i] = nearest.index;
- }
- if (!r_distances_sq.is_empty()) {
- r_distances_sq[i] = nearest.dist_sq;
- }
- if (!r_positions.is_empty()) {
- r_positions[i] = nearest.co;
- }
- }
-}
-
-static void get_closest_pointcloud_points(const PointCloud &pointcloud,
- const VArray<float3> &positions,
- const MutableSpan<int> r_indices,
- const MutableSpan<float> r_distances_sq)
-{
- BLI_assert(positions.size() == r_indices.size());
- BLI_assert(pointcloud.totpoint > 0);
-
- BVHTreeFromPointCloud tree_data;
- BKE_bvhtree_from_pointcloud_get(&tree_data, &pointcloud, 2);
-
- for (const int i : positions.index_range()) {
- BVHTreeNearest nearest;
- nearest.dist_sq = FLT_MAX;
- const float3 position = positions[i];
- BLI_bvhtree_find_nearest(
- tree_data.tree, position, &nearest, tree_data.nearest_callback, &tree_data);
- r_indices[i] = nearest.index;
- r_distances_sq[i] = nearest.dist_sq;
- }
-
- free_bvhtree_from_pointcloud(&tree_data);
-}
-
-static void get_closest_mesh_points(const Mesh &mesh,
- const VArray<float3> &positions,
- const MutableSpan<int> r_point_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totvert > 0);
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_VERTS, 2);
- get_closest_in_bvhtree(tree_data, positions, r_point_indices, r_distances_sq, r_positions);
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static void get_closest_mesh_edges(const Mesh &mesh,
- const VArray<float3> &positions,
- const MutableSpan<int> r_edge_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totedge > 0);
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_EDGES, 2);
- get_closest_in_bvhtree(tree_data, positions, r_edge_indices, r_distances_sq, r_positions);
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static void get_closest_mesh_looptris(const Mesh &mesh,
- const VArray<float3> &positions,
- const MutableSpan<int> r_looptri_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totpoly > 0);
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_LOOPTRI, 2);
- get_closest_in_bvhtree(tree_data, positions, r_looptri_indices, r_distances_sq, r_positions);
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static void get_closest_mesh_polygons(const Mesh &mesh,
- const VArray<float3> &positions,
- const MutableSpan<int> r_poly_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totpoly > 0);
-
- Array<int> looptri_indices(positions.size());
- get_closest_mesh_looptris(mesh, positions, looptri_indices, r_distances_sq, r_positions);
-
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
- for (const int i : positions.index_range()) {
- const MLoopTri &looptri = looptris[looptri_indices[i]];
- r_poly_indices[i] = looptri.poly;
- }
-}
-
-/* The closest corner is defined to be the closest corner on the closest face. */
-static void get_closest_mesh_corners(const Mesh &mesh,
- const VArray<float3> &positions,
- const MutableSpan<int> r_corner_indices,
- const MutableSpan<float> r_distances_sq,
- const MutableSpan<float3> r_positions)
-{
- BLI_assert(mesh.totloop > 0);
- Array<int> poly_indices(positions.size());
- get_closest_mesh_polygons(mesh, positions, poly_indices, {}, {});
-
- for (const int i : positions.index_range()) {
- const float3 position = positions[i];
- const int poly_index = poly_indices[i];
- const MPoly &poly = mesh.mpoly[poly_index];
-
- /* Find the closest vertex in the polygon. */
- float min_distance_sq = FLT_MAX;
- const MVert *closest_mvert;
- int closest_loop_index = 0;
- for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
- const int vertex_index = loop.v;
- const MVert &mvert = mesh.mvert[vertex_index];
- const float distance_sq = math::distance_squared(position, float3(mvert.co));
- if (distance_sq < min_distance_sq) {
- min_distance_sq = distance_sq;
- closest_loop_index = loop_index;
- closest_mvert = &mvert;
- }
- }
- if (!r_corner_indices.is_empty()) {
- r_corner_indices[i] = closest_loop_index;
- }
- if (!r_positions.is_empty()) {
- r_positions[i] = closest_mvert->co;
- }
- if (!r_distances_sq.is_empty()) {
- r_distances_sq[i] = min_distance_sq;
- }
- }
-}
-
-static void transfer_attribute_nearest_face_interpolated(const GeometrySet &src_geometry,
- GeometryComponent &dst_component,
- const VArray<float3> &dst_positions,
- const AttributeDomain dst_domain,
- const CustomDataType data_type,
- const StringRef src_name,
- const StringRef dst_name)
-{
- const int tot_samples = dst_positions.size();
- const MeshComponent *component = src_geometry.get_component_for_read<MeshComponent>();
- if (component == nullptr) {
- return;
- }
- const Mesh *mesh = component->get_for_read();
- if (mesh == nullptr) {
- return;
- }
- if (mesh->totpoly == 0) {
- return;
- }
-
- ReadAttributeLookup src_attribute = component->attribute_try_get_for_read(src_name, data_type);
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- dst_name, dst_domain, data_type);
- if (!src_attribute || !dst_attribute) {
- return;
- }
-
- /* Find closest points on the mesh surface. */
- Array<int> looptri_indices(tot_samples);
- Array<float3> positions(tot_samples);
- get_closest_mesh_looptris(*mesh, dst_positions, looptri_indices, {}, positions);
-
- bke::mesh_surface_sample::MeshAttributeInterpolator interp(
- mesh, IndexMask(tot_samples), positions, looptri_indices);
- interp.sample_attribute(
- src_attribute, dst_attribute, bke::mesh_surface_sample::eAttributeMapMode::INTERPOLATED);
-
- dst_attribute.save();
-}
-
-static void transfer_attribute_nearest(const GeometrySet &src_geometry,
- GeometryComponent &dst_component,
- const VArray<float3> &dst_positions,
- const AttributeDomain dst_domain,
- const CustomDataType data_type,
- const StringRef src_name,
- const StringRef dst_name)
-{
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- /* Get pointcloud data from geometry. */
- const PointCloudComponent *pointcloud_component =
- src_geometry.get_component_for_read<PointCloudComponent>();
- const PointCloud *pointcloud = pointcloud_component ? pointcloud_component->get_for_read() :
- nullptr;
-
- /* Get mesh data from geometry. */
- const MeshComponent *mesh_component = src_geometry.get_component_for_read<MeshComponent>();
- const Mesh *mesh = mesh_component ? mesh_component->get_for_read() : nullptr;
-
- const int tot_samples = dst_positions.size();
-
- Array<int> pointcloud_indices;
- Array<float> pointcloud_distances_sq;
- bool use_pointcloud = false;
-
- /* Depending on where what domain the source attribute lives, these indices are either vertex,
- * corner, edge or polygon indices. */
- Array<int> mesh_indices;
- Array<float> mesh_distances_sq;
- bool use_mesh = false;
-
- /* If there is a pointcloud, find the closest points. */
- if (pointcloud != nullptr && pointcloud->totpoint > 0) {
- if (pointcloud_component->attribute_exists(src_name)) {
- use_pointcloud = true;
- pointcloud_indices.reinitialize(tot_samples);
- pointcloud_distances_sq.reinitialize(tot_samples);
- get_closest_pointcloud_points(
- *pointcloud, dst_positions, pointcloud_indices, pointcloud_distances_sq);
- }
- }
-
- /* If there is a mesh, find the closest mesh elements. */
- if (mesh != nullptr) {
- ReadAttributeLookup src_attribute = mesh_component->attribute_try_get_for_read(src_name);
- if (src_attribute) {
- switch (src_attribute.domain) {
- case ATTR_DOMAIN_POINT: {
- if (mesh->totvert > 0) {
- use_mesh = true;
- mesh_indices.reinitialize(tot_samples);
- mesh_distances_sq.reinitialize(tot_samples);
- get_closest_mesh_points(*mesh, dst_positions, mesh_indices, mesh_distances_sq, {});
- }
- break;
- }
- case ATTR_DOMAIN_EDGE: {
- if (mesh->totedge > 0) {
- use_mesh = true;
- mesh_indices.reinitialize(tot_samples);
- mesh_distances_sq.reinitialize(tot_samples);
- get_closest_mesh_edges(*mesh, dst_positions, mesh_indices, mesh_distances_sq, {});
- }
- break;
- }
- case ATTR_DOMAIN_FACE: {
- if (mesh->totpoly > 0) {
- use_mesh = true;
- mesh_indices.reinitialize(tot_samples);
- mesh_distances_sq.reinitialize(tot_samples);
- get_closest_mesh_polygons(*mesh, dst_positions, mesh_indices, mesh_distances_sq, {});
- }
- break;
- }
- case ATTR_DOMAIN_CORNER: {
- if (mesh->totloop > 0) {
- use_mesh = true;
- mesh_indices.reinitialize(tot_samples);
- mesh_distances_sq.reinitialize(tot_samples);
- get_closest_mesh_corners(*mesh, dst_positions, mesh_indices, mesh_distances_sq, {});
- }
- break;
- }
- default: {
- break;
- }
- }
- }
- }
-
- if (!use_pointcloud && !use_mesh) {
- return;
- }
-
- OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
- dst_name, dst_domain, data_type);
- if (!dst_attribute) {
- return;
- }
-
- /* Create a buffer for intermediate values. */
- BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
-
- if (use_mesh && use_pointcloud) {
- /* When there is a mesh and a pointcloud, we still have to check whether a pointcloud point or
- * a mesh element is closer to every point. */
- ReadAttributeLookup pointcloud_src_attribute =
- pointcloud_component->attribute_try_get_for_read(src_name, data_type);
- ReadAttributeLookup mesh_src_attribute = mesh_component->attribute_try_get_for_read(src_name,
- data_type);
- for (const int i : IndexRange(tot_samples)) {
- if (pointcloud_distances_sq[i] < mesh_distances_sq[i]) {
- /* Point cloud point is closer. */
- const int index = pointcloud_indices[i];
- pointcloud_src_attribute.varray.get(index, buffer);
- dst_attribute->set_by_relocate(i, buffer);
- }
- else {
- /* Mesh element is closer. */
- const int index = mesh_indices[i];
- mesh_src_attribute.varray.get(index, buffer);
- dst_attribute->set_by_relocate(i, buffer);
- }
- }
- }
- else if (use_pointcloud) {
- /* The source geometry only has a pointcloud. */
- ReadAttributeLookup src_attribute = pointcloud_component->attribute_try_get_for_read(
- src_name, data_type);
- for (const int i : IndexRange(tot_samples)) {
- const int index = pointcloud_indices[i];
- src_attribute.varray.get(index, buffer);
- dst_attribute->set_by_relocate(i, buffer);
- }
- }
- else if (use_mesh) {
- /* The source geometry only has a mesh. */
- ReadAttributeLookup src_attribute = mesh_component->attribute_try_get_for_read(src_name,
- data_type);
- for (const int i : IndexRange(tot_samples)) {
- const int index = mesh_indices[i];
- src_attribute.varray.get(index, buffer);
- dst_attribute->set_by_relocate(i, buffer);
- }
- }
-
- dst_attribute.save();
-}
-
-static void transfer_attribute(const GeoNodeExecParams &params,
- const GeometrySet &src_geometry,
- GeometryComponent &dst_component,
- const StringRef src_name,
- const StringRef dst_name)
-{
- const NodeGeometryAttributeTransfer &storage =
- *(const NodeGeometryAttributeTransfer *)params.node().storage;
- const GeometryNodeAttributeTransferMapMode mapping = (GeometryNodeAttributeTransferMapMode)
- storage.mapping;
- const AttributeDomain input_domain = (AttributeDomain)storage.domain;
-
- CustomDataType data_type;
- AttributeDomain auto_domain;
- get_result_domain_and_data_type(src_geometry, dst_component, src_name, &data_type, &auto_domain);
- const AttributeDomain dst_domain = (input_domain == ATTR_DOMAIN_AUTO) ? auto_domain :
- input_domain;
-
- VArray<float3> dst_positions = dst_component.attribute_get_for_read<float3>(
- "position", dst_domain, {0, 0, 0});
-
- switch (mapping) {
- case GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {
- transfer_attribute_nearest_face_interpolated(
- src_geometry, dst_component, dst_positions, dst_domain, data_type, src_name, dst_name);
- break;
- }
- case GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER_NEAREST: {
- transfer_attribute_nearest(
- src_geometry, dst_component, dst_positions, dst_domain, data_type, src_name, dst_name);
- break;
- }
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet dst_geometry_set = params.extract_input<GeometrySet>("Geometry");
- GeometrySet src_geometry_set = params.extract_input<GeometrySet>("Source Geometry");
- const std::string src_attribute_name = params.extract_input<std::string>("Source");
- const std::string dst_attribute_name = params.extract_input<std::string>("Destination");
-
- if (src_attribute_name.empty() || dst_attribute_name.empty()) {
- params.set_default_remaining_outputs();
- return;
- }
-
- dst_geometry_set = geometry::realize_instances_legacy(dst_geometry_set);
- src_geometry_set = geometry::realize_instances_legacy(src_geometry_set);
-
- if (dst_geometry_set.has<MeshComponent>()) {
- transfer_attribute(params,
- src_geometry_set,
- dst_geometry_set.get_component_for_write<MeshComponent>(),
- src_attribute_name,
- dst_attribute_name);
- }
- if (dst_geometry_set.has<PointCloudComponent>()) {
- transfer_attribute(params,
- src_geometry_set,
- dst_geometry_set.get_component_for_write<PointCloudComponent>(),
- src_attribute_name,
- dst_attribute_name);
- }
-
- params.set_output("Geometry", dst_geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_transfer_cc
-
-void register_node_type_geo_legacy_attribute_transfer()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_transfer_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_ATTRIBUTE_TRANSFER, "Attribute Transfer", NODE_CLASS_ATTRIBUTE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(&ntype,
- "NodeGeometryAttributeTransfer",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc
deleted file mode 100644
index 83ece031dd2..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc
+++ /dev/null
@@ -1,559 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_math_base_safe.h"
-#include "BLI_task.hh"
-
-#include "RNA_enum_types.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "NOD_math_functions.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_attribute_vector_math_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("A"));
- b.add_input<decl::Vector>(N_("A"), "A_001");
- b.add_input<decl::String>(N_("B"));
- b.add_input<decl::Vector>(N_("B"), "B_001");
- b.add_input<decl::Float>(N_("B"), "B_002");
- b.add_input<decl::String>(N_("C"));
- b.add_input<decl::Vector>(N_("C"), "C_001");
- b.add_input<decl::Float>(N_("C"), "C_002");
- b.add_input<decl::String>(N_("Result"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static bool operation_use_input_b(const NodeVectorMathOperation operation)
-{
- return !ELEM(operation,
- NODE_VECTOR_MATH_NORMALIZE,
- NODE_VECTOR_MATH_FLOOR,
- NODE_VECTOR_MATH_CEIL,
- NODE_VECTOR_MATH_FRACTION,
- NODE_VECTOR_MATH_ABSOLUTE,
- NODE_VECTOR_MATH_SINE,
- NODE_VECTOR_MATH_COSINE,
- NODE_VECTOR_MATH_TANGENT,
- NODE_VECTOR_MATH_LENGTH);
-}
-
-static bool operation_use_input_c(const NodeVectorMathOperation operation)
-{
- return ELEM(operation,
- NODE_VECTOR_MATH_WRAP,
- NODE_VECTOR_MATH_REFRACT,
- NODE_VECTOR_MATH_FACEFORWARD,
- NODE_VECTOR_MATH_MULTIPLY_ADD);
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- bNode *node = (bNode *)ptr->data;
- const NodeAttributeVectorMath &node_storage = *(NodeAttributeVectorMath *)node->storage;
- const NodeVectorMathOperation operation = (const NodeVectorMathOperation)node_storage.operation;
-
- uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
-
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "input_type_a", 0, IFACE_("A"), ICON_NONE);
- if (operation_use_input_b(operation)) {
- uiItemR(layout, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
- }
- if (operation_use_input_c(operation)) {
- uiItemR(layout, ptr, "input_type_c", 0, IFACE_("C"), ICON_NONE);
- }
-}
-
-static CustomDataType operation_get_read_type_b(const NodeVectorMathOperation operation)
-{
- if (operation == NODE_VECTOR_MATH_SCALE) {
- return CD_PROP_FLOAT;
- }
- return CD_PROP_FLOAT3;
-}
-
-static CustomDataType operation_get_read_type_c(const NodeVectorMathOperation operation)
-{
- if (operation == NODE_VECTOR_MATH_REFRACT) {
- return CD_PROP_FLOAT;
- }
- return CD_PROP_FLOAT3;
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeAttributeVectorMath *data = MEM_cnew<NodeAttributeVectorMath>(__func__);
-
- data->operation = NODE_VECTOR_MATH_ADD;
- data->input_type_a = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- data->input_type_b = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node->storage = data;
-}
-
-static CustomDataType operation_get_result_type(const NodeVectorMathOperation operation)
-{
- switch (operation) {
- case NODE_VECTOR_MATH_ADD:
- case NODE_VECTOR_MATH_SUBTRACT:
- case NODE_VECTOR_MATH_MULTIPLY:
- case NODE_VECTOR_MATH_DIVIDE:
- case NODE_VECTOR_MATH_CROSS_PRODUCT:
- case NODE_VECTOR_MATH_PROJECT:
- case NODE_VECTOR_MATH_REFLECT:
- case NODE_VECTOR_MATH_SCALE:
- case NODE_VECTOR_MATH_NORMALIZE:
- case NODE_VECTOR_MATH_SNAP:
- case NODE_VECTOR_MATH_FLOOR:
- case NODE_VECTOR_MATH_CEIL:
- case NODE_VECTOR_MATH_MODULO:
- case NODE_VECTOR_MATH_FRACTION:
- case NODE_VECTOR_MATH_ABSOLUTE:
- case NODE_VECTOR_MATH_MINIMUM:
- case NODE_VECTOR_MATH_MAXIMUM:
- case NODE_VECTOR_MATH_WRAP:
- case NODE_VECTOR_MATH_SINE:
- case NODE_VECTOR_MATH_COSINE:
- case NODE_VECTOR_MATH_TANGENT:
- case NODE_VECTOR_MATH_REFRACT:
- case NODE_VECTOR_MATH_FACEFORWARD:
- case NODE_VECTOR_MATH_MULTIPLY_ADD:
- return CD_PROP_FLOAT3;
- case NODE_VECTOR_MATH_DOT_PRODUCT:
- case NODE_VECTOR_MATH_DISTANCE:
- case NODE_VECTOR_MATH_LENGTH:
- return CD_PROP_FLOAT;
- }
-
- BLI_assert(false);
- return CD_PROP_FLOAT3;
-}
-
-static void geo_node_vector_math_label(const bNodeTree *UNUSED(ntree),
- const bNode *node,
- char *label,
- int maxlen)
-{
- NodeAttributeMath &node_storage = *(NodeAttributeMath *)node->storage;
- const char *name;
- bool enum_label = RNA_enum_name(rna_enum_node_vec_math_items, node_storage.operation, &name);
- if (!enum_label) {
- name = "Unknown";
- }
- BLI_snprintf(label, maxlen, IFACE_("Vector %s"), IFACE_(name));
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- const NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
- const NodeVectorMathOperation operation = (const NodeVectorMathOperation)node_storage->operation;
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "A", (GeometryNodeAttributeInputMode)node_storage->input_type_a);
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "B",
- (GeometryNodeAttributeInputMode)node_storage->input_type_b,
- operation_use_input_b(operation));
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "C",
- (GeometryNodeAttributeInputMode)node_storage->input_type_c,
- operation_use_input_c(operation));
-}
-
-static void do_math_operation_fl3_fl3_to_fl3(const VArray<float3> &input_a,
- const VArray<float3> &input_b,
- const VMutableArray<float3> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VArray_Span<float3> span_b{input_b};
- VMutableArray_Span<float3> span_result{result, false};
-
- bool success = try_dispatch_float_math_fl3_fl3_to_fl3(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 a = span_a[i];
- const float3 b = span_b[i];
- const float3 out = math_function(a, b);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation_fl3_fl3_fl3_to_fl3(const VArray<float3> &input_a,
- const VArray<float3> &input_b,
- const VArray<float3> &input_c,
- const VMutableArray<float3> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VArray_Span<float3> span_b{input_b};
- VArray_Span<float3> span_c{input_c};
- VMutableArray_Span<float3> span_result{result};
-
- bool success = try_dispatch_float_math_fl3_fl3_fl3_to_fl3(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 a = span_a[i];
- const float3 b = span_b[i];
- const float3 c = span_c[i];
- const float3 out = math_function(a, b, c);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation_fl3_fl3_fl_to_fl3(const VArray<float3> &input_a,
- const VArray<float3> &input_b,
- const VArray<float> &input_c,
- const VMutableArray<float3> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VArray_Span<float3> span_b{input_b};
- VArray_Span<float> span_c{input_c};
- VMutableArray_Span<float3> span_result{result, false};
-
- bool success = try_dispatch_float_math_fl3_fl3_fl_to_fl3(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 a = span_a[i];
- const float3 b = span_b[i];
- const float c = span_c[i];
- const float3 out = math_function(a, b, c);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation_fl3_fl3_to_fl(const VArray<float3> &input_a,
- const VArray<float3> &input_b,
- const VMutableArray<float> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VArray_Span<float3> span_b{input_b};
- VMutableArray_Span<float> span_result{result, false};
-
- bool success = try_dispatch_float_math_fl3_fl3_to_fl(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 a = span_a[i];
- const float3 b = span_b[i];
- const float out = math_function(a, b);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation_fl3_fl_to_fl3(const VArray<float3> &input_a,
- const VArray<float> &input_b,
- const VMutableArray<float3> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VArray_Span<float> span_b{input_b};
- VMutableArray_Span<float3> span_result{result, false};
-
- bool success = try_dispatch_float_math_fl3_fl_to_fl3(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 a = span_a[i];
- const float b = span_b[i];
- const float3 out = math_function(a, b);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation_fl3_to_fl3(const VArray<float3> &input_a,
- const VMutableArray<float3> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VMutableArray_Span<float3> span_result{result, false};
-
- bool success = try_dispatch_float_math_fl3_to_fl3(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 in = span_a[i];
- const float3 out = math_function(in);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static void do_math_operation_fl3_to_fl(const VArray<float3> &input_a,
- const VMutableArray<float> &result,
- const NodeVectorMathOperation operation)
-{
- const int size = input_a.size();
-
- VArray_Span<float3> span_a{input_a};
- VMutableArray_Span<float> span_result{result, false};
-
- bool success = try_dispatch_float_math_fl3_to_fl(
- operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) {
- threading::parallel_for(IndexRange(size), 512, [&](IndexRange range) {
- for (const int i : range) {
- const float3 in = span_a[i];
- const float out = math_function(in);
- span_result[i] = out;
- }
- });
- });
-
- span_result.save();
-
- /* The operation is not supported by this node currently. */
- BLI_assert(success);
- UNUSED_VARS_NDEBUG(success);
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- const NodeVectorMathOperation operation,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> result_info = component.attribute_get_meta_data(result_name);
- if (result_info) {
- return result_info->domain;
- }
-
- /* Otherwise use the highest priority domain from existing input attributes, or the default. */
- const AttributeDomain default_domain = ATTR_DOMAIN_POINT;
- if (operation_use_input_b(operation)) {
- if (operation_use_input_c(operation)) {
- return params.get_highest_priority_input_domain({"A", "B", "C"}, component, default_domain);
- }
- return params.get_highest_priority_input_domain({"A", "B"}, component, default_domain);
- }
- return params.get_highest_priority_input_domain({"A"}, component, default_domain);
-}
-
-static void attribute_vector_math_calc(GeometryComponent &component,
- const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- const NodeAttributeVectorMath *node_storage = (const NodeAttributeVectorMath *)node.storage;
- const NodeVectorMathOperation operation = (NodeVectorMathOperation)node_storage->operation;
- const std::string result_name = params.get_input<std::string>("Result");
-
- /* The number and type of the input attribute depend on the operation. */
- const CustomDataType read_type_a = CD_PROP_FLOAT3;
- const bool use_input_b = operation_use_input_b(operation);
- const CustomDataType read_type_b = operation_get_read_type_b(operation);
- const bool use_input_c = operation_use_input_c(operation);
- const CustomDataType read_type_c = operation_get_read_type_c(operation);
-
- /* The result domain is always point for now. */
- const CustomDataType result_type = operation_get_result_type(operation);
- const AttributeDomain result_domain = get_result_domain(
- component, params, operation, result_name);
-
- GVArray attribute_a = params.get_input_attribute(
- "A", component, result_domain, read_type_a, nullptr);
- if (!attribute_a) {
- return;
- }
- GVArray attribute_b;
- GVArray attribute_c;
- if (use_input_b) {
- attribute_b = params.get_input_attribute("B", component, result_domain, read_type_b, nullptr);
- if (!attribute_b) {
- return;
- }
- }
- if (use_input_c) {
- attribute_c = params.get_input_attribute("C", component, result_domain, read_type_c, nullptr);
- if (!attribute_c) {
- return;
- }
- }
-
- /* Get result attribute first, in case it has to overwrite one of the existing attributes. */
- OutputAttribute attribute_result = component.attribute_try_get_for_output_only(
- result_name, result_domain, result_type);
- if (!attribute_result) {
- return;
- }
-
- switch (operation) {
- case NODE_VECTOR_MATH_ADD:
- case NODE_VECTOR_MATH_SUBTRACT:
- case NODE_VECTOR_MATH_MULTIPLY:
- case NODE_VECTOR_MATH_DIVIDE:
- case NODE_VECTOR_MATH_CROSS_PRODUCT:
- case NODE_VECTOR_MATH_PROJECT:
- case NODE_VECTOR_MATH_REFLECT:
- case NODE_VECTOR_MATH_SNAP:
- case NODE_VECTOR_MATH_MODULO:
- case NODE_VECTOR_MATH_MINIMUM:
- case NODE_VECTOR_MATH_MAXIMUM:
- do_math_operation_fl3_fl3_to_fl3(attribute_a.typed<float3>(),
- attribute_b.typed<float3>(),
- attribute_result.varray().typed<float3>(),
- operation);
- break;
- case NODE_VECTOR_MATH_DOT_PRODUCT:
- case NODE_VECTOR_MATH_DISTANCE:
- do_math_operation_fl3_fl3_to_fl(attribute_a.typed<float3>(),
- attribute_b.typed<float3>(),
- attribute_result.varray().typed<float>(),
- operation);
- break;
- case NODE_VECTOR_MATH_LENGTH:
- do_math_operation_fl3_to_fl(
- attribute_a.typed<float3>(), attribute_result.varray().typed<float>(), operation);
- break;
- case NODE_VECTOR_MATH_SCALE:
- do_math_operation_fl3_fl_to_fl3(attribute_a.typed<float3>(),
- attribute_b.typed<float>(),
- attribute_result.varray().typed<float3>(),
- operation);
- break;
- case NODE_VECTOR_MATH_NORMALIZE:
- case NODE_VECTOR_MATH_FLOOR:
- case NODE_VECTOR_MATH_CEIL:
- case NODE_VECTOR_MATH_FRACTION:
- case NODE_VECTOR_MATH_ABSOLUTE:
- case NODE_VECTOR_MATH_SINE:
- case NODE_VECTOR_MATH_COSINE:
- case NODE_VECTOR_MATH_TANGENT:
- do_math_operation_fl3_to_fl3(
- attribute_a.typed<float3>(), attribute_result.varray().typed<float3>(), operation);
- break;
- case NODE_VECTOR_MATH_WRAP:
- case NODE_VECTOR_MATH_FACEFORWARD:
- case NODE_VECTOR_MATH_MULTIPLY_ADD:
- do_math_operation_fl3_fl3_fl3_to_fl3(attribute_a.typed<float3>(),
- attribute_b.typed<float3>(),
- attribute_c.typed<float3>(),
- attribute_result.varray().typed<float3>(),
- operation);
- break;
- case NODE_VECTOR_MATH_REFRACT:
- do_math_operation_fl3_fl3_fl_to_fl3(attribute_a.typed<float3>(),
- attribute_b.typed<float3>(),
- attribute_c.typed<float>(),
- attribute_result.varray().typed<float3>(),
- operation);
- break;
- }
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- attribute_vector_math_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- attribute_vector_math_calc(geometry_set.get_component_for_write<PointCloudComponent>(),
- params);
- }
- if (geometry_set.has<CurveComponent>()) {
- attribute_vector_math_calc(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_vector_math_cc
-
-void register_node_type_geo_attribute_vector_math()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_vector_math_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype,
- GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_MATH,
- "Attribute Vector Math",
- NODE_CLASS_ATTRIBUTE);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- ntype.labelfunc = file_ns::geo_node_vector_math_label;
- node_type_update(&ntype, file_ns::node_update);
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(
- &ntype, "NodeAttributeVectorMath", node_free_standard_storage, node_copy_standard_storage);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc
deleted file mode 100644
index ccf1bdb0a19..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "node_geometry_util.hh"
-
-#include "BLI_task.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-namespace blender::nodes::node_geo_legacy_attribute_vector_rotate_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Vector"));
- b.add_input<decl::Vector>(N_("Vector"), "Vector_001").min(0.0f).max(1.0f).hide_value();
- b.add_input<decl::String>(N_("Center"));
- b.add_input<decl::Vector>(N_("Center"), "Center_001").subtype(PROP_XYZ);
- b.add_input<decl::String>(N_("Axis"));
- b.add_input<decl::Vector>(N_("Axis"), "Axis_001").min(-1.0f).max(1.0f).subtype(PROP_XYZ);
- b.add_input<decl::String>(N_("Angle"));
- b.add_input<decl::Float>(N_("Angle"), "Angle_001").subtype(PROP_ANGLE);
- b.add_input<decl::String>(N_("Rotation"));
- b.add_input<decl::Vector>(N_("Rotation"), "Rotation_001").subtype(PROP_EULER);
- b.add_input<decl::Bool>(N_("Invert"));
- b.add_input<decl::String>(N_("Result"));
-
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- bNode *node = (bNode *)ptr->data;
- const NodeAttributeVectorRotate &node_storage = *(NodeAttributeVectorRotate *)node->storage;
- const GeometryNodeAttributeVectorRotateMode mode = (const GeometryNodeAttributeVectorRotateMode)
- node_storage.mode;
-
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiLayout *column = uiLayoutColumn(layout, false);
-
- uiItemR(column, ptr, "rotation_mode", 0, "", ICON_NONE);
-
- uiItemR(column, ptr, "input_type_vector", 0, IFACE_("Vector"), ICON_NONE);
- uiItemR(column, ptr, "input_type_center", 0, IFACE_("Center"), ICON_NONE);
- if (mode == GEO_NODE_VECTOR_ROTATE_TYPE_AXIS) {
- uiItemR(column, ptr, "input_type_axis", 0, IFACE_("Axis"), ICON_NONE);
- }
- if (mode != GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
- uiItemR(column, ptr, "input_type_angle", 0, IFACE_("Angle"), ICON_NONE);
- }
- if (mode == GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
- uiItemR(column, ptr, "input_type_rotation", 0, IFACE_("Rotation"), ICON_NONE);
- }
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- const NodeAttributeVectorRotate *node_storage = (NodeAttributeVectorRotate *)node->storage;
- const GeometryNodeAttributeVectorRotateMode mode = (const GeometryNodeAttributeVectorRotateMode)
- node_storage->mode;
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Vector", (GeometryNodeAttributeInputMode)node_storage->input_type_vector);
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Center", (GeometryNodeAttributeInputMode)node_storage->input_type_center);
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Axis",
- (GeometryNodeAttributeInputMode)node_storage->input_type_axis,
- (mode == GEO_NODE_VECTOR_ROTATE_TYPE_AXIS));
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Angle",
- (GeometryNodeAttributeInputMode)node_storage->input_type_angle,
- (mode != GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Rotation",
- (GeometryNodeAttributeInputMode)node_storage->input_type_rotation,
- (mode == GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ));
-}
-
-static float3 vector_rotate_around_axis(const float3 vector,
- const float3 center,
- const float3 axis,
- const float angle)
-{
- float3 result = vector - center;
- float mat[3][3];
- axis_angle_to_mat3(mat, axis, angle);
- mul_m3_v3(mat, result);
- return result + center;
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeAttributeVectorRotate *node_storage = MEM_cnew<NodeAttributeVectorRotate>(__func__);
-
- node_storage->mode = GEO_NODE_VECTOR_ROTATE_TYPE_AXIS;
- node_storage->input_type_vector = GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE;
- node_storage->input_type_center = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- node_storage->input_type_axis = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- node_storage->input_type_angle = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node_storage->input_type_rotation = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
-
- node->storage = node_storage;
-}
-
-static float3 vector_rotate_euler(const float3 vector,
- const float3 center,
- const float3 rotation,
- const bool invert)
-{
- float mat[3][3];
- float3 result = vector - center;
- eul_to_mat3(mat, rotation);
- if (invert) {
- invert_m3(mat);
- }
- mul_m3_v3(mat, result);
- return result + center;
-}
-
-static void do_vector_rotate_around_axis(const VArray<float3> &vector,
- const VArray<float3> &center,
- const VArray<float3> &axis,
- const VArray<float> &angle,
- MutableSpan<float3> results,
- const bool invert)
-{
- VArray_Span<float3> span_vector{vector};
- VArray_Span<float3> span_center{center};
- VArray_Span<float3> span_axis{axis};
- VArray_Span<float> span_angle{angle};
-
- threading::parallel_for(IndexRange(results.size()), 1024, [&](IndexRange range) {
- for (const int i : range) {
- float angle = (invert) ? -span_angle[i] : span_angle[i];
- results[i] = vector_rotate_around_axis(span_vector[i], span_center[i], span_axis[i], angle);
- }
- });
-}
-
-static void do_vector_rotate_around_fixed_axis(const VArray<float3> &vector,
- const VArray<float3> &center,
- const float3 axis,
- const VArray<float> &angle,
- MutableSpan<float3> results,
- const bool invert)
-{
- VArray_Span<float3> span_vector{vector};
- VArray_Span<float3> span_center{center};
- VArray_Span<float> span_angle{angle};
-
- threading::parallel_for(IndexRange(results.size()), 1024, [&](IndexRange range) {
- for (const int i : range) {
- float angle = (invert) ? -span_angle[i] : span_angle[i];
- results[i] = vector_rotate_around_axis(span_vector[i], span_center[i], axis, angle);
- }
- });
-}
-
-static void do_vector_rotate_euler(const VArray<float3> &vector,
- const VArray<float3> &center,
- const VArray<float3> &rotation,
- MutableSpan<float3> results,
- const bool invert)
-{
- VArray_Span<float3> span_vector{vector};
- VArray_Span<float3> span_center{center};
- VArray_Span<float3> span_rotation{rotation};
-
- threading::parallel_for(IndexRange(results.size()), 1024, [&](IndexRange range) {
- for (const int i : range) {
- results[i] = vector_rotate_euler(span_vector[i], span_center[i], span_rotation[i], invert);
- }
- });
-}
-
-static AttributeDomain get_result_domain(const GeometryComponent &component,
- const GeoNodeExecParams &params,
- StringRef result_name)
-{
- /* Use the domain of the result attribute if it already exists. */
- std::optional<AttributeMetaData> meta_data = component.attribute_get_meta_data(result_name);
- if (meta_data) {
- return meta_data->domain;
- }
-
- /* Otherwise use the highest priority domain from existing input attributes, or the default. */
- const AttributeDomain default_domain = ATTR_DOMAIN_POINT;
- return params.get_highest_priority_input_domain({"Vector", "Center"}, component, default_domain);
-}
-
-static void execute_on_component(const GeoNodeExecParams &params, GeometryComponent &component)
-{
- const bNode &node = params.node();
- const NodeAttributeVectorRotate *node_storage = (const NodeAttributeVectorRotate *)node.storage;
- const GeometryNodeAttributeVectorRotateMode mode = (GeometryNodeAttributeVectorRotateMode)
- node_storage->mode;
- const std::string result_name = params.get_input<std::string>("Result");
- const AttributeDomain result_domain = get_result_domain(component, params, result_name);
- const bool invert = params.get_input<bool>("Invert");
-
- GVArray attribute_vector = params.get_input_attribute(
- "Vector", component, result_domain, CD_PROP_FLOAT3, nullptr);
- if (!attribute_vector) {
- return;
- }
- GVArray attribute_center = params.get_input_attribute(
- "Center", component, result_domain, CD_PROP_FLOAT3, nullptr);
- if (!attribute_center) {
- return;
- }
-
- OutputAttribute attribute_result = component.attribute_try_get_for_output_only(
- result_name, result_domain, CD_PROP_FLOAT3);
- if (!attribute_result) {
- return;
- }
-
- if (mode == GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ) {
- GVArray attribute_rotation = params.get_input_attribute(
- "Rotation", component, result_domain, CD_PROP_FLOAT3, nullptr);
- if (!attribute_rotation) {
- return;
- }
- do_vector_rotate_euler(attribute_vector.typed<float3>(),
- attribute_center.typed<float3>(),
- attribute_rotation.typed<float3>(),
- attribute_result.as_span<float3>(),
- invert);
- attribute_result.save();
- return;
- }
-
- GVArray attribute_angle = params.get_input_attribute(
- "Angle", component, result_domain, CD_PROP_FLOAT, nullptr);
- if (!attribute_angle) {
- return;
- }
-
- switch (mode) {
- case GEO_NODE_VECTOR_ROTATE_TYPE_AXIS: {
- GVArray attribute_axis = params.get_input_attribute(
- "Axis", component, result_domain, CD_PROP_FLOAT3, nullptr);
- if (!attribute_axis) {
- return;
- }
- do_vector_rotate_around_axis(attribute_vector.typed<float3>(),
- attribute_center.typed<float3>(),
- attribute_axis.typed<float3>(),
- attribute_angle.typed<float>(),
- attribute_result.as_span<float3>(),
- invert);
- } break;
- case GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_X:
- do_vector_rotate_around_fixed_axis(attribute_vector.typed<float3>(),
- attribute_center.typed<float3>(),
- float3(1.0f, 0.0f, 0.0f),
- attribute_angle.typed<float>(),
- attribute_result.as_span<float3>(),
- invert);
- break;
- case GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_Y:
- do_vector_rotate_around_fixed_axis(attribute_vector.typed<float3>(),
- attribute_center.typed<float3>(),
- float3(0.0f, 1.0f, 0.0f),
- attribute_angle.typed<float>(),
- attribute_result.as_span<float3>(),
- invert);
-
- break;
- case GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_Z:
- do_vector_rotate_around_fixed_axis(attribute_vector.typed<float3>(),
- attribute_center.typed<float3>(),
- float3(0.0f, 0.0f, 1.0f),
- attribute_angle.typed<float>(),
- attribute_result.as_span<float3>(),
- invert);
-
- break;
- case GEO_NODE_VECTOR_ROTATE_TYPE_EULER_XYZ:
- /* Euler is handled before other modes to avoid processing the unavailable angle socket. */
- BLI_assert_unreachable();
- break;
- }
- attribute_result.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
- }
- if (geometry_set.has<PointCloudComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<PointCloudComponent>());
- }
- if (geometry_set.has<CurveComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<CurveComponent>());
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_attribute_vector_rotate_cc
-
-void register_node_type_geo_attribute_vector_rotate()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_attribute_vector_rotate_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype,
- GEO_NODE_LEGACY_ATTRIBUTE_VECTOR_ROTATE,
- "Attribute Vector Rotate",
- NODE_CLASS_ATTRIBUTE);
- node_type_update(&ntype, file_ns::node_update);
- node_type_init(&ntype, file_ns::node_init);
- node_type_size(&ntype, 165, 100, 600);
- node_type_storage(
- &ntype, "NodeAttributeVectorRotate", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- ntype.declare = file_ns::node_declare;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc
deleted file mode 100644
index 0980c2d6e72..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-#include "BLI_timeit.hh"
-
-#include "BKE_pointcloud.h"
-#include "BKE_spline.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_curve_endpoints_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_output<decl::Geometry>(N_("Start Points"));
- b.add_output<decl::Geometry>(N_("End Points"));
-}
-
-/**
- * Evaluate splines in parallel to speed up the rest of the node's execution.
- */
-static void evaluate_splines(Span<SplinePtr> splines)
-{
- threading::parallel_for_each(splines, [](const SplinePtr &spline) {
- /* These functions fill the corresponding caches on each spline. */
- spline->evaluated_positions();
- spline->evaluated_tangents();
- spline->evaluated_normals();
- spline->evaluated_lengths();
- });
-}
-
-/**
- * \note Use attributes from the curve component rather than the attribute data directly on the
- * attribute storage to allow reading the virtual spline attributes like "cyclic" and "resolution".
- */
-static void copy_spline_domain_attributes(const CurveComponent &curve_component,
- Span<int> offsets,
- PointCloudComponent &points)
-{
- curve_component.attribute_foreach(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- if (meta_data.domain != ATTR_DOMAIN_CURVE) {
- return true;
- }
- GVArray spline_attribute = curve_component.attribute_get_for_read(
- attribute_id, ATTR_DOMAIN_CURVE, meta_data.data_type);
-
- OutputAttribute result_attribute = points.attribute_try_get_for_output_only(
- attribute_id, ATTR_DOMAIN_POINT, meta_data.data_type);
- GMutableSpan result = result_attribute.as_span();
-
- /* Only copy the attributes of splines in the offsets. */
- for (const int i : offsets.index_range()) {
- spline_attribute.get(offsets[i], result[i]);
- }
-
- result_attribute.save();
- return true;
- });
-}
-
-/**
- * Get the offsets for the splines whose endpoints we want to output.
- * Filter those which are cyclic, or that evaluate to empty.
- * Could be easily adapted to include a selection argument to support attribute selection.
- */
-static blender::Vector<int> get_endpoint_spline_offsets(Span<SplinePtr> splines)
-{
- blender::Vector<int> spline_offsets;
- spline_offsets.reserve(splines.size());
-
- for (const int i : splines.index_range()) {
- if (!(splines[i]->is_cyclic() || splines[i]->evaluated_points_size() == 0)) {
- spline_offsets.append(i);
- }
- }
-
- return spline_offsets;
-}
-
-/**
- * Copy the endpoint attributes from the correct positions at the splines at the offsets to
- * the start and end attributes.
- */
-static void copy_endpoint_attributes(Span<SplinePtr> splines,
- Span<int> offsets,
- CurveToPointsResults &start_data,
- CurveToPointsResults &end_data)
-{
- threading::parallel_for(offsets.index_range(), 64, [&](IndexRange range) {
- for (const int i : range) {
- const Spline &spline = *splines[offsets[i]];
-
- /* Copy the start and end point data over. */
- start_data.positions[i] = spline.evaluated_positions().first();
- start_data.tangents[i] = spline.evaluated_tangents().first();
- start_data.normals[i] = spline.evaluated_normals().first();
- start_data.radii[i] = spline.radii().first();
- start_data.tilts[i] = spline.tilts().first();
-
- end_data.positions[i] = spline.evaluated_positions().last();
- end_data.tangents[i] = spline.evaluated_tangents().last();
- end_data.normals[i] = spline.evaluated_normals().last();
- end_data.radii[i] = spline.radii().last();
- end_data.tilts[i] = spline.tilts().last();
-
- /* Copy the point attribute data over. */
- for (const auto item : start_data.point_attributes.items()) {
- const AttributeIDRef attribute_id = item.key;
- GMutableSpan point_span = item.value;
-
- BLI_assert(spline.attributes.get_for_read(attribute_id));
- GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
- spline_span.type().copy_assign(spline_span[0], point_span[i]);
- }
-
- for (const auto item : end_data.point_attributes.items()) {
- const AttributeIDRef attribute_id = item.key;
- GMutableSpan point_span = item.value;
-
- BLI_assert(spline.attributes.get_for_read(attribute_id));
- GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
- spline_span.type().copy_assign(spline_span[spline.size() - 1], point_span[i]);
- }
- }
- });
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (!geometry_set.has_curves()) {
- params.set_default_remaining_outputs();
- return;
- }
-
- const CurveComponent &curve_component = *geometry_set.get_component_for_read<CurveComponent>();
- const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component.get_for_read());
- const Span<SplinePtr> splines = curve->splines();
- curve->assert_valid_point_attributes();
-
- evaluate_splines(splines);
-
- const Vector<int> offsets = get_endpoint_spline_offsets(splines);
- const int total_size = offsets.size();
-
- if (total_size == 0) {
- params.set_default_remaining_outputs();
- return;
- }
-
- GeometrySet start_result = GeometrySet::create_with_pointcloud(
- BKE_pointcloud_new_nomain(total_size));
- GeometrySet end_result = GeometrySet::create_with_pointcloud(
- BKE_pointcloud_new_nomain(total_size));
- PointCloudComponent &start_point_component =
- start_result.get_component_for_write<PointCloudComponent>();
- PointCloudComponent &end_point_component =
- end_result.get_component_for_write<PointCloudComponent>();
-
- CurveToPointsResults start_attributes = curve_to_points_create_result_attributes(
- start_point_component, *curve);
- CurveToPointsResults end_attributes = curve_to_points_create_result_attributes(
- end_point_component, *curve);
-
- copy_endpoint_attributes(splines, offsets.as_span(), start_attributes, end_attributes);
- copy_spline_domain_attributes(curve_component, offsets.as_span(), start_point_component);
- curve_create_default_rotation_attribute(
- start_attributes.tangents, start_attributes.normals, start_attributes.rotations);
- curve_create_default_rotation_attribute(
- end_attributes.tangents, end_attributes.normals, end_attributes.rotations);
-
- /* The default radius is way too large for points, divide by 10. */
- for (float &radius : start_attributes.radii) {
- radius *= 0.1f;
- }
- for (float &radius : end_attributes.radii) {
- radius *= 0.1f;
- }
-
- params.set_output("Start Points", std::move(start_result));
- params.set_output("End Points", std::move(end_result));
-}
-
-} // namespace blender::nodes::node_geo_legacy_curve_endpoints_cc
-
-void register_node_type_geo_legacy_curve_endpoints()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_endpoints_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_CURVE_ENDPOINTS, "Curve Endpoints", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc
deleted file mode 100644
index 2c801642bd7..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-
-#include "BKE_spline.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_curve_reverse_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Curve"));
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Curve"));
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- geometry_set = geometry::realize_instances_legacy(geometry_set);
- if (!geometry_set.has_curves()) {
- params.set_output("Curve", geometry_set);
- return;
- }
-
- /* Retrieve data for write access so we can avoid new allocations for the reversed data. */
- CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
- std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component.get_for_read());
- MutableSpan<SplinePtr> splines = curve->splines();
-
- const std::string selection_name = params.extract_input<std::string>("Selection");
- VArray<bool> selection = curve_component.attribute_get_for_read(
- selection_name, ATTR_DOMAIN_CURVE, true);
-
- threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
- for (const int i : range) {
- if (selection[i]) {
- splines[i]->reverse();
- }
- }
- });
-
- geometry_set.replace_curves(curve_eval_to_curves(*curve));
-
- params.set_output("Curve", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_curve_reverse_cc
-
-void register_node_type_geo_legacy_curve_reverse()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_reverse_cc;
-
- static bNodeType ntype;
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_CURVE_REVERSE, "Curve Reverse", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc
deleted file mode 100644
index 729ccca5f04..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-
-#include "BKE_spline.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_curve_select_by_handle_type_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "handle_type", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryCurveSelectHandles *data = MEM_cnew<NodeGeometryCurveSelectHandles>(__func__);
-
- data->handle_type = GEO_NODE_CURVE_HANDLE_AUTO;
- data->mode = GEO_NODE_CURVE_HANDLE_LEFT | GEO_NODE_CURVE_HANDLE_RIGHT;
- node->storage = data;
-}
-
-static HandleType handle_type_from_input_type(const GeometryNodeCurveHandleType type)
-{
- switch (type) {
- case GEO_NODE_CURVE_HANDLE_AUTO:
- return BEZIER_HANDLE_AUTO;
- case GEO_NODE_CURVE_HANDLE_ALIGN:
- return BEZIER_HANDLE_ALIGN;
- case GEO_NODE_CURVE_HANDLE_FREE:
- return BEZIER_HANDLE_FREE;
- case GEO_NODE_CURVE_HANDLE_VECTOR:
- return BEZIER_HANDLE_VECTOR;
- }
- BLI_assert_unreachable();
- return BEZIER_HANDLE_AUTO;
-}
-
-static void select_curve_by_handle_type(const CurveEval &curve,
- const HandleType type,
- const GeometryNodeCurveHandleMode mode,
- const MutableSpan<bool> r_selection)
-{
- const Array<int> offsets = curve.control_point_offsets();
- Span<SplinePtr> splines = curve.splines();
- threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
- for (const int i_spline : range) {
- const Spline &spline = *splines[i_spline];
- if (spline.type() == CURVE_TYPE_BEZIER) {
- const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(spline);
- Span<int8_t> types_left = bezier_spline.handle_types_left();
- Span<int8_t> types_right = bezier_spline.handle_types_right();
- for (const int i_point : IndexRange(bezier_spline.size())) {
- r_selection[offsets[i_spline] + i_point] = (mode & GEO_NODE_CURVE_HANDLE_LEFT &&
- types_left[i_point] == type) ||
- (mode & GEO_NODE_CURVE_HANDLE_RIGHT &&
- types_right[i_point] == type);
- }
- }
- else {
- r_selection.slice(offsets[i_spline], offsets[i_spline + 1]).fill(false);
- }
- }
- });
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- const NodeGeometryCurveSelectHandles *storage =
- (const NodeGeometryCurveSelectHandles *)params.node().storage;
- const HandleType handle_type = handle_type_from_input_type(
- (GeometryNodeCurveHandleType)storage->handle_type);
- const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)storage->mode;
-
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
- if (curve_component.has_curves()) {
- const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component.get_for_read());
- const std::string selection_name = params.extract_input<std::string>("Selection");
- OutputAttribute_Typed<bool> selection =
- curve_component.attribute_try_get_for_output_only<bool>(selection_name, ATTR_DOMAIN_POINT);
- if (selection) {
- select_curve_by_handle_type(*curve, handle_type, mode, selection.as_span());
- selection.save();
- }
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_curve_select_by_handle_type_cc
-
-void register_node_type_geo_legacy_select_by_handle_type()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_select_by_handle_type_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_CURVE_SELECT_HANDLES, "Select by Handle Type", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(&ntype,
- "NodeGeometryCurveSelectHandles",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.draw_buttons = file_ns::node_layout;
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc
deleted file mode 100644
index 56e9068882b..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BKE_spline.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_curve_set_handles_cc {
-
-static void node_decalre(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Curve"));
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Curve"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "handle_type", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryCurveSetHandles *data = MEM_cnew<NodeGeometryCurveSetHandles>(__func__);
-
- data->handle_type = GEO_NODE_CURVE_HANDLE_AUTO;
- data->mode = GEO_NODE_CURVE_HANDLE_LEFT | GEO_NODE_CURVE_HANDLE_RIGHT;
- node->storage = data;
-}
-
-static HandleType handle_type_from_input_type(GeometryNodeCurveHandleType type)
-{
- switch (type) {
- case GEO_NODE_CURVE_HANDLE_AUTO:
- return BEZIER_HANDLE_AUTO;
- case GEO_NODE_CURVE_HANDLE_ALIGN:
- return BEZIER_HANDLE_ALIGN;
- case GEO_NODE_CURVE_HANDLE_FREE:
- return BEZIER_HANDLE_FREE;
- case GEO_NODE_CURVE_HANDLE_VECTOR:
- return BEZIER_HANDLE_VECTOR;
- }
- BLI_assert_unreachable();
- return BEZIER_HANDLE_AUTO;
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- const NodeGeometryCurveSetHandles *node_storage =
- (NodeGeometryCurveSetHandles *)params.node().storage;
- const GeometryNodeCurveHandleType type = (GeometryNodeCurveHandleType)node_storage->handle_type;
- const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)node_storage->mode;
-
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- geometry_set = geometry::realize_instances_legacy(geometry_set);
- if (!geometry_set.has_curves()) {
- params.set_output("Curve", geometry_set);
- return;
- }
-
- /* Retrieve data for write access so we can avoid new allocations for the handles data. */
- CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
- std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component.get_for_read());
- MutableSpan<SplinePtr> splines = curve->splines();
-
- const std::string selection_name = params.extract_input<std::string>("Selection");
- VArray<bool> selection = curve_component.attribute_get_for_read(
- selection_name, ATTR_DOMAIN_POINT, true);
-
- const HandleType new_handle_type = handle_type_from_input_type(type);
- int point_index = 0;
- bool has_bezier_spline = false;
- for (SplinePtr &spline : splines) {
- if (spline->type() != CURVE_TYPE_BEZIER) {
- point_index += spline->positions().size();
- continue;
- }
-
- BezierSpline &bezier_spline = static_cast<BezierSpline &>(*spline);
- if (ELEM(new_handle_type, BEZIER_HANDLE_FREE, BEZIER_HANDLE_ALIGN)) {
- /* In this case the automatically calculated handle types need to be "baked", because
- * they're possibly changing from a type that is calculated automatically to a type that
- * is positioned manually. */
- bezier_spline.ensure_auto_handles();
- }
- has_bezier_spline = true;
- for (int i_point : IndexRange(bezier_spline.size())) {
- if (selection[point_index]) {
- if (mode & GEO_NODE_CURVE_HANDLE_LEFT) {
- bezier_spline.handle_types_left()[i_point] = new_handle_type;
- }
- if (mode & GEO_NODE_CURVE_HANDLE_RIGHT) {
- bezier_spline.handle_types_right()[i_point] = new_handle_type;
- }
- }
- point_index++;
- }
- bezier_spline.mark_cache_invalid();
- }
-
- geometry_set.replace_curves(curve_eval_to_curves(*curve));
-
- if (!has_bezier_spline) {
- params.error_message_add(NodeWarningType::Info, TIP_("No Bezier splines in input curve"));
- }
-
- params.set_output("Curve", geometry_set);
-}
-} // namespace blender::nodes::node_geo_legacy_curve_set_handles_cc
-
-void register_node_type_geo_legacy_curve_set_handles()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_set_handles_cc;
-
- static bNodeType ntype;
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_CURVE_SET_HANDLES, "Set Handle Type", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_decalre;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(&ntype,
- "NodeGeometryCurveSetHandles",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.draw_buttons = file_ns::node_layout;
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc
deleted file mode 100644
index 002c42c4c82..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc
+++ /dev/null
@@ -1,294 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BKE_spline.hh"
-
-#include "BLI_task.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_curve_spline_type_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Curve"));
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Curve"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "spline_type", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryCurveSplineType *data = MEM_cnew<NodeGeometryCurveSplineType>(__func__);
-
- data->spline_type = GEO_NODE_SPLINE_TYPE_POLY;
- node->storage = data;
-}
-
-template<class T>
-static void scale_input_assign(const Span<T> input,
- const int scale,
- const int offset,
- const MutableSpan<T> r_output)
-{
- for (const int i : IndexRange(r_output.size())) {
- r_output[i] = input[i * scale + offset];
- }
-}
-
-template<class T>
-static void scale_output_assign(const Span<T> input,
- const int scale,
- const int offset,
- const MutableSpan<T> &r_output)
-{
- for (const int i : IndexRange(input.size())) {
- r_output[i * scale + offset] = input[i];
- }
-}
-
-template<typename CopyFn>
-static void copy_attributes(const Spline &input_spline, Spline &output_spline, CopyFn copy_fn)
-{
- input_spline.attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<GSpan> src = input_spline.attributes.get_for_read(attribute_id);
- BLI_assert(src);
- if (!output_spline.attributes.create(attribute_id, meta_data.data_type)) {
- BLI_assert_unreachable();
- return false;
- }
- std::optional<GMutableSpan> dst = output_spline.attributes.get_for_write(attribute_id);
- if (!dst) {
- BLI_assert_unreachable();
- return false;
- }
-
- copy_fn(*src, *dst);
-
- return true;
- },
- ATTR_DOMAIN_POINT);
-}
-
-static SplinePtr convert_to_poly_spline(const Spline &input)
-{
- std::unique_ptr<PolySpline> output = std::make_unique<PolySpline>();
- output->resize(input.positions().size());
- output->positions().copy_from(input.positions());
- output->radii().copy_from(input.radii());
- output->tilts().copy_from(input.tilts());
- Spline::copy_base_settings(input, *output);
- output->attributes = input.attributes;
- return output;
-}
-
-static SplinePtr poly_to_nurbs(const Spline &input)
-{
- std::unique_ptr<NURBSpline> output = std::make_unique<NURBSpline>();
- output->resize(input.positions().size());
- output->positions().copy_from(input.positions());
- output->radii().copy_from(input.radii());
- output->tilts().copy_from(input.tilts());
- output->weights().fill(1.0f);
- output->set_resolution(12);
- output->set_order(4);
- Spline::copy_base_settings(input, *output);
- output->knots_mode = NURBS_KNOT_MODE_BEZIER;
- output->attributes = input.attributes;
- return output;
-}
-
-static SplinePtr bezier_to_nurbs(const Spline &input)
-{
- const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(input);
- std::unique_ptr<NURBSpline> output = std::make_unique<NURBSpline>();
- output->resize(input.size() * 3);
-
- scale_output_assign(bezier_spline.handle_positions_left(), 3, 0, output->positions());
- scale_output_assign(input.radii(), 3, 0, output->radii());
- scale_output_assign(input.tilts(), 3, 0, output->tilts());
-
- scale_output_assign(bezier_spline.positions(), 3, 1, output->positions());
- scale_output_assign(input.radii(), 3, 1, output->radii());
- scale_output_assign(input.tilts(), 3, 1, output->tilts());
-
- scale_output_assign(bezier_spline.handle_positions_right(), 3, 2, output->positions());
- scale_output_assign(input.radii(), 3, 2, output->radii());
- scale_output_assign(input.tilts(), 3, 2, output->tilts());
-
- Spline::copy_base_settings(input, *output);
- output->weights().fill(1.0f);
- output->set_resolution(12);
- output->set_order(4);
- output->set_cyclic(input.is_cyclic());
- output->knots_mode = NURBS_KNOT_MODE_BEZIER;
- output->attributes.reallocate(output->size());
- copy_attributes(input, *output, [](GSpan src, GMutableSpan dst) {
- attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- scale_output_assign<T>(src.typed<T>(), 3, 0, dst.typed<T>());
- scale_output_assign<T>(src.typed<T>(), 3, 1, dst.typed<T>());
- scale_output_assign<T>(src.typed<T>(), 3, 2, dst.typed<T>());
- });
- });
- return output;
-}
-
-static SplinePtr poly_to_bezier(const Spline &input)
-{
- std::unique_ptr<BezierSpline> output = std::make_unique<BezierSpline>();
- output->resize(input.size());
- output->positions().copy_from(input.positions());
- output->radii().copy_from(input.radii());
- output->tilts().copy_from(input.tilts());
- output->handle_types_left().fill(BEZIER_HANDLE_VECTOR);
- output->handle_types_right().fill(BEZIER_HANDLE_VECTOR);
- output->set_resolution(12);
- Spline::copy_base_settings(input, *output);
- output->attributes = input.attributes;
- return output;
-}
-
-static SplinePtr nurbs_to_bezier(const Spline &input)
-{
- const NURBSpline &nurbs_spline = static_cast<const NURBSpline &>(input);
- std::unique_ptr<BezierSpline> output = std::make_unique<BezierSpline>();
- output->resize(input.size() / 3);
- scale_input_assign<float3>(input.positions(), 3, 1, output->positions());
- scale_input_assign<float3>(input.positions(), 3, 0, output->handle_positions_left());
- scale_input_assign<float3>(input.positions(), 3, 2, output->handle_positions_right());
- scale_input_assign<float>(input.radii(), 3, 2, output->radii());
- scale_input_assign<float>(input.tilts(), 3, 2, output->tilts());
- output->handle_types_left().fill(BEZIER_HANDLE_ALIGN);
- output->handle_types_right().fill(BEZIER_HANDLE_ALIGN);
- output->set_resolution(nurbs_spline.resolution());
- Spline::copy_base_settings(input, *output);
- output->attributes.reallocate(output->size());
- copy_attributes(input, *output, [](GSpan src, GMutableSpan dst) {
- attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
- using T = decltype(dummy);
- scale_input_assign<T>(src.typed<T>(), 3, 1, dst.typed<T>());
- });
- });
- return output;
-}
-
-static SplinePtr convert_to_bezier(const Spline &input, GeoNodeExecParams params)
-{
- switch (input.type()) {
- case CURVE_TYPE_BEZIER:
- return input.copy();
- case CURVE_TYPE_POLY:
- return poly_to_bezier(input);
- case CURVE_TYPE_NURBS:
- if (input.size() < 6) {
- params.error_message_add(
- NodeWarningType::Info,
- TIP_("NURBS must have minimum of 6 points for Bezier Conversion"));
- return input.copy();
- }
- else {
- if (input.size() % 3 != 0) {
- params.error_message_add(NodeWarningType::Info,
- TIP_("NURBS must have multiples of 3 points for full Bezier "
- "conversion, curve truncated"));
- }
- return nurbs_to_bezier(input);
- }
- case CURVE_TYPE_CATMULL_ROM: {
- BLI_assert_unreachable();
- return {};
- }
- }
- BLI_assert_unreachable();
- return {};
-}
-
-static SplinePtr convert_to_nurbs(const Spline &input)
-{
- switch (input.type()) {
- case CURVE_TYPE_NURBS:
- return input.copy();
- case CURVE_TYPE_BEZIER:
- return bezier_to_nurbs(input);
- case CURVE_TYPE_POLY:
- return poly_to_nurbs(input);
- case CURVE_TYPE_CATMULL_ROM:
- BLI_assert_unreachable();
- return {};
- }
- BLI_assert_unreachable();
- return {};
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- const NodeGeometryCurveSplineType *storage =
- (const NodeGeometryCurveSplineType *)params.node().storage;
- const GeometryNodeSplineType output_type = (const GeometryNodeSplineType)storage->spline_type;
-
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- geometry_set = geometry::realize_instances_legacy(geometry_set);
- if (!geometry_set.has_curves()) {
- params.set_output("Curve", geometry_set);
- return;
- }
-
- const CurveComponent *curve_component = geometry_set.get_component_for_read<CurveComponent>();
- const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component->get_for_read());
-
- const std::string selection_name = params.extract_input<std::string>("Selection");
- VArray<bool> selection = curve_component->attribute_get_for_read(
- selection_name, ATTR_DOMAIN_CURVE, true);
-
- std::unique_ptr<CurveEval> new_curve = std::make_unique<CurveEval>();
- for (const int i : curve->splines().index_range()) {
- if (selection[i]) {
- switch (output_type) {
- case GEO_NODE_SPLINE_TYPE_POLY:
- new_curve->add_spline(convert_to_poly_spline(*curve->splines()[i]));
- break;
- case GEO_NODE_SPLINE_TYPE_BEZIER:
- new_curve->add_spline(convert_to_bezier(*curve->splines()[i], params));
- break;
- case GEO_NODE_SPLINE_TYPE_NURBS:
- new_curve->add_spline(convert_to_nurbs(*curve->splines()[i]));
- break;
- }
- }
- else {
- new_curve->add_spline(curve->splines()[i]->copy());
- }
- }
-
- new_curve->attributes = curve->attributes;
- params.set_output("Curve", GeometrySet::create_with_curves(curve_eval_to_curves(*new_curve)));
-}
-
-} // namespace blender::nodes::node_geo_legacy_curve_spline_type_cc
-
-void register_node_type_geo_legacy_curve_spline_type()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_spline_type_cc;
-
- static bNodeType ntype;
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_CURVE_SPLINE_TYPE, "Set Spline Type", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(&ntype,
- "NodeGeometryCurveSplineType",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.draw_buttons = file_ns::node_layout;
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc
deleted file mode 100644
index 03f7aec8838..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc
+++ /dev/null
@@ -1,384 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_task.hh"
-#include "BLI_timeit.hh"
-
-#include "BKE_attribute_math.hh"
-#include "BKE_spline.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_curve_subdivide_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Cuts"));
- b.add_input<decl::Int>(N_("Cuts"), "Cuts_001").default_value(1).min(0).max(1000);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "cuts_type", 0, IFACE_("Cuts"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryCurveSubdivide *data = MEM_cnew<NodeGeometryCurveSubdivide>(__func__);
-
- data->cuts_type = GEO_NODE_ATTRIBUTE_INPUT_INTEGER;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryPointTranslate &node_storage = *(NodeGeometryPointTranslate *)node->storage;
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Cuts", (GeometryNodeAttributeInputMode)node_storage.input_type);
-}
-
-static Array<int> get_subdivided_offsets(const Spline &spline,
- const VArray<int> &cuts,
- const int spline_offset)
-{
- Array<int> offsets(spline.segments_size() + 1);
- int offset = 0;
- for (const int i : IndexRange(spline.segments_size())) {
- offsets[i] = offset;
- offset = offset + std::max(cuts[spline_offset + i], 0) + 1;
- }
- offsets.last() = offset;
- return offsets;
-}
-
-template<typename T>
-static void subdivide_attribute(Span<T> src,
- const Span<int> offsets,
- const bool is_cyclic,
- MutableSpan<T> dst)
-{
- const int src_size = src.size();
- threading::parallel_for(IndexRange(src_size - 1), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const int cuts = offsets[i + 1] - offsets[i];
- dst[offsets[i]] = src[i];
- const float factor_delta = 1.0f / (cuts + 1.0f);
- for (const int cut : IndexRange(cuts)) {
- const float factor = (cut + 1) * factor_delta;
- dst[offsets[i] + cut] = attribute_math::mix2(factor, src[i], src[i + 1]);
- }
- }
- });
-
- if (is_cyclic) {
- const int i = src_size - 1;
- const int cuts = offsets[i + 1] - offsets[i];
- dst[offsets[i]] = src.last();
- const float factor_delta = 1.0f / (cuts + 1.0f);
- for (const int cut : IndexRange(cuts)) {
- const float factor = (cut + 1) * factor_delta;
- dst[offsets[i] + cut] = attribute_math::mix2(factor, src.last(), src.first());
- }
- }
- else {
- dst.last() = src.last();
- }
-}
-
-/**
- * In order to generate a Bezier spline with the same shape as the input spline, apply the
- * De Casteljau algorithm iteratively for the provided number of cuts, constantly updating the
- * previous result point's right handle and the left handle at the end of the segment.
- *
- * \note Non-vector segments in the result spline are given free handles. This could possibly be
- * improved with another pass that sets handles to aligned where possible, but currently that does
- * not provide much benefit for the increased complexity.
- */
-static void subdivide_bezier_segment(const BezierSpline &src,
- const int index,
- const int offset,
- const int result_size,
- Span<float3> src_positions,
- Span<float3> src_handles_left,
- Span<float3> src_handles_right,
- MutableSpan<float3> dst_positions,
- MutableSpan<float3> dst_handles_left,
- MutableSpan<float3> dst_handles_right,
- MutableSpan<int8_t> dst_type_left,
- MutableSpan<int8_t> dst_type_right)
-{
- const bool is_last_cyclic_segment = index == (src.size() - 1);
- const int next_index = is_last_cyclic_segment ? 0 : index + 1;
-
- /* The first point in the segment is always copied. */
- dst_positions[offset] = src_positions[index];
-
- if (src.segment_is_vector(index)) {
- if (is_last_cyclic_segment) {
- dst_type_left.first() = BEZIER_HANDLE_VECTOR;
- }
- dst_type_left.slice(offset + 1, result_size).fill(BEZIER_HANDLE_VECTOR);
- dst_type_right.slice(offset, result_size).fill(BEZIER_HANDLE_VECTOR);
-
- const float factor_delta = 1.0f / result_size;
- for (const int cut : IndexRange(result_size)) {
- const float factor = cut * factor_delta;
- dst_positions[offset + cut] = attribute_math::mix2(
- factor, src_positions[index], src_positions[next_index]);
- }
- }
- else {
- if (is_last_cyclic_segment) {
- dst_type_left.first() = BEZIER_HANDLE_FREE;
- }
- dst_type_left.slice(offset + 1, result_size).fill(BEZIER_HANDLE_FREE);
- dst_type_right.slice(offset, result_size).fill(BEZIER_HANDLE_FREE);
-
- const int i_segment_last = is_last_cyclic_segment ? 0 : offset + result_size;
-
- /* Create a Bezier segment to update iteratively for every subdivision
- * and references to the meaningful values for ease of use. */
- BezierSpline temp;
- temp.resize(2);
- float3 &segment_start = temp.positions().first();
- float3 &segment_end = temp.positions().last();
- float3 &handle_prev = temp.handle_positions_right().first();
- float3 &handle_next = temp.handle_positions_left().last();
- segment_start = src_positions[index];
- segment_end = src_positions[next_index];
- handle_prev = src_handles_right[index];
- handle_next = src_handles_left[next_index];
-
- for (const int cut : IndexRange(result_size - 1)) {
- const float parameter = 1.0f / (result_size - cut);
- const BezierSpline::InsertResult insert = temp.calculate_segment_insertion(0, 1, parameter);
-
- /* Copy relevant temporary data to the result. */
- dst_handles_right[offset + cut] = insert.handle_prev;
- dst_handles_left[offset + cut + 1] = insert.left_handle;
- dst_positions[offset + cut + 1] = insert.position;
-
- /* Update the segment to prepare it for the next subdivision. */
- segment_start = insert.position;
- handle_prev = insert.right_handle;
- handle_next = insert.handle_next;
- }
-
- /* Copy the handles for the last segment from the temporary spline. */
- dst_handles_right[offset + result_size - 1] = handle_prev;
- dst_handles_left[i_segment_last] = handle_next;
- }
-}
-
-static void subdivide_bezier_spline(const BezierSpline &src,
- const Span<int> offsets,
- BezierSpline &dst)
-{
- Span<float3> src_positions = src.positions();
- Span<float3> src_handles_left = src.handle_positions_left();
- Span<float3> src_handles_right = src.handle_positions_right();
- MutableSpan<float3> dst_positions = dst.positions();
- MutableSpan<float3> dst_handles_left = dst.handle_positions_left();
- MutableSpan<float3> dst_handles_right = dst.handle_positions_right();
- MutableSpan<int8_t> dst_type_left = dst.handle_types_left();
- MutableSpan<int8_t> dst_type_right = dst.handle_types_right();
-
- threading::parallel_for(IndexRange(src.size() - 1), 512, [&](IndexRange range) {
- for (const int i : range) {
- subdivide_bezier_segment(src,
- i,
- offsets[i],
- offsets[i + 1] - offsets[i],
- src_positions,
- src_handles_left,
- src_handles_right,
- dst_positions,
- dst_handles_left,
- dst_handles_right,
- dst_type_left,
- dst_type_right);
- }
- });
-
- if (src.is_cyclic()) {
- const int i_last = src.size() - 1;
- subdivide_bezier_segment(src,
- i_last,
- offsets[i_last],
- offsets.last() - offsets[i_last],
- src_positions,
- src_handles_left,
- src_handles_right,
- dst_positions,
- dst_handles_left,
- dst_handles_right,
- dst_type_left,
- dst_type_right);
- }
- else {
- dst_positions.last() = src_positions.last();
- }
-}
-
-static void subdivide_builtin_attributes(const Spline &src_spline,
- const Span<int> offsets,
- Spline &dst_spline)
-{
- const bool is_cyclic = src_spline.is_cyclic();
- subdivide_attribute<float>(src_spline.radii(), offsets, is_cyclic, dst_spline.radii());
- subdivide_attribute<float>(src_spline.tilts(), offsets, is_cyclic, dst_spline.tilts());
- switch (src_spline.type()) {
- case CURVE_TYPE_POLY: {
- const PolySpline &src = static_cast<const PolySpline &>(src_spline);
- PolySpline &dst = static_cast<PolySpline &>(dst_spline);
- subdivide_attribute<float3>(src.positions(), offsets, is_cyclic, dst.positions());
- break;
- }
- case CURVE_TYPE_BEZIER: {
- const BezierSpline &src = static_cast<const BezierSpline &>(src_spline);
- BezierSpline &dst = static_cast<BezierSpline &>(dst_spline);
- subdivide_bezier_spline(src, offsets, dst);
- dst.mark_cache_invalid();
- break;
- }
- case CURVE_TYPE_NURBS: {
- const NURBSpline &src = static_cast<const NURBSpline &>(src_spline);
- NURBSpline &dst = static_cast<NURBSpline &>(dst_spline);
- subdivide_attribute<float3>(src.positions(), offsets, is_cyclic, dst.positions());
- subdivide_attribute<float>(src.weights(), offsets, is_cyclic, dst.weights());
- break;
- }
- case CURVE_TYPE_CATMULL_ROM: {
- BLI_assert_unreachable();
- break;
- }
- }
-}
-
-static void subdivide_dynamic_attributes(const Spline &src_spline,
- const Span<int> offsets,
- Spline &dst_spline)
-{
- const bool is_cyclic = src_spline.is_cyclic();
- src_spline.attributes.foreach_attribute(
- [&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<GSpan> src = src_spline.attributes.get_for_read(attribute_id);
- BLI_assert(src);
-
- if (!dst_spline.attributes.create(attribute_id, meta_data.data_type)) {
- /* Since the source spline of the same type had the attribute, adding it should work. */
- BLI_assert_unreachable();
- }
-
- std::optional<GMutableSpan> dst = dst_spline.attributes.get_for_write(attribute_id);
- BLI_assert(dst);
-
- attribute_math::convert_to_static_type(dst->type(), [&](auto dummy) {
- using T = decltype(dummy);
- subdivide_attribute<T>(src->typed<T>(), offsets, is_cyclic, dst->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-}
-
-static SplinePtr subdivide_spline(const Spline &spline,
- const VArray<int> &cuts,
- const int spline_offset)
-{
- if (spline.size() <= 1) {
- return spline.copy();
- }
-
- /* Since we expect to access each value many times, it should be worth it to make sure count
- * of cuts is a real span (especially considering the note below). Using the offset at each
- * point facilitates subdividing in parallel later. */
- Array<int> offsets = get_subdivided_offsets(spline, cuts, spline_offset);
- const int result_size = offsets.last() + int(!spline.is_cyclic());
- SplinePtr new_spline = spline.copy_only_settings();
- new_spline->resize(result_size);
- subdivide_builtin_attributes(spline, offsets, *new_spline);
- subdivide_dynamic_attributes(spline, offsets, *new_spline);
- return new_spline;
-}
-
-/**
- * \note Passing the virtual array for the entire spline is possibly quite inefficient here when
- * the attribute was on the point domain and stored separately for each spline already, and it
- * prevents some other optimizations like skipping splines with a single attribute value of < 1.
- * However, it allows the node to access builtin attribute easily, so it the makes most sense this
- * way until the attribute API is refactored.
- */
-static std::unique_ptr<CurveEval> subdivide_curve(const CurveEval &input_curve,
- const VArray<int> &cuts)
-{
- const Array<int> control_point_offsets = input_curve.control_point_offsets();
- const Span<SplinePtr> input_splines = input_curve.splines();
-
- std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>();
- output_curve->resize(input_splines.size());
- output_curve->attributes = input_curve.attributes;
- MutableSpan<SplinePtr> output_splines = output_curve->splines();
-
- threading::parallel_for(input_splines.index_range(), 128, [&](IndexRange range) {
- for (const int i : range) {
- output_splines[i] = subdivide_spline(*input_splines[i], cuts, control_point_offsets[i]);
- }
- });
-
- return output_curve;
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (!geometry_set.has_curves()) {
- params.set_output("Geometry", geometry_set);
- return;
- }
-
- const CurveComponent &component = *geometry_set.get_component_for_read<CurveComponent>();
- VArray<int> cuts = params.get_input_attribute<int>("Cuts", component, ATTR_DOMAIN_POINT, 0);
- if (cuts.is_single() && cuts.get_internal_single() < 1) {
- params.set_output("Geometry", geometry_set);
- return;
- }
-
- std::unique_ptr<CurveEval> output_curve = subdivide_curve(
- *curves_to_curve_eval(*component.get_for_read()), cuts);
-
- params.set_output("Geometry",
- GeometrySet::create_with_curves(curve_eval_to_curves(*output_curve)));
-}
-
-} // namespace blender::nodes::node_geo_legacy_curve_subdivide_cc
-
-void register_node_type_geo_legacy_curve_subdivide()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_subdivide_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_CURVE_SUBDIVIDE, "Curve Subdivide", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_storage(&ntype,
- "NodeGeometryCurveSubdivide",
- node_free_standard_storage,
- node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc
deleted file mode 100644
index f8fcc3cc363..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc
+++ /dev/null
@@ -1,351 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_array.hh"
-#include "BLI_task.hh"
-#include "BLI_timeit.hh"
-
-#include "BKE_pointcloud.h"
-#include "BKE_spline.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes {
-
-static GMutableSpan create_attribute_and_retrieve_span(PointCloudComponent &points,
- const AttributeIDRef &attribute_id,
- const CustomDataType data_type)
-{
- points.attribute_try_create(attribute_id, ATTR_DOMAIN_POINT, data_type, AttributeInitDefault());
- WriteAttributeLookup attribute = points.attribute_try_get_for_write(attribute_id);
- BLI_assert(attribute);
- return attribute.varray.get_internal_span();
-}
-
-template<typename T>
-static MutableSpan<T> create_attribute_and_retrieve_span(PointCloudComponent &points,
- const AttributeIDRef &attribute_id)
-{
- GMutableSpan attribute = create_attribute_and_retrieve_span(
- points, attribute_id, bke::cpp_type_to_custom_data_type(CPPType::get<T>()));
- return attribute.typed<T>();
-}
-
-CurveToPointsResults curve_to_points_create_result_attributes(PointCloudComponent &points,
- const CurveEval &curve)
-{
- CurveToPointsResults attributes;
-
- attributes.result_size = points.attribute_domain_size(ATTR_DOMAIN_POINT);
-
- attributes.positions = create_attribute_and_retrieve_span<float3>(points, "position");
- attributes.radii = create_attribute_and_retrieve_span<float>(points, "radius");
- attributes.tilts = create_attribute_and_retrieve_span<float>(points, "tilt");
-
- /* Because of the invariants of the curve component, we use the attributes of the
- * first spline as a representative for the attribute meta data all splines. */
- curve.splines().first()->attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- attributes.point_attributes.add_new(
- attribute_id,
- create_attribute_and_retrieve_span(points, attribute_id, meta_data.data_type));
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- attributes.tangents = create_attribute_and_retrieve_span<float3>(points, "tangent");
- attributes.normals = create_attribute_and_retrieve_span<float3>(points, "normal");
- attributes.rotations = create_attribute_and_retrieve_span<float3>(points, "rotation");
-
- return attributes;
-}
-
-} // namespace blender::nodes
-
-namespace blender::nodes::node_geo_legacy_curve_to_points_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Int>(N_("Count")).default_value(10).min(2).max(100000);
- b.add_input<decl::Float>(N_("Length")).default_value(0.1f).min(0.001f).subtype(PROP_DISTANCE);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryCurveToPoints *data = MEM_cnew<NodeGeometryCurveToPoints>(__func__);
-
- data->mode = GEO_NODE_CURVE_RESAMPLE_COUNT;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryCurveToPoints &node_storage = *(NodeGeometryCurveToPoints *)node->storage;
- const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
-
- bNodeSocket *count_socket = ((bNodeSocket *)node->inputs.first)->next;
- bNodeSocket *length_socket = count_socket->next;
-
- nodeSetSocketAvailability(ntree, count_socket, mode == GEO_NODE_CURVE_RESAMPLE_COUNT);
- nodeSetSocketAvailability(ntree, length_socket, mode == GEO_NODE_CURVE_RESAMPLE_LENGTH);
-}
-
-/**
- * Evaluate splines in parallel to speed up the rest of the node's execution.
- */
-static void evaluate_splines(Span<SplinePtr> splines)
-{
- threading::parallel_for_each(splines, [](const SplinePtr &spline) {
- /* These functions fill the corresponding caches on each spline. */
- spline->evaluated_positions();
- spline->evaluated_tangents();
- spline->evaluated_normals();
- spline->evaluated_lengths();
- });
-}
-
-static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
- const GeometryNodeCurveResampleMode mode,
- const CurveEval &curve,
- const Span<SplinePtr> splines)
-{
- const int size = curve.splines().size();
- switch (mode) {
- case GEO_NODE_CURVE_RESAMPLE_COUNT: {
- const int count = params.extract_input<int>("Count");
- if (count < 1) {
- return {0};
- }
- Array<int> offsets(size + 1);
- for (const int i : offsets.index_range()) {
- offsets[i] = count * i;
- }
- return offsets;
- }
- case GEO_NODE_CURVE_RESAMPLE_LENGTH: {
- /* Don't allow asymptotic count increase for low resolution values. */
- const float resolution = std::max(params.extract_input<float>("Length"), 0.0001f);
- Array<int> offsets(size + 1);
- int offset = 0;
- for (const int i : IndexRange(size)) {
- offsets[i] = offset;
- offset += splines[i]->length() / resolution + 1;
- }
- offsets.last() = offset;
- return offsets;
- }
- case GEO_NODE_CURVE_RESAMPLE_EVALUATED: {
- return curve.evaluated_point_offsets();
- }
- }
- BLI_assert_unreachable();
- return {0};
-}
-
-/**
- * TODO: For non-poly splines, this has double copies that could be avoided as part
- * of a general look at optimizing uses of #Spline::interpolate_to_evaluated.
- */
-static void copy_evaluated_point_attributes(Span<SplinePtr> splines,
- Span<int> offsets,
- CurveToPointsResults &data)
-{
- threading::parallel_for(splines.index_range(), 64, [&](IndexRange range) {
- for (const int i : range) {
- const Spline &spline = *splines[i];
- const int offset = offsets[i];
- const int size = offsets[i + 1] - offsets[i];
-
- data.positions.slice(offset, size).copy_from(spline.evaluated_positions());
- spline.interpolate_to_evaluated(spline.radii()).materialize(data.radii.slice(offset, size));
- spline.interpolate_to_evaluated(spline.tilts()).materialize(data.tilts.slice(offset, size));
-
- for (const Map<AttributeIDRef, GMutableSpan>::Item item : data.point_attributes.items()) {
- const AttributeIDRef attribute_id = item.key;
- GMutableSpan point_span = item.value;
-
- BLI_assert(spline.attributes.get_for_read(attribute_id));
- GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
-
- spline.interpolate_to_evaluated(spline_span)
- .materialize(point_span.slice(offset, size).data());
- }
-
- data.tangents.slice(offset, size).copy_from(spline.evaluated_tangents());
- data.normals.slice(offset, size).copy_from(spline.evaluated_normals());
- }
- });
-}
-
-static void copy_uniform_sample_point_attributes(Span<SplinePtr> splines,
- Span<int> offsets,
- CurveToPointsResults &data)
-{
- threading::parallel_for(splines.index_range(), 64, [&](IndexRange range) {
- for (const int i : range) {
- const Spline &spline = *splines[i];
- const int offset = offsets[i];
- const int size = offsets[i + 1] - offsets[i];
- if (size == 0) {
- continue;
- }
-
- const Array<float> uniform_samples = spline.sample_uniform_index_factors(size);
-
- spline.sample_with_index_factors<float3>(
- spline.evaluated_positions(), uniform_samples, data.positions.slice(offset, size));
-
- spline.sample_with_index_factors<float>(spline.interpolate_to_evaluated(spline.radii()),
- uniform_samples,
- data.radii.slice(offset, size));
-
- spline.sample_with_index_factors<float>(spline.interpolate_to_evaluated(spline.tilts()),
- uniform_samples,
- data.tilts.slice(offset, size));
-
- for (const Map<AttributeIDRef, GMutableSpan>::Item item : data.point_attributes.items()) {
- const AttributeIDRef attribute_id = item.key;
- GMutableSpan point_span = item.value;
-
- BLI_assert(spline.attributes.get_for_read(attribute_id));
- GSpan spline_span = *spline.attributes.get_for_read(attribute_id);
-
- spline.sample_with_index_factors(spline.interpolate_to_evaluated(spline_span),
- uniform_samples,
- point_span.slice(offset, size));
- }
-
- spline.sample_with_index_factors<float3>(
- spline.evaluated_tangents(), uniform_samples, data.tangents.slice(offset, size));
- for (float3 &tangent : data.tangents) {
- tangent = math::normalize(tangent);
- }
-
- spline.sample_with_index_factors<float3>(
- spline.evaluated_normals(), uniform_samples, data.normals.slice(offset, size));
- for (float3 &normals : data.normals) {
- normals = math::normalize(normals);
- }
- }
- });
-}
-
-/**
- * \note Use attributes from the curve component rather than the attribute data directly on the
- * attribute storage to allow reading the virtual spline attributes like "cyclic" and "resolution".
- */
-static void copy_spline_domain_attributes(const CurveComponent &curve_component,
- Span<int> offsets,
- PointCloudComponent &points)
-{
- curve_component.attribute_foreach(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- if (meta_data.domain != ATTR_DOMAIN_CURVE) {
- return true;
- }
- GVArray spline_attribute = curve_component.attribute_get_for_read(
- attribute_id, ATTR_DOMAIN_CURVE, meta_data.data_type);
- const CPPType &type = spline_attribute.type();
-
- OutputAttribute result_attribute = points.attribute_try_get_for_output_only(
- attribute_id, ATTR_DOMAIN_POINT, meta_data.data_type);
- GMutableSpan result = result_attribute.as_span();
-
- for (const int i : spline_attribute.index_range()) {
- const int offset = offsets[i];
- const int size = offsets[i + 1] - offsets[i];
- if (size != 0) {
- BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
- spline_attribute.get(i, buffer);
- type.fill_assign_n(buffer, result[offset], size);
- }
- }
-
- result_attribute.save();
- return true;
- });
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- NodeGeometryCurveToPoints &node_storage = *(NodeGeometryCurveToPoints *)params.node().storage;
- const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (!geometry_set.has_curves()) {
- params.set_output("Geometry", GeometrySet());
- return;
- }
-
- const CurveComponent &curve_component = *geometry_set.get_component_for_read<CurveComponent>();
- const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component.get_for_read());
- const Span<SplinePtr> splines = curve->splines();
- curve->assert_valid_point_attributes();
-
- evaluate_splines(splines);
-
- const Array<int> offsets = calculate_spline_point_offsets(params, mode, *curve, splines);
- const int total_size = offsets.last();
- if (total_size == 0) {
- params.set_output("Geometry", GeometrySet());
- return;
- }
-
- GeometrySet result = GeometrySet::create_with_pointcloud(BKE_pointcloud_new_nomain(total_size));
- PointCloudComponent &point_component = result.get_component_for_write<PointCloudComponent>();
-
- CurveToPointsResults new_attributes = curve_to_points_create_result_attributes(point_component,
- *curve);
- switch (mode) {
- case GEO_NODE_CURVE_RESAMPLE_COUNT:
- case GEO_NODE_CURVE_RESAMPLE_LENGTH:
- copy_uniform_sample_point_attributes(splines, offsets, new_attributes);
- break;
- case GEO_NODE_CURVE_RESAMPLE_EVALUATED:
- copy_evaluated_point_attributes(splines, offsets, new_attributes);
- break;
- }
-
- copy_spline_domain_attributes(curve_component, offsets, point_component);
- curve_create_default_rotation_attribute(
- new_attributes.tangents, new_attributes.normals, new_attributes.rotations);
-
- /* The default radius is way too large for points, divide by 10. */
- for (float &radius : new_attributes.radii) {
- radius *= 0.1f;
- }
-
- params.set_output("Geometry", std::move(result));
-}
-
-} // namespace blender::nodes::node_geo_legacy_curve_to_points_cc
-
-void register_node_type_geo_legacy_curve_to_points()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_curve_to_points_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_CURVE_TO_POINTS, "Curve to Points", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_storage(
- &ntype, "NodeGeometryCurveToPoints", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc
deleted file mode 100644
index ca98d83c137..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc
+++ /dev/null
@@ -1,726 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_array.hh"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BKE_customdata.h"
-#include "BKE_mesh.h"
-#include "BKE_pointcloud.h"
-#include "BKE_spline.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_delete_geometry_cc {
-
-using blender::bke::CustomDataAttributes;
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Selection"));
- b.add_input<decl::Bool>(N_("Invert"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-template<typename T> static void copy_data(Span<T> data, MutableSpan<T> r_data, IndexMask mask)
-{
- for (const int i_out : mask.index_range()) {
- r_data[i_out] = data[mask[i_out]];
- }
-}
-
-static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- Span<int> vertex_map)
-{
- BLI_assert(src_mesh.totvert == vertex_map.size());
- for (const int i_src : vertex_map.index_range()) {
- const int i_dst = vertex_map[i_src];
- if (i_dst == -1) {
- continue;
- }
-
- const MVert &v_src = src_mesh.mvert[i_src];
- MVert &v_dst = dst_mesh.mvert[i_dst];
-
- v_dst = v_src;
- CustomData_copy_data(&src_mesh.vdata, &dst_mesh.vdata, i_src, i_dst, 1);
- }
-}
-
-static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- Span<int> vertex_map,
- Span<int> edge_map)
-{
- BLI_assert(src_mesh.totvert == vertex_map.size());
- BLI_assert(src_mesh.totedge == edge_map.size());
- for (const int i_src : IndexRange(src_mesh.totedge)) {
- const int i_dst = edge_map[i_src];
- if (ELEM(i_dst, -1, -2)) {
- continue;
- }
-
- const MEdge &e_src = src_mesh.medge[i_src];
- MEdge &e_dst = dst_mesh.medge[i_dst];
-
- CustomData_copy_data(&src_mesh.edata, &dst_mesh.edata, i_src, i_dst, 1);
- e_dst = e_src;
- e_dst.v1 = vertex_map[e_src.v1];
- e_dst.v2 = vertex_map[e_src.v2];
- }
-}
-
-static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- Span<int> vertex_map,
- Span<int> edge_map,
- Span<int> masked_poly_indices,
- Span<int> new_loop_starts)
-{
- for (const int i_dst : masked_poly_indices.index_range()) {
- const int i_src = masked_poly_indices[i_dst];
-
- const MPoly &mp_src = src_mesh.mpoly[i_src];
- MPoly &mp_dst = dst_mesh.mpoly[i_dst];
- const int i_ml_src = mp_src.loopstart;
- const int i_ml_dst = new_loop_starts[i_dst];
-
- CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1);
- CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop);
-
- const MLoop *ml_src = src_mesh.mloop + i_ml_src;
- MLoop *ml_dst = dst_mesh.mloop + i_ml_dst;
-
- mp_dst = mp_src;
- mp_dst.loopstart = i_ml_dst;
- for (int i : IndexRange(mp_src.totloop)) {
- ml_dst[i].v = vertex_map[ml_src[i].v];
- ml_dst[i].e = edge_map[ml_src[i].e];
- }
- }
-}
-
-static void spline_copy_builtin_attributes(const Spline &spline,
- Spline &r_spline,
- const IndexMask mask)
-{
- copy_data(spline.positions(), r_spline.positions(), mask);
- copy_data(spline.radii(), r_spline.radii(), mask);
- copy_data(spline.tilts(), r_spline.tilts(), mask);
- switch (spline.type()) {
- case CURVE_TYPE_POLY:
- break;
- case CURVE_TYPE_BEZIER: {
- const BezierSpline &src = static_cast<const BezierSpline &>(spline);
- BezierSpline &dst = static_cast<BezierSpline &>(r_spline);
- copy_data(src.handle_positions_left(), dst.handle_positions_left(), mask);
- copy_data(src.handle_positions_right(), dst.handle_positions_right(), mask);
- copy_data(src.handle_types_left(), dst.handle_types_left(), mask);
- copy_data(src.handle_types_right(), dst.handle_types_right(), mask);
- break;
- }
- case CURVE_TYPE_NURBS: {
- const NURBSpline &src = static_cast<const NURBSpline &>(spline);
- NURBSpline &dst = static_cast<NURBSpline &>(r_spline);
- copy_data(src.weights(), dst.weights(), mask);
- break;
- }
- case CURVE_TYPE_CATMULL_ROM: {
- BLI_assert_unreachable();
- break;
- }
- }
-}
-
-static void copy_dynamic_attributes(const CustomDataAttributes &src,
- CustomDataAttributes &dst,
- const IndexMask mask)
-{
- src.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<GSpan> src_attribute = src.get_for_read(attribute_id);
- BLI_assert(src_attribute);
-
- if (!dst.create(attribute_id, meta_data.data_type)) {
- /* Since the source spline of the same type had the attribute, adding it should work.
- */
- BLI_assert_unreachable();
- }
-
- std::optional<GMutableSpan> new_attribute = dst.get_for_write(attribute_id);
- BLI_assert(new_attribute);
-
- attribute_math::convert_to_static_type(new_attribute->type(), [&](auto dummy) {
- using T = decltype(dummy);
- copy_data(src_attribute->typed<T>(), new_attribute->typed<T>(), mask);
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-}
-
-static SplinePtr spline_delete(const Spline &spline, const IndexMask mask)
-{
- SplinePtr new_spline = spline.copy_only_settings();
- new_spline->resize(mask.size());
-
- spline_copy_builtin_attributes(spline, *new_spline, mask);
- copy_dynamic_attributes(spline.attributes, new_spline->attributes, mask);
-
- return new_spline;
-}
-
-static std::unique_ptr<CurveEval> curve_delete(const CurveEval &input_curve,
- const StringRef name,
- const bool invert)
-{
- Span<SplinePtr> input_splines = input_curve.splines();
- std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>();
-
- /* Keep track of which splines were copied to the result to copy spline domain attributes. */
- Vector<int64_t> copied_splines;
-
- if (input_curve.attributes.get_for_read(name)) {
- VArray<bool> selection = input_curve.attributes.get_for_read<bool>(name, false);
- for (const int i : input_splines.index_range()) {
- if (selection[i] == invert) {
- output_curve->add_spline(input_splines[i]->copy());
- copied_splines.append(i);
- }
- }
- }
- else {
- /* Reuse index vector for each spline. */
- Vector<int64_t> indices_to_copy;
-
- for (const int i : input_splines.index_range()) {
- const Spline &spline = *input_splines[i];
- VArray<bool> selection = spline.attributes.get_for_read<bool>(name, false);
-
- indices_to_copy.clear();
- for (const int i_point : IndexRange(spline.size())) {
- if (selection[i_point] == invert) {
- indices_to_copy.append(i_point);
- }
- }
-
- /* Avoid creating an empty spline. */
- if (indices_to_copy.is_empty()) {
- continue;
- }
-
- SplinePtr new_spline = spline_delete(spline, IndexMask(indices_to_copy));
- output_curve->add_spline(std::move(new_spline));
- copied_splines.append(i);
- }
- }
-
- if (copied_splines.is_empty()) {
- return {};
- }
-
- output_curve->attributes.reallocate(output_curve->splines().size());
- copy_dynamic_attributes(
- input_curve.attributes, output_curve->attributes, IndexMask(copied_splines));
-
- return output_curve;
-}
-
-static void delete_curve_selection(const CurveComponent &in_component,
- CurveComponent &r_component,
- const StringRef selection_name,
- const bool invert)
-{
- std::unique_ptr<CurveEval> r_curve = curve_delete(
- *curves_to_curve_eval(*in_component.get_for_read()), selection_name, invert);
- if (r_curve) {
- r_component.replace(curve_eval_to_curves(*r_curve));
- }
- else {
- r_component.clear();
- }
-}
-
-static void delete_point_cloud_selection(const PointCloudComponent &in_component,
- PointCloudComponent &out_component,
- const StringRef selection_name,
- const bool invert)
-{
- const VArray<bool> selection_attribute = in_component.attribute_get_for_read<bool>(
- selection_name, ATTR_DOMAIN_POINT, false);
- VArray_Span<bool> selection{selection_attribute};
-
- const int total = selection.count(invert);
- if (total == 0) {
- out_component.clear();
- return;
- }
- out_component.replace(BKE_pointcloud_new_nomain(total));
-
- /* Invert the inversion, because this deletes the selected points instead of keeping them. */
- copy_point_attributes_based_on_mask(in_component, out_component, selection, !invert);
-}
-
-static void compute_selected_vertices_from_vertex_selection(const VArray<bool> &vertex_selection,
- const bool invert,
- MutableSpan<int> r_vertex_map,
- uint *r_num_selected_vertices)
-{
- BLI_assert(vertex_selection.size() == r_vertex_map.size());
-
- uint num_selected_vertices = 0;
- for (const int i : r_vertex_map.index_range()) {
- if (vertex_selection[i] != invert) {
- r_vertex_map[i] = num_selected_vertices;
- num_selected_vertices++;
- }
- else {
- r_vertex_map[i] = -1;
- }
- }
-
- *r_num_selected_vertices = num_selected_vertices;
-}
-
-static void compute_selected_edges_from_vertex_selection(const Mesh &mesh,
- const VArray<bool> &vertex_selection,
- const bool invert,
- MutableSpan<int> r_edge_map,
- uint *r_num_selected_edges)
-{
- BLI_assert(mesh.totedge == r_edge_map.size());
-
- uint num_selected_edges = 0;
- for (const int i : IndexRange(mesh.totedge)) {
- const MEdge &edge = mesh.medge[i];
-
- /* Only add the edge if both vertices will be in the new mesh. */
- if (vertex_selection[edge.v1] != invert && vertex_selection[edge.v2] != invert) {
- r_edge_map[i] = num_selected_edges;
- num_selected_edges++;
- }
- else {
- r_edge_map[i] = -1;
- }
- }
-
- *r_num_selected_edges = num_selected_edges;
-}
-
-static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh,
- const VArray<bool> &vertex_selection,
- const bool invert,
- Vector<int> &r_selected_poly_indices,
- Vector<int> &r_loop_starts,
- uint *r_num_selected_polys,
- uint *r_num_selected_loops)
-{
- BLI_assert(mesh.totvert == vertex_selection.size());
-
- r_selected_poly_indices.reserve(mesh.totpoly);
- r_loop_starts.reserve(mesh.totloop);
-
- uint num_selected_loops = 0;
- for (const int i : IndexRange(mesh.totpoly)) {
- const MPoly &poly_src = mesh.mpoly[i];
-
- bool all_verts_in_selection = true;
- Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop);
- for (const MLoop &loop : loops_src) {
- if (vertex_selection[loop.v] == invert) {
- all_verts_in_selection = false;
- break;
- }
- }
-
- if (all_verts_in_selection) {
- r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
- }
- }
-
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
-}
-
-/**
- * Checks for every edge if it is in `edge_selection`. If it is, then the two vertices of the
- * edge are kept along with the edge.
- */
-static void compute_selected_vertices_and_edges_from_edge_selection(
- const Mesh &mesh,
- const VArray<bool> &edge_selection,
- const bool invert,
- MutableSpan<int> r_vertex_map,
- MutableSpan<int> r_edge_map,
- uint *r_num_selected_vertices,
- uint *r_num_selected_edges)
-{
- BLI_assert(mesh.totedge == edge_selection.size());
-
- uint num_selected_edges = 0;
- uint num_selected_vertices = 0;
- for (const int i : IndexRange(mesh.totedge)) {
- const MEdge &edge = mesh.medge[i];
- if (edge_selection[i] != invert) {
- r_edge_map[i] = num_selected_edges;
- num_selected_edges++;
- if (r_vertex_map[edge.v1] == -1) {
- r_vertex_map[edge.v1] = num_selected_vertices;
- num_selected_vertices++;
- }
- if (r_vertex_map[edge.v2] == -1) {
- r_vertex_map[edge.v2] = num_selected_vertices;
- num_selected_vertices++;
- }
- }
- else {
- r_edge_map[i] = -1;
- }
- }
-
- *r_num_selected_vertices = num_selected_vertices;
- *r_num_selected_edges = num_selected_edges;
-}
-
-/**
- * Checks for every polygon if all the edges are in `edge_selection`. If they are, then that
- * polygon is kept.
- */
-static void compute_selected_polygons_from_edge_selection(const Mesh &mesh,
- const VArray<bool> &edge_selection,
- const bool invert,
- Vector<int> &r_selected_poly_indices,
- Vector<int> &r_loop_starts,
- uint *r_num_selected_polys,
- uint *r_num_selected_loops)
-{
- r_selected_poly_indices.reserve(mesh.totpoly);
- r_loop_starts.reserve(mesh.totloop);
-
- uint num_selected_loops = 0;
- for (const int i : IndexRange(mesh.totpoly)) {
- const MPoly &poly_src = mesh.mpoly[i];
-
- bool all_edges_in_selection = true;
- Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop);
- for (const MLoop &loop : loops_src) {
- if (edge_selection[loop.e] == invert) {
- all_edges_in_selection = false;
- break;
- }
- }
-
- if (all_edges_in_selection) {
- r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
- }
- }
-
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
-}
-
-/**
- * Checks for every vertex if it is in `vertex_selection`. The polygons and edges are kept if all
- * vertices of that polygon or edge are in the selection.
- */
-static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh,
- const VArray<bool> &vertex_selection,
- const bool invert,
- MutableSpan<int> r_vertex_map,
- MutableSpan<int> r_edge_map,
- Vector<int> &r_selected_poly_indices,
- Vector<int> &r_loop_starts,
- uint *r_num_selected_vertices,
- uint *r_num_selected_edges,
- uint *r_num_selected_polys,
- uint *r_num_selected_loops)
-{
- compute_selected_vertices_from_vertex_selection(
- vertex_selection, invert, r_vertex_map, r_num_selected_vertices);
-
- compute_selected_edges_from_vertex_selection(
- mesh, vertex_selection, invert, r_edge_map, r_num_selected_edges);
-
- compute_selected_polygons_from_vertex_selection(mesh,
- vertex_selection,
- invert,
- r_selected_poly_indices,
- r_loop_starts,
- r_num_selected_polys,
- r_num_selected_loops);
-}
-
-/**
- * Checks for every edge if it is in `edge_selection`. If it is, the vertices belonging to
- * that edge are kept as well. The polygons are kept if all edges are in the selection.
- */
-static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh,
- const VArray<bool> &edge_selection,
- const bool invert,
- MutableSpan<int> r_vertex_map,
- MutableSpan<int> r_edge_map,
- Vector<int> &r_selected_poly_indices,
- Vector<int> &r_loop_starts,
- uint *r_num_selected_vertices,
- uint *r_num_selected_edges,
- uint *r_num_selected_polys,
- uint *r_num_selected_loops)
-{
- r_vertex_map.fill(-1);
- compute_selected_vertices_and_edges_from_edge_selection(mesh,
- edge_selection,
- invert,
- r_vertex_map,
- r_edge_map,
- r_num_selected_vertices,
- r_num_selected_edges);
- compute_selected_polygons_from_edge_selection(mesh,
- edge_selection,
- invert,
- r_selected_poly_indices,
- r_loop_starts,
- r_num_selected_polys,
- r_num_selected_loops);
-}
-
-/**
- * Checks for every polygon if it is in `poly_selection`. If it is, the edges and vertices
- * belonging to that polygon are kept as well.
- */
-static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh,
- const VArray<bool> &poly_selection,
- const bool invert,
- MutableSpan<int> r_vertex_map,
- MutableSpan<int> r_edge_map,
- Vector<int> &r_selected_poly_indices,
- Vector<int> &r_loop_starts,
- uint *r_num_selected_vertices,
- uint *r_num_selected_edges,
- uint *r_num_selected_polys,
- uint *r_num_selected_loops)
-{
- BLI_assert(mesh.totpoly == poly_selection.size());
- BLI_assert(mesh.totedge == r_edge_map.size());
- r_vertex_map.fill(-1);
- r_edge_map.fill(-1);
-
- r_selected_poly_indices.reserve(mesh.totpoly);
- r_loop_starts.reserve(mesh.totloop);
-
- uint num_selected_loops = 0;
- uint num_selected_vertices = 0;
- uint num_selected_edges = 0;
- for (const int i : IndexRange(mesh.totpoly)) {
- const MPoly &poly_src = mesh.mpoly[i];
- /* We keep this one. */
- if (poly_selection[i] != invert) {
- r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
-
- /* Add the vertices and the edges. */
- Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop);
- for (const MLoop &loop : loops_src) {
- /* Check first if it has not yet been added. */
- if (r_vertex_map[loop.v] == -1) {
- r_vertex_map[loop.v] = num_selected_vertices;
- num_selected_vertices++;
- }
- if (r_edge_map[loop.e] == -1) {
- r_edge_map[loop.e] = num_selected_edges;
- num_selected_edges++;
- }
- }
- }
- }
- *r_num_selected_vertices = num_selected_vertices;
- *r_num_selected_edges = num_selected_edges;
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
-}
-
-using FillMapsFunction = void (*)(const Mesh &mesh,
- const VArray<bool> &selection,
- const bool invert,
- MutableSpan<int> r_vertex_map,
- MutableSpan<int> r_edge_map,
- Vector<int> &r_selected_poly_indices,
- Vector<int> &r_loop_starts,
- uint *r_num_selected_vertices,
- uint *r_num_selected_edges,
- uint *r_num_selected_polys,
- uint *r_num_selected_loops);
-
-/**
- * Delete the parts of the mesh that are in the selection. The `fill_maps_function`
- * depends on the selection type: vertices, edges or faces.
- */
-static Mesh *delete_mesh_selection(const Mesh &mesh_in,
- const VArray<bool> &selection,
- const bool invert,
- FillMapsFunction fill_maps_function)
-{
- Array<int> vertex_map(mesh_in.totvert);
- uint num_selected_vertices;
-
- Array<int> edge_map(mesh_in.totedge);
- uint num_selected_edges;
-
- Vector<int> selected_poly_indices;
- Vector<int> new_loop_starts;
- uint num_selected_polys;
- uint num_selected_loops;
-
- /* Fill all the maps based on the selection. We delete everything
- * in the selection instead of keeping it, so we need to invert it. */
- fill_maps_function(mesh_in,
- selection,
- !invert,
- vertex_map,
- edge_map,
- selected_poly_indices,
- new_loop_starts,
- &num_selected_vertices,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
-
- Mesh *result = BKE_mesh_new_nomain_from_template(&mesh_in,
- num_selected_vertices,
- num_selected_edges,
- 0,
- num_selected_loops,
- num_selected_polys);
-
- /* Copy the selected parts of the mesh over to the new mesh. */
- copy_masked_vertices_to_new_mesh(mesh_in, *result, vertex_map);
- copy_masked_edges_to_new_mesh(mesh_in, *result, vertex_map, edge_map);
- copy_masked_polys_to_new_mesh(
- mesh_in, *result, vertex_map, edge_map, selected_poly_indices, new_loop_starts);
- BKE_mesh_calc_edges_loose(result);
- /* Tag to recalculate normals later. */
- BKE_mesh_normals_tag_dirty(result);
-
- return result;
-}
-
-static AttributeDomain get_mesh_selection_domain(MeshComponent &component, const StringRef name)
-{
- std::optional<AttributeMetaData> selection_attribute = component.attribute_get_meta_data(name);
- if (!selection_attribute) {
- /* The node will not do anything in this case, but this function must return something. */
- return ATTR_DOMAIN_POINT;
- }
-
- /* Corners can't be deleted separately, so interpolate corner attributes
- * to the face domain. Note that this choice is somewhat arbitrary. */
- if (selection_attribute->domain == ATTR_DOMAIN_CORNER) {
- return ATTR_DOMAIN_FACE;
- }
-
- return selection_attribute->domain;
-}
-
-static void delete_mesh_selection(MeshComponent &component,
- const Mesh &mesh_in,
- const StringRef selection_name,
- const bool invert)
-{
- /* Figure out the best domain to use. */
- const AttributeDomain selection_domain = get_mesh_selection_domain(component, selection_name);
-
- /* This already checks if the attribute exists, and displays a warning in that case. */
- VArray<bool> selection = component.attribute_get_for_read<bool>(
- selection_name, selection_domain, false);
-
- /* Check if there is anything to delete. */
- bool delete_nothing = true;
- for (const int i : selection.index_range()) {
- if (selection[i] != invert) {
- delete_nothing = false;
- break;
- }
- }
- if (delete_nothing) {
- return;
- }
-
- Mesh *mesh_out;
- switch (selection_domain) {
- case ATTR_DOMAIN_POINT:
- mesh_out = delete_mesh_selection(
- mesh_in, selection, invert, compute_selected_mesh_data_from_vertex_selection);
- break;
- case ATTR_DOMAIN_EDGE:
- mesh_out = delete_mesh_selection(
- mesh_in, selection, invert, compute_selected_mesh_data_from_edge_selection);
- break;
- case ATTR_DOMAIN_FACE:
- mesh_out = delete_mesh_selection(
- mesh_in, selection, invert, compute_selected_mesh_data_from_poly_selection);
- break;
- default:
- BLI_assert_unreachable();
- mesh_out = nullptr;
- break;
- }
- component.replace(mesh_out);
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- const bool invert = params.extract_input<bool>("Invert");
- const std::string selection_name = params.extract_input<std::string>("Selection");
- if (selection_name.empty()) {
- params.set_output("Geometry", std::move(geometry_set));
- return;
- }
-
- GeometrySet out_set(geometry_set);
- if (geometry_set.has<PointCloudComponent>()) {
- delete_point_cloud_selection(*geometry_set.get_component_for_read<PointCloudComponent>(),
- out_set.get_component_for_write<PointCloudComponent>(),
- selection_name,
- invert);
- }
- if (geometry_set.has<MeshComponent>()) {
- delete_mesh_selection(out_set.get_component_for_write<MeshComponent>(),
- *geometry_set.get_mesh_for_read(),
- selection_name,
- invert);
- }
- if (geometry_set.has<CurveComponent>()) {
- delete_curve_selection(*geometry_set.get_component_for_read<CurveComponent>(),
- out_set.get_component_for_write<CurveComponent>(),
- selection_name,
- invert);
- }
-
- params.set_output("Geometry", std::move(out_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_delete_geometry_cc
-
-void register_node_type_geo_legacy_delete_geometry()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_delete_geometry_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_DELETE_GEOMETRY, "Delete Geometry", NODE_CLASS_GEOMETRY);
-
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc
deleted file mode 100644
index 74fea7cef22..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "DNA_modifier_types.h"
-
-#include "node_geometry_util.hh"
-
-extern "C" {
-Mesh *doEdgeSplit(const Mesh *mesh, EdgeSplitModifierData *emd);
-}
-
-namespace blender::nodes::node_geo_legacy_edge_split_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Bool>(N_("Edge Angle")).default_value(true);
- b.add_input<decl::Float>(N_("Angle"))
- .default_value(DEG2RADF(30.0f))
- .min(0.0f)
- .max(DEG2RADF(180.0f))
- .subtype(PROP_ANGLE);
- b.add_input<decl::Bool>(N_("Sharp Edges"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (!geometry_set.has_mesh()) {
- params.set_output("Geometry", std::move(geometry_set));
- return;
- }
-
- const bool use_sharp_flag = params.extract_input<bool>("Sharp Edges");
- const bool use_edge_angle = params.extract_input<bool>("Edge Angle");
-
- if (!use_edge_angle && !use_sharp_flag) {
- params.set_output("Geometry", std::move(geometry_set));
- return;
- }
-
- const float split_angle = params.extract_input<float>("Angle");
- const Mesh *mesh_in = geometry_set.get_mesh_for_read();
-
- /* Use modifier struct to pass arguments to the modifier code. */
- EdgeSplitModifierData emd;
- memset(&emd, 0, sizeof(EdgeSplitModifierData));
- emd.split_angle = split_angle;
- if (use_edge_angle) {
- emd.flags = MOD_EDGESPLIT_FROMANGLE;
- }
- if (use_sharp_flag) {
- emd.flags |= MOD_EDGESPLIT_FROMFLAG;
- }
-
- Mesh *mesh_out = doEdgeSplit(mesh_in, &emd);
- geometry_set.replace_mesh(mesh_out);
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_edge_split_cc
-
-void register_node_type_geo_legacy_edge_split()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_edge_split_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_EDGE_SPLIT, "Edge Split", NODE_CLASS_GEOMETRY);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.declare = file_ns::node_declare;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc
deleted file mode 100644
index cb5f4044d6f..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "node_geometry_util.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BKE_material.h"
-
-namespace blender::nodes::node_geo_legacy_material_assign_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Material>(N_("Material")).hide_label(true);
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask, Material *material)
-{
- int new_material_index = -1;
- for (const int i : IndexRange(mesh.totcol)) {
- Material *other_material = mesh.mat[i];
- if (other_material == material) {
- new_material_index = i;
- break;
- }
- }
- if (new_material_index == -1) {
- /* Append a new material index. */
- new_material_index = mesh.totcol;
- BKE_id_material_eval_assign(&mesh.id, new_material_index + 1, material);
- }
-
- mesh.mpoly = (MPoly *)CustomData_duplicate_referenced_layer(&mesh.pdata, CD_MPOLY, mesh.totpoly);
- for (const int i : IndexRange(mesh.totpoly)) {
- if (face_mask[i]) {
- MPoly &poly = mesh.mpoly[i];
- poly.mat_nr = new_material_index;
- }
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- Material *material = params.extract_input<Material *>("Material");
- const std::string mask_name = params.extract_input<std::string>("Selection");
-
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
- Mesh *mesh = mesh_component.get_for_write();
- if (mesh != nullptr) {
- VArray<bool> face_mask = mesh_component.attribute_get_for_read<bool>(
- mask_name, ATTR_DOMAIN_FACE, true);
- assign_material_to_faces(*mesh, face_mask, material);
- }
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_material_assign_cc
-
-void register_node_type_geo_legacy_material_assign()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_material_assign_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc
deleted file mode 100644
index 72cb540df4a..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "GEO_mesh_to_curve.hh"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_mesh_to_curve_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Mesh"));
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Curve"));
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (!geometry_set.has_mesh()) {
- params.set_default_remaining_outputs();
- return;
- }
-
- const MeshComponent &component = *geometry_set.get_component_for_read<MeshComponent>();
- const std::string selection_name = params.extract_input<std::string>("Selection");
- if (!selection_name.empty() && !component.attribute_exists(selection_name)) {
- params.error_message_add(NodeWarningType::Error,
- TIP_("No attribute with name \"") + selection_name + "\"");
- }
- VArray<bool> selection = component.attribute_get_for_read<bool>(
- selection_name, ATTR_DOMAIN_EDGE, true);
-
- Vector<int64_t> selected_edge_indices;
- for (const int64_t i : IndexRange(component.attribute_domain_size(ATTR_DOMAIN_EDGE))) {
- if (selection[i]) {
- selected_edge_indices.append(i);
- }
- }
-
- if (selected_edge_indices.size() == 0) {
- params.set_default_remaining_outputs();
- return;
- }
-
- Curves *curves = geometry::mesh_to_curve_convert(component, IndexMask(selected_edge_indices));
- params.set_output("Curve", GeometrySet::create_with_curves(curves));
-}
-
-} // namespace blender::nodes::node_geo_legacy_mesh_to_curve_cc
-
-void register_node_type_geo_legacy_mesh_to_curve()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_mesh_to_curve_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_MESH_TO_CURVE, "Mesh to Curve", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc
deleted file mode 100644
index f7cd0624b53..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc
+++ /dev/null
@@ -1,657 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_hash.h"
-#include "BLI_kdtree.h"
-#include "BLI_rand.hh"
-#include "BLI_timeit.hh"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_pointcloud_types.h"
-
-#include "BKE_attribute_math.hh"
-#include "BKE_bvhutils.h"
-#include "BKE_geometry_set_instances.hh"
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
-#include "BKE_mesh_sample.hh"
-#include "BKE_pointcloud.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_point_distribute_cc {
-
-using blender::bke::GeometryInstanceGroup;
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Float>(N_("Distance Min")).min(0.0f).max(100000.0f).subtype(PROP_DISTANCE);
- b.add_input<decl::Float>(N_("Density Max"))
- .default_value(1.0f)
- .min(0.0f)
- .max(100000.0f)
- .subtype(PROP_NONE);
- b.add_input<decl::String>(N_("Density Attribute"));
- b.add_input<decl::Int>(N_("Seed")).min(-10000).max(10000);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE);
-}
-
-static void node_point_distribute_update(bNodeTree *ntree, bNode *node)
-{
- bNodeSocket *sock_min_dist = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
-
- nodeSetSocketAvailability(
- ntree, sock_min_dist, ELEM(node->custom1, GEO_NODE_POINT_DISTRIBUTE_POISSON));
-}
-
-/**
- * Use an arbitrary choice of axes for a usable rotation attribute directly out of this node.
- */
-static float3 normal_to_euler_rotation(const float3 normal)
-{
- float quat[4];
- vec_to_quat(quat, normal, OB_NEGZ, OB_POSY);
- float3 rotation;
- quat_to_eul(rotation, quat);
- return rotation;
-}
-
-static void sample_mesh_surface(const Mesh &mesh,
- const float4x4 &transform,
- const float base_density,
- const VArray<float> *density_factors,
- const int seed,
- Vector<float3> &r_positions,
- Vector<float3> &r_bary_coords,
- Vector<int> &r_looptri_indices)
-{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
-
- for (const int looptri_index : looptris.index_range()) {
- const MLoopTri &looptri = looptris[looptri_index];
- const int v0_loop = looptri.tri[0];
- const int v1_loop = looptri.tri[1];
- const int v2_loop = looptri.tri[2];
- const int v0_index = mesh.mloop[v0_loop].v;
- const int v1_index = mesh.mloop[v1_loop].v;
- const int v2_index = mesh.mloop[v2_loop].v;
- const float3 v0_pos = transform * float3(mesh.mvert[v0_index].co);
- const float3 v1_pos = transform * float3(mesh.mvert[v1_index].co);
- const float3 v2_pos = transform * float3(mesh.mvert[v2_index].co);
-
- float looptri_density_factor = 1.0f;
- if (density_factors != nullptr) {
- const float v0_density_factor = std::max(0.0f, (*density_factors)[v0_loop]);
- const float v1_density_factor = std::max(0.0f, (*density_factors)[v1_loop]);
- const float v2_density_factor = std::max(0.0f, (*density_factors)[v2_loop]);
- looptri_density_factor = (v0_density_factor + v1_density_factor + v2_density_factor) / 3.0f;
- }
- const float area = area_tri_v3(v0_pos, v1_pos, v2_pos);
-
- const int looptri_seed = BLI_hash_int(looptri_index + seed);
- RandomNumberGenerator looptri_rng(looptri_seed);
-
- const float points_amount_fl = area * base_density * looptri_density_factor;
- const float add_point_probability = fractf(points_amount_fl);
- const bool add_point = add_point_probability > looptri_rng.get_float();
- const int point_amount = (int)points_amount_fl + (int)add_point;
-
- for (int i = 0; i < point_amount; i++) {
- const float3 bary_coord = looptri_rng.get_barycentric_coordinates();
- float3 point_pos;
- interp_v3_v3v3v3(point_pos, v0_pos, v1_pos, v2_pos, bary_coord);
- r_positions.append(point_pos);
- r_bary_coords.append(bary_coord);
- r_looptri_indices.append(looptri_index);
- }
- }
-}
-
-BLI_NOINLINE static KDTree_3d *build_kdtree(Span<Vector<float3>> positions_all,
- const int initial_points_len)
-{
- KDTree_3d *kdtree = BLI_kdtree_3d_new(initial_points_len);
-
- int i_point = 0;
- for (const Vector<float3> &positions : positions_all) {
- for (const float3 position : positions) {
- BLI_kdtree_3d_insert(kdtree, i_point, position);
- i_point++;
- }
- }
- BLI_kdtree_3d_balance(kdtree);
- return kdtree;
-}
-
-BLI_NOINLINE static void update_elimination_mask_for_close_points(
- Span<Vector<float3>> positions_all,
- Span<int> instance_start_offsets,
- const float minimum_distance,
- MutableSpan<bool> elimination_mask,
- const int initial_points_len)
-{
- if (minimum_distance <= 0.0f) {
- return;
- }
-
- KDTree_3d *kdtree = build_kdtree(positions_all, initial_points_len);
-
- /* The elimination mask is a flattened array for every point,
- * so keep track of the index to it separately. */
- for (const int i_instance : positions_all.index_range()) {
- Span<float3> positions = positions_all[i_instance];
- const int offset = instance_start_offsets[i_instance];
-
- for (const int i : positions.index_range()) {
- if (elimination_mask[offset + i]) {
- continue;
- }
-
- struct CallbackData {
- int index;
- MutableSpan<bool> elimination_mask;
- } callback_data = {offset + i, elimination_mask};
-
- BLI_kdtree_3d_range_search_cb(
- kdtree,
- positions[i],
- minimum_distance,
- [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) {
- CallbackData &callback_data = *static_cast<CallbackData *>(user_data);
- if (index != callback_data.index) {
- callback_data.elimination_mask[index] = true;
- }
- return true;
- },
- &callback_data);
- }
- }
- BLI_kdtree_3d_free(kdtree);
-}
-
-BLI_NOINLINE static void update_elimination_mask_based_on_density_factors(
- const Mesh &mesh,
- const VArray<float> &density_factors,
- Span<float3> bary_coords,
- Span<int> looptri_indices,
- MutableSpan<bool> elimination_mask)
-{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
- for (const int i : bary_coords.index_range()) {
- if (elimination_mask[i]) {
- continue;
- }
-
- const MLoopTri &looptri = looptris[looptri_indices[i]];
- const float3 bary_coord = bary_coords[i];
-
- const int v0_loop = looptri.tri[0];
- const int v1_loop = looptri.tri[1];
- const int v2_loop = looptri.tri[2];
-
- const float v0_density_factor = std::max(0.0f, density_factors[v0_loop]);
- const float v1_density_factor = std::max(0.0f, density_factors[v1_loop]);
- const float v2_density_factor = std::max(0.0f, density_factors[v2_loop]);
-
- const float probablity = v0_density_factor * bary_coord.x + v1_density_factor * bary_coord.y +
- v2_density_factor * bary_coord.z;
-
- const float hash = BLI_hash_int_01(bary_coord.hash());
- if (hash > probablity) {
- elimination_mask[i] = true;
- }
- }
-}
-
-BLI_NOINLINE static void eliminate_points_based_on_mask(Span<bool> elimination_mask,
- Vector<float3> &positions,
- Vector<float3> &bary_coords,
- Vector<int> &looptri_indices)
-{
- for (int i = positions.size() - 1; i >= 0; i--) {
- if (elimination_mask[i]) {
- positions.remove_and_reorder(i);
- bary_coords.remove_and_reorder(i);
- looptri_indices.remove_and_reorder(i);
- }
- }
-}
-
-BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
- Span<float3> bary_coords,
- Span<int> looptri_indices,
- const AttributeDomain source_domain,
- const GVArray &source_data,
- GMutableSpan output_data)
-{
- switch (source_domain) {
- case ATTR_DOMAIN_POINT: {
- bke::mesh_surface_sample::sample_point_attribute(mesh,
- looptri_indices,
- bary_coords,
- source_data,
- IndexMask(output_data.size()),
- output_data);
- break;
- }
- case ATTR_DOMAIN_CORNER: {
- bke::mesh_surface_sample::sample_corner_attribute(mesh,
- looptri_indices,
- bary_coords,
- source_data,
- IndexMask(output_data.size()),
- output_data);
- break;
- }
- case ATTR_DOMAIN_FACE: {
- bke::mesh_surface_sample::sample_face_attribute(
- mesh, looptri_indices, source_data, IndexMask(output_data.size()), output_data);
- break;
- }
- default: {
- /* Not supported currently. */
- return;
- }
- }
-}
-
-BLI_NOINLINE static void interpolate_existing_attributes(
- Span<GeometryInstanceGroup> set_groups,
- Span<int> instance_start_offsets,
- const Map<AttributeIDRef, AttributeKind> &attributes,
- GeometryComponent &component,
- Span<Vector<float3>> bary_coords_array,
- Span<Vector<int>> looptri_indices_array)
-{
- for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
- const AttributeIDRef attribute_id = entry.key;
- const CustomDataType output_data_type = entry.value.data_type;
- /* The output domain is always #ATTR_DOMAIN_POINT, since we are creating a point cloud. */
- OutputAttribute attribute_out = component.attribute_try_get_for_output_only(
- attribute_id, ATTR_DOMAIN_POINT, output_data_type);
- if (!attribute_out) {
- continue;
- }
-
- GMutableSpan out_span = attribute_out.as_span();
-
- int i_instance = 0;
- for (const GeometryInstanceGroup &set_group : set_groups) {
- const GeometrySet &set = set_group.geometry_set;
- const MeshComponent &source_component = *set.get_component_for_read<MeshComponent>();
- const Mesh &mesh = *source_component.get_for_read();
-
- std::optional<AttributeMetaData> attribute_info = component.attribute_get_meta_data(
- attribute_id);
- if (!attribute_info) {
- i_instance += set_group.transforms.size();
- continue;
- }
-
- const AttributeDomain source_domain = attribute_info->domain;
- GVArray source_attribute = source_component.attribute_get_for_read(
- attribute_id, source_domain, output_data_type, nullptr);
- if (!source_attribute) {
- i_instance += set_group.transforms.size();
- continue;
- }
-
- for ([[maybe_unused]] const int i_set_instance : set_group.transforms.index_range()) {
- const int offset = instance_start_offsets[i_instance];
- Span<float3> bary_coords = bary_coords_array[i_instance];
- Span<int> looptri_indices = looptri_indices_array[i_instance];
-
- GMutableSpan instance_span = out_span.slice(offset, bary_coords.size());
- interpolate_attribute(
- mesh, bary_coords, looptri_indices, source_domain, source_attribute, instance_span);
-
- i_instance++;
- }
-
- attribute_math::convert_to_static_type(output_data_type, [&](auto dummy) {
- using T = decltype(dummy);
-
- VArray_Span source_span{source_attribute.typed<T>()};
- });
- }
-
- attribute_out.save();
- }
-}
-
-BLI_NOINLINE static void compute_special_attributes(Span<GeometryInstanceGroup> sets,
- Span<int> instance_start_offsets,
- GeometryComponent &component,
- Span<Vector<float3>> bary_coords_array,
- Span<Vector<int>> looptri_indices_array)
-{
- OutputAttribute_Typed<int> id_attribute = component.attribute_try_get_for_output_only<int>(
- "id", ATTR_DOMAIN_POINT);
- OutputAttribute_Typed<float3> normal_attribute =
- component.attribute_try_get_for_output_only<float3>("normal", ATTR_DOMAIN_POINT);
- OutputAttribute_Typed<float3> rotation_attribute =
- component.attribute_try_get_for_output_only<float3>("rotation", ATTR_DOMAIN_POINT);
-
- MutableSpan<int> result_ids = id_attribute.as_span();
- MutableSpan<float3> result_normals = normal_attribute.as_span();
- MutableSpan<float3> result_rotations = rotation_attribute.as_span();
-
- int i_instance = 0;
- for (const GeometryInstanceGroup &set_group : sets) {
- const GeometrySet &set = set_group.geometry_set;
- const MeshComponent &component = *set.get_component_for_read<MeshComponent>();
- const Mesh &mesh = *component.get_for_read();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
-
- for (const float4x4 &transform : set_group.transforms) {
- const int offset = instance_start_offsets[i_instance];
-
- Span<float3> bary_coords = bary_coords_array[i_instance];
- Span<int> looptri_indices = looptri_indices_array[i_instance];
- MutableSpan<int> ids = result_ids.slice(offset, bary_coords.size());
- MutableSpan<float3> normals = result_normals.slice(offset, bary_coords.size());
- MutableSpan<float3> rotations = result_rotations.slice(offset, bary_coords.size());
-
- /* Use one matrix multiplication per point instead of three (for each triangle corner). */
- float rotation_matrix[3][3];
- mat4_to_rot(rotation_matrix, transform.values);
-
- for (const int i : bary_coords.index_range()) {
- const int looptri_index = looptri_indices[i];
- const MLoopTri &looptri = looptris[looptri_index];
- const float3 &bary_coord = bary_coords[i];
-
- const int v0_index = mesh.mloop[looptri.tri[0]].v;
- const int v1_index = mesh.mloop[looptri.tri[1]].v;
- const int v2_index = mesh.mloop[looptri.tri[2]].v;
- const float3 v0_pos = float3(mesh.mvert[v0_index].co);
- const float3 v1_pos = float3(mesh.mvert[v1_index].co);
- const float3 v2_pos = float3(mesh.mvert[v2_index].co);
-
- ids[i] = (int)(bary_coord.hash() + (uint64_t)looptri_index);
- normal_tri_v3(normals[i], v0_pos, v1_pos, v2_pos);
- mul_m3_v3(rotation_matrix, normals[i]);
- rotations[i] = normal_to_euler_rotation(normals[i]);
- }
-
- i_instance++;
- }
- }
-
- id_attribute.save();
- normal_attribute.save();
- rotation_attribute.save();
-}
-
-BLI_NOINLINE static void add_remaining_point_attributes(
- Span<GeometryInstanceGroup> set_groups,
- Span<int> instance_start_offsets,
- const Map<AttributeIDRef, AttributeKind> &attributes,
- GeometryComponent &component,
- Span<Vector<float3>> bary_coords_array,
- Span<Vector<int>> looptri_indices_array)
-{
- interpolate_existing_attributes(set_groups,
- instance_start_offsets,
- attributes,
- component,
- bary_coords_array,
- looptri_indices_array);
- compute_special_attributes(
- set_groups, instance_start_offsets, component, bary_coords_array, looptri_indices_array);
-}
-
-static void distribute_points_random(Span<GeometryInstanceGroup> set_groups,
- const StringRef density_attribute_name,
- const float density,
- const int seed,
- MutableSpan<Vector<float3>> positions_all,
- MutableSpan<Vector<float3>> bary_coords_all,
- MutableSpan<Vector<int>> looptri_indices_all)
-{
- /* If there is an attribute name, the default value for the densities should be zero so that
- * points are only scattered where the attribute exists. Otherwise, just "ignore" the density
- * factors. */
- const bool use_one_default = density_attribute_name.is_empty();
-
- int i_instance = 0;
- for (const GeometryInstanceGroup &set_group : set_groups) {
- const GeometrySet &set = set_group.geometry_set;
- const MeshComponent &component = *set.get_component_for_read<MeshComponent>();
- VArray<float> density_factors = component.attribute_get_for_read<float>(
- density_attribute_name, ATTR_DOMAIN_CORNER, use_one_default ? 1.0f : 0.0f);
- const Mesh &mesh = *component.get_for_read();
- for (const float4x4 &transform : set_group.transforms) {
- Vector<float3> &positions = positions_all[i_instance];
- Vector<float3> &bary_coords = bary_coords_all[i_instance];
- Vector<int> &looptri_indices = looptri_indices_all[i_instance];
- sample_mesh_surface(mesh,
- transform,
- density,
- &density_factors,
- seed,
- positions,
- bary_coords,
- looptri_indices);
- i_instance++;
- }
- }
-}
-
-static void distribute_points_poisson_disk(Span<GeometryInstanceGroup> set_groups,
- const StringRef density_attribute_name,
- const float density,
- const int seed,
- const float minimum_distance,
- MutableSpan<Vector<float3>> positions_all,
- MutableSpan<Vector<float3>> bary_coords_all,
- MutableSpan<Vector<int>> looptri_indices_all)
-{
- Array<int> instance_start_offsets(positions_all.size());
- int initial_points_len = 0;
- int i_instance = 0;
- for (const GeometryInstanceGroup &set_group : set_groups) {
- const GeometrySet &set = set_group.geometry_set;
- const MeshComponent &component = *set.get_component_for_read<MeshComponent>();
- const Mesh &mesh = *component.get_for_read();
- for (const float4x4 &transform : set_group.transforms) {
- Vector<float3> &positions = positions_all[i_instance];
- Vector<float3> &bary_coords = bary_coords_all[i_instance];
- Vector<int> &looptri_indices = looptri_indices_all[i_instance];
- sample_mesh_surface(
- mesh, transform, density, nullptr, seed, positions, bary_coords, looptri_indices);
-
- instance_start_offsets[i_instance] = initial_points_len;
- initial_points_len += positions.size();
- i_instance++;
- }
- }
-
- /* If there is an attribute name, the default value for the densities should be zero so that
- * points are only scattered where the attribute exists. Otherwise, just "ignore" the density
- * factors. */
- const bool use_one_default = density_attribute_name.is_empty();
-
- /* Unlike the other result arrays, the elimination mask in stored as a flat array for every
- * point, in order to simplify culling points from the KDTree (which needs to know about all
- * points at once). */
- Array<bool> elimination_mask(initial_points_len, false);
- update_elimination_mask_for_close_points(positions_all,
- instance_start_offsets,
- minimum_distance,
- elimination_mask,
- initial_points_len);
-
- i_instance = 0;
- for (const GeometryInstanceGroup &set_group : set_groups) {
- const GeometrySet &set = set_group.geometry_set;
- const MeshComponent &component = *set.get_component_for_read<MeshComponent>();
- const Mesh &mesh = *component.get_for_read();
- const VArray<float> density_factors = component.attribute_get_for_read<float>(
- density_attribute_name, ATTR_DOMAIN_CORNER, use_one_default ? 1.0f : 0.0f);
-
- for ([[maybe_unused]] const int i_set_instance : set_group.transforms.index_range()) {
- Vector<float3> &positions = positions_all[i_instance];
- Vector<float3> &bary_coords = bary_coords_all[i_instance];
- Vector<int> &looptri_indices = looptri_indices_all[i_instance];
-
- const int offset = instance_start_offsets[i_instance];
- update_elimination_mask_based_on_density_factors(
- mesh,
- density_factors,
- bary_coords,
- looptri_indices,
- elimination_mask.as_mutable_span().slice(offset, positions.size()));
-
- eliminate_points_based_on_mask(elimination_mask.as_span().slice(offset, positions.size()),
- positions,
- bary_coords,
- looptri_indices);
-
- i_instance++;
- }
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- const GeometryNodePointDistributeMode distribute_method =
- static_cast<GeometryNodePointDistributeMode>(params.node().custom1);
-
- const int seed = params.get_input<int>("Seed") * 5383843;
- const float density = params.extract_input<float>("Density Max");
- const std::string density_attribute_name = params.extract_input<std::string>(
- "Density Attribute");
-
- if (density <= 0.0f) {
- params.set_default_remaining_outputs();
- return;
- }
-
- Vector<GeometryInstanceGroup> set_groups;
- geometry_set_gather_instances(geometry_set, set_groups);
- if (set_groups.is_empty()) {
- params.set_default_remaining_outputs();
- return;
- }
-
- /* Remove any set inputs that don't contain a mesh, to avoid checking later on. */
- for (int i = set_groups.size() - 1; i >= 0; i--) {
- const GeometrySet &set = set_groups[i].geometry_set;
- if (!set.has_mesh()) {
- set_groups.remove_and_reorder(i);
- }
- }
-
- if (set_groups.is_empty()) {
- params.error_message_add(NodeWarningType::Error, TIP_("Input geometry must contain a mesh"));
- params.set_default_remaining_outputs();
- return;
- }
-
- int instances_len = 0;
- for (GeometryInstanceGroup &set_group : set_groups) {
- instances_len += set_group.transforms.size();
- }
-
- /* Store data per-instance in order to simplify attribute access after the scattering,
- * and to make the point elimination simpler for the poisson disk mode. Note that some
- * vectors will be empty if any instances don't contain mesh data. */
- Array<Vector<float3>> positions_all(instances_len);
- Array<Vector<float3>> bary_coords_all(instances_len);
- Array<Vector<int>> looptri_indices_all(instances_len);
-
- switch (distribute_method) {
- case GEO_NODE_POINT_DISTRIBUTE_RANDOM: {
- distribute_points_random(set_groups,
- density_attribute_name,
- density,
- seed,
- positions_all,
- bary_coords_all,
- looptri_indices_all);
- break;
- }
- case GEO_NODE_POINT_DISTRIBUTE_POISSON: {
- const float minimum_distance = params.extract_input<float>("Distance Min");
- distribute_points_poisson_disk(set_groups,
- density_attribute_name,
- density,
- seed,
- minimum_distance,
- positions_all,
- bary_coords_all,
- looptri_indices_all);
- break;
- }
- }
-
- int final_points_len = 0;
- Array<int> instance_start_offsets(set_groups.size());
- for (const int i : positions_all.index_range()) {
- Vector<float3> &positions = positions_all[i];
- instance_start_offsets[i] = final_points_len;
- final_points_len += positions.size();
- }
-
- if (final_points_len == 0) {
- params.set_default_remaining_outputs();
- return;
- }
-
- PointCloud *pointcloud = BKE_pointcloud_new_nomain(final_points_len);
- for (const int instance_index : positions_all.index_range()) {
- const int offset = instance_start_offsets[instance_index];
- Span<float3> positions = positions_all[instance_index];
- memcpy(pointcloud->co + offset, positions.data(), sizeof(float3) * positions.size());
- }
-
- uninitialized_fill_n(pointcloud->radius, pointcloud->totpoint, 0.05f);
-
- GeometrySet geometry_set_out = GeometrySet::create_with_pointcloud(pointcloud);
- PointCloudComponent &point_component =
- geometry_set_out.get_component_for_write<PointCloudComponent>();
-
- Map<AttributeIDRef, AttributeKind> attributes;
- bke::geometry_set_gather_instances_attribute_info(
- set_groups, {GEO_COMPONENT_TYPE_MESH}, {"position", "normal", "id"}, attributes);
- add_remaining_point_attributes(set_groups,
- instance_start_offsets,
- attributes,
- point_component,
- bary_coords_all,
- looptri_indices_all);
-
- params.set_output("Geometry", std::move(geometry_set_out));
-}
-
-} // namespace blender::nodes::node_geo_legacy_point_distribute_cc
-
-void register_node_type_geo_point_distribute()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_point_distribute_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_POINT_DISTRIBUTE, "Point Distribute", NODE_CLASS_GEOMETRY);
- node_type_update(&ntype, file_ns::node_point_distribute_update);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc
deleted file mode 100644
index 3d31773300d..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "DNA_collection_types.h"
-
-#include "BLI_hash.h"
-#include "BLI_task.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_point_instance_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Object>(N_("Object")).hide_label();
- b.add_input<decl::Collection>(N_("Collection")).hide_label();
- b.add_input<decl::Geometry>(N_("Instance Geometry"));
- b.add_input<decl::Int>(N_("Seed")).min(-10000).max(10000);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiItemR(layout, ptr, "instance_type", 0, "", ICON_NONE);
- if (RNA_enum_get(ptr, "instance_type") == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) {
- uiItemR(layout, ptr, "use_whole_collection", 0, nullptr, ICON_NONE);
- }
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryPointInstance *data = MEM_cnew<NodeGeometryPointInstance>(__func__);
- data->instance_type = GEO_NODE_POINT_INSTANCE_TYPE_OBJECT;
- data->flag |= GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- bNodeSocket *object_socket = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
- bNodeSocket *collection_socket = object_socket->next;
- bNodeSocket *instance_geometry_socket = collection_socket->next;
- bNodeSocket *seed_socket = instance_geometry_socket->next;
-
- NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node->storage;
- GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)node_storage->instance_type;
- const bool use_whole_collection = (node_storage->flag &
- GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION) != 0;
-
- nodeSetSocketAvailability(ntree, object_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_OBJECT);
- nodeSetSocketAvailability(
- ntree, collection_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION);
- nodeSetSocketAvailability(
- ntree, instance_geometry_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_GEOMETRY);
- nodeSetSocketAvailability(ntree,
- seed_socket,
- type == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION &&
- !use_whole_collection);
-}
-
-static Vector<InstanceReference> get_instance_references__object(GeoNodeExecParams &params)
-{
- Object *object = params.extract_input<Object *>("Object");
- if (object == params.self_object()) {
- return {};
- }
- if (object != nullptr) {
- return {*object};
- }
- return {};
-}
-
-static Vector<InstanceReference> get_instance_references__collection(GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
-
- Collection *collection = params.get_input<Collection *>("Collection");
- if (collection == nullptr) {
- return {};
- }
-
- if (BLI_listbase_is_empty(&collection->children) &&
- BLI_listbase_is_empty(&collection->gobject)) {
- params.error_message_add(NodeWarningType::Info, TIP_("Collection is empty"));
- return {};
- }
-
- if (node_storage->flag & GEO_NODE_POINT_INSTANCE_WHOLE_COLLECTION) {
- return {*collection};
- }
-
- Vector<InstanceReference> references;
- /* Direct child objects are instanced as objects. */
- LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
- references.append(*cob->ob);
- }
- /* Direct child collections are instanced as collections. */
- LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- references.append(*child->collection);
- }
-
- return references;
-}
-
-static Vector<InstanceReference> get_instance_references__geometry(GeoNodeExecParams &params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Instance Geometry");
- geometry_set.ensure_owns_direct_data();
- return {std::move(geometry_set)};
-}
-
-static Vector<InstanceReference> get_instance_references(GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
- const GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)
- node_storage->instance_type;
-
- switch (type) {
- case GEO_NODE_POINT_INSTANCE_TYPE_OBJECT: {
- return get_instance_references__object(params);
- }
- case GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION: {
- return get_instance_references__collection(params);
- }
- case GEO_NODE_POINT_INSTANCE_TYPE_GEOMETRY: {
- return get_instance_references__geometry(params);
- }
- }
- return {};
-}
-
-/**
- * Add the instance references to the component as a separate step from actually creating the
- * instances in order to avoid a map lookup for every transform. While this might add some
- * unnecessary references if they are not chosen while adding transforms, in the common cases
- * there are many more transforms than there are references, so that isn't likely.
- */
-static Array<int> add_instance_references(InstancesComponent &instance_component,
- Span<InstanceReference> possible_references)
-{
- Array<int> possible_handles(possible_references.size());
- for (const int i : possible_references.index_range()) {
- possible_handles[i] = instance_component.add_reference(possible_references[i]);
- }
- return possible_handles;
-}
-
-static void add_instances_from_component(InstancesComponent &instances,
- const GeometryComponent &src_geometry,
- Span<int> possible_handles,
- const GeoNodeExecParams &params)
-{
- const AttributeDomain domain = ATTR_DOMAIN_POINT;
-
- const int domain_size = src_geometry.attribute_domain_size(domain);
- if (domain_size == 0) {
- return;
- }
-
- VArray<float3> positions = src_geometry.attribute_get_for_read<float3>(
- "position", domain, {0, 0, 0});
- VArray<float3> rotations = src_geometry.attribute_get_for_read<float3>(
- "rotation", domain, {0, 0, 0});
- VArray<float3> scales = src_geometry.attribute_get_for_read<float3>("scale", domain, {1, 1, 1});
- VArray<int> id_attribute = src_geometry.attribute_get_for_read<int>("id", domain, -1);
-
- /* The initial size of the component might be non-zero if there are two component types. */
- const int start_len = instances.instances_amount();
- instances.resize(start_len + domain_size);
- MutableSpan<int> handles = instances.instance_reference_handles().slice(start_len, domain_size);
- MutableSpan<float4x4> transforms = instances.instance_transforms().slice(start_len, domain_size);
- OutputAttribute_Typed<int> instance_id_attribute =
- instances.attribute_try_get_for_output_only<int>("id", ATTR_DOMAIN_INSTANCE);
- MutableSpan<int> instance_ids = instance_id_attribute.as_span();
-
- /* Skip all of the randomness handling if there is only a single possible instance
- * (anything except for collection mode with "Whole Collection" turned off). */
- if (possible_handles.size() == 1) {
- const int handle = possible_handles.first();
- threading::parallel_for(IndexRange(domain_size), 1024, [&](IndexRange range) {
- for (const int i : range) {
- handles[i] = handle;
- transforms[i] = float4x4::from_loc_eul_scale(positions[i], rotations[i], scales[i]);
- instance_ids[i] = id_attribute[i];
- }
- });
- }
- else {
- const int seed = params.get_input<int>("Seed");
- Array<uint32_t> ids = get_geometry_element_ids_as_uints(src_geometry, ATTR_DOMAIN_POINT);
- threading::parallel_for(IndexRange(domain_size), 1024, [&](IndexRange range) {
- for (const int i : range) {
- const int index = BLI_hash_int_2d(ids[i], seed) % possible_handles.size();
- const int handle = possible_handles[index];
- handles[i] = handle;
- transforms[i] = float4x4::from_loc_eul_scale(positions[i], rotations[i], scales[i]);
- instance_ids[i] = id_attribute[i];
- }
- });
- }
-
- instance_id_attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- GeometrySet geometry_set_out;
-
- /* TODO: This node should be able to instance on the input instances component
- * rather than making the entire input geometry set real. */
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- const Vector<InstanceReference> possible_references = get_instance_references(params);
- if (possible_references.is_empty()) {
- params.set_output("Geometry", std::move(geometry_set_out));
- return;
- }
-
- InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
- Array<int> possible_handles = add_instance_references(instances, possible_references);
-
- if (geometry_set.has<MeshComponent>()) {
- add_instances_from_component(instances,
- *geometry_set.get_component_for_read<MeshComponent>(),
- possible_handles,
- params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- add_instances_from_component(instances,
- *geometry_set.get_component_for_read<PointCloudComponent>(),
- possible_handles,
- params);
- }
- if (geometry_set.has<CurveComponent>()) {
- add_instances_from_component(instances,
- *geometry_set.get_component_for_read<CurveComponent>(),
- possible_handles,
- params);
- }
-
- params.set_output("Geometry", std::move(geometry_set_out));
-}
-
-} // namespace blender::nodes::node_geo_legacy_point_instance_cc
-
-void register_node_type_geo_point_instance()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_point_instance_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_POINT_INSTANCE, "Point Instance", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_storage(
- &ntype, "NodeGeometryPointInstance", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_update(&ntype, file_ns::node_update);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc
deleted file mode 100644
index 2895c15cb8c..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BLI_math_rotation.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_point_rotate_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Axis"));
- b.add_input<decl::Vector>(N_("Axis"), "Axis_001")
- .default_value({0.0, 0.0, 1.0})
- .subtype(PROP_XYZ);
- b.add_input<decl::String>(N_("Angle"));
- b.add_input<decl::Float>(N_("Angle"), "Angle_001").subtype(PROP_ANGLE);
- b.add_input<decl::String>(N_("Rotation"));
- b.add_input<decl::Vector>(N_("Rotation"), "Rotation_001").subtype(PROP_EULER);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- NodeGeometryRotatePoints *storage = (NodeGeometryRotatePoints *)((bNode *)ptr->data)->storage;
-
- uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
-
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
-
- uiLayout *col = uiLayoutColumn(layout, false);
- if (storage->type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE) {
- uiItemR(col, ptr, "input_type_axis", 0, IFACE_("Axis"), ICON_NONE);
- uiItemR(col, ptr, "input_type_angle", 0, IFACE_("Angle"), ICON_NONE);
- }
- else {
- uiItemR(col, ptr, "input_type_rotation", 0, IFACE_("Rotation"), ICON_NONE);
- }
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometryRotatePoints *node_storage = MEM_cnew<NodeGeometryRotatePoints>(__func__);
-
- node_storage->type = GEO_NODE_POINT_ROTATE_TYPE_EULER;
- node_storage->space = GEO_NODE_POINT_ROTATE_SPACE_OBJECT;
- node_storage->input_type_axis = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- node_storage->input_type_angle = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node_storage->input_type_rotation = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
-
- node->storage = node_storage;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryRotatePoints *node_storage = (NodeGeometryRotatePoints *)node->storage;
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Axis",
- (GeometryNodeAttributeInputMode)node_storage->input_type_axis,
- node_storage->type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE);
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Angle",
- (GeometryNodeAttributeInputMode)node_storage->input_type_angle,
- node_storage->type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE);
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Rotation",
- (GeometryNodeAttributeInputMode)node_storage->input_type_rotation,
- node_storage->type == GEO_NODE_POINT_ROTATE_TYPE_EULER);
-}
-
-static void point_rotate__axis_angle__object_space(const int domain_size,
- const VArray<float3> &axis,
- const VArray<float> &angles,
- MutableSpan<float3> rotations)
-{
- for (const int i : IndexRange(domain_size)) {
- float old_rotation[3][3];
- eul_to_mat3(old_rotation, rotations[i]);
- float rotation[3][3];
- axis_angle_to_mat3(rotation, axis[i], angles[i]);
- float new_rotation[3][3];
- mul_m3_m3m3(new_rotation, rotation, old_rotation);
- mat3_to_eul(rotations[i], new_rotation);
- }
-}
-
-static void point_rotate__axis_angle__point_space(const int domain_size,
- const VArray<float3> &axis,
- const VArray<float> &angles,
- MutableSpan<float3> rotations)
-{
- for (const int i : IndexRange(domain_size)) {
- float old_rotation[3][3];
- eul_to_mat3(old_rotation, rotations[i]);
- float rotation[3][3];
- axis_angle_to_mat3(rotation, axis[i], angles[i]);
- float new_rotation[3][3];
- mul_m3_m3m3(new_rotation, old_rotation, rotation);
- mat3_to_eul(rotations[i], new_rotation);
- }
-}
-
-static void point_rotate__euler__object_space(const int domain_size,
- const VArray<float3> &eulers,
- MutableSpan<float3> rotations)
-{
- for (const int i : IndexRange(domain_size)) {
- float old_rotation[3][3];
- eul_to_mat3(old_rotation, rotations[i]);
- float rotation[3][3];
- eul_to_mat3(rotation, eulers[i]);
- float new_rotation[3][3];
- mul_m3_m3m3(new_rotation, rotation, old_rotation);
- mat3_to_eul(rotations[i], new_rotation);
- }
-}
-
-static void point_rotate__euler__point_space(const int domain_size,
- const VArray<float3> &eulers,
- MutableSpan<float3> rotations)
-{
- for (const int i : IndexRange(domain_size)) {
- float old_rotation[3][3];
- eul_to_mat3(old_rotation, rotations[i]);
- float rotation[3][3];
- eul_to_mat3(rotation, eulers[i]);
- float new_rotation[3][3];
- mul_m3_m3m3(new_rotation, old_rotation, rotation);
- mat3_to_eul(rotations[i], new_rotation);
- }
-}
-
-static void point_rotate_on_component(GeometryComponent &component,
- const GeoNodeExecParams &params)
-{
- const bNode &node = params.node();
- const NodeGeometryRotatePoints &storage = *(const NodeGeometryRotatePoints *)node.storage;
-
- OutputAttribute_Typed<float3> rotation_attribute =
- component.attribute_try_get_for_output<float3>("rotation", ATTR_DOMAIN_POINT, {0, 0, 0});
- if (!rotation_attribute) {
- return;
- }
-
- MutableSpan<float3> rotations = rotation_attribute.as_span();
- const int domain_size = rotations.size();
-
- if (storage.type == GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE) {
- VArray<float3> axis = params.get_input_attribute<float3>(
- "Axis", component, ATTR_DOMAIN_POINT, {0, 0, 1});
- VArray<float> angles = params.get_input_attribute<float>(
- "Angle", component, ATTR_DOMAIN_POINT, 0);
-
- if (storage.space == GEO_NODE_POINT_ROTATE_SPACE_OBJECT) {
- point_rotate__axis_angle__object_space(domain_size, axis, angles, rotations);
- }
- else {
- point_rotate__axis_angle__point_space(domain_size, axis, angles, rotations);
- }
- }
- else {
- VArray<float3> eulers = params.get_input_attribute<float3>(
- "Rotation", component, ATTR_DOMAIN_POINT, {0, 0, 0});
-
- if (storage.space == GEO_NODE_POINT_ROTATE_SPACE_OBJECT) {
- point_rotate__euler__object_space(domain_size, eulers, rotations);
- }
- else {
- point_rotate__euler__point_space(domain_size, eulers, rotations);
- }
- }
-
- rotation_attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- point_rotate_on_component(geometry_set.get_component_for_write<MeshComponent>(), params);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- point_rotate_on_component(geometry_set.get_component_for_write<PointCloudComponent>(), params);
- }
- if (geometry_set.has<CurveComponent>()) {
- point_rotate_on_component(geometry_set.get_component_for_write<CurveComponent>(), params);
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_point_rotate_cc
-
-void register_node_type_geo_point_rotate()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_point_rotate_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_POINT_ROTATE, "Point Rotate", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeGeometryRotatePoints", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc
deleted file mode 100644
index b51ef22fb49..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BKE_colorband.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_point_scale_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Factor"));
- b.add_input<decl::Vector>(N_("Factor"), "Factor_001")
- .default_value({1.0f, 1.0f, 1.0f})
- .subtype(PROP_XYZ);
- b.add_input<decl::Float>(N_("Factor"), "Factor_002").default_value(1.0f).min(0.0f);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryPointScale *data = MEM_cnew<NodeGeometryPointScale>(__func__);
-
- data->input_type = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryPointScale &node_storage = *(NodeGeometryPointScale *)node->storage;
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Factor", (GeometryNodeAttributeInputMode)node_storage.input_type);
-}
-
-static void execute_on_component(GeoNodeExecParams params, GeometryComponent &component)
-{
- /* Note that scale doesn't necessarily need to be created with a vector type-- it could also use
- * the highest complexity of the existing attribute's type (if it exists) and the data type used
- * for the factor. But for it's simpler to simply always use float3, since that is usually
- * expected anyway. */
- static const float3 scale_default = float3(1.0f);
- OutputAttribute_Typed<float3> scale_attribute = component.attribute_try_get_for_output(
- "scale", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, &scale_default);
- if (!scale_attribute) {
- return;
- }
-
- const bNode &node = params.node();
- const NodeGeometryPointScale &node_storage = *(const NodeGeometryPointScale *)node.storage;
- const GeometryNodeAttributeInputMode input_type = (GeometryNodeAttributeInputMode)
- node_storage.input_type;
- const CustomDataType data_type = (input_type == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) ? CD_PROP_FLOAT :
- CD_PROP_FLOAT3;
-
- GVArray attribute = params.get_input_attribute(
- "Factor", component, ATTR_DOMAIN_POINT, data_type, nullptr);
- if (!attribute) {
- return;
- }
-
- MutableSpan<float3> scale_span = scale_attribute.as_span();
- if (data_type == CD_PROP_FLOAT) {
- VArray<float> factors = attribute.typed<float>();
- for (const int i : scale_span.index_range()) {
- scale_span[i] = scale_span[i] * factors[i];
- }
- }
- else if (data_type == CD_PROP_FLOAT3) {
- VArray<float3> factors = attribute.typed<float3>();
- for (const int i : scale_span.index_range()) {
- scale_span[i] = scale_span[i] * factors[i];
- }
- }
-
- scale_attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
- }
- if (geometry_set.has<PointCloudComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<PointCloudComponent>());
- }
- if (geometry_set.has<CurveComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<CurveComponent>());
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_point_scale_cc
-
-void register_node_type_geo_point_scale()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_point_scale_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_POINT_SCALE, "Point Scale", NODE_CLASS_GEOMETRY);
-
- ntype.declare = file_ns::node_declare;
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeGeometryPointScale", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc
deleted file mode 100644
index 541be1933af..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BKE_attribute_math.hh"
-#include "BKE_mesh.h"
-#include "BKE_pointcloud.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_pointcloud_types.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes {
-
-template<typename T>
-static void copy_data_based_on_mask(Span<T> data,
- Span<bool> masks,
- const bool invert,
- MutableSpan<T> out_data)
-{
- int offset = 0;
- for (const int i : data.index_range()) {
- if (masks[i] != invert) {
- out_data[offset] = data[i];
- offset++;
- }
- }
-}
-
-void copy_point_attributes_based_on_mask(const GeometryComponent &in_component,
- GeometryComponent &result_component,
- Span<bool> masks,
- const bool invert)
-{
- for (const AttributeIDRef &attribute_id : in_component.attribute_ids()) {
- ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
- const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
-
- /* Only copy point attributes. Theoretically this could interpolate attributes on other
- * domains to the point domain, but that would conflict with attributes that are built-in
- * on other domains, which causes creating the attributes to fail. */
- if (attribute.domain != ATTR_DOMAIN_POINT) {
- continue;
- }
-
- OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
- attribute_id, ATTR_DOMAIN_POINT, data_type);
-
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
- using T = decltype(dummy);
- VArray_Span span{attribute.varray.typed<T>()};
- MutableSpan<T> out_span = result_attribute.as_span<T>();
- copy_data_based_on_mask(span, masks, invert, out_span);
- });
-
- result_attribute.save();
- }
-}
-
-} // namespace blender::nodes
-
-namespace blender::nodes::node_geo_legacy_point_separate_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Mask"));
- b.add_output<decl::Geometry>(N_("Geometry 1"));
- b.add_output<decl::Geometry>(N_("Geometry 2"));
-}
-
-static void create_component_points(GeometryComponent &component, const int total)
-{
- switch (component.type()) {
- case GEO_COMPONENT_TYPE_MESH:
- static_cast<MeshComponent &>(component).replace(BKE_mesh_new_nomain(total, 0, 0, 0, 0));
- break;
- case GEO_COMPONENT_TYPE_POINT_CLOUD:
- static_cast<PointCloudComponent &>(component).replace(BKE_pointcloud_new_nomain(total));
- break;
- default:
- BLI_assert(false);
- break;
- }
-}
-
-static void separate_points_from_component(const GeometryComponent &in_component,
- GeometryComponent &out_component,
- const StringRef mask_name,
- const bool invert)
-{
- if (!in_component.attribute_domain_supported(ATTR_DOMAIN_POINT) ||
- in_component.attribute_domain_size(ATTR_DOMAIN_POINT) == 0) {
- return;
- }
-
- const VArray<bool> mask_attribute = in_component.attribute_get_for_read<bool>(
- mask_name, ATTR_DOMAIN_POINT, false);
- VArray_Span<bool> masks{mask_attribute};
-
- const int total = masks.count(!invert);
- if (total == 0) {
- return;
- }
-
- create_component_points(out_component, total);
-
- copy_point_attributes_based_on_mask(in_component, out_component, masks, invert);
-}
-
-static GeometrySet separate_geometry_set(const GeometrySet &set_in,
- const StringRef mask_name,
- const bool invert)
-{
- GeometrySet set_out;
- for (const GeometryComponent *component : set_in.get_components_for_read()) {
- if (component->type() == GEO_COMPONENT_TYPE_CURVE) {
- /* Don't support the curve component for now, even though it has a point domain. */
- continue;
- }
- GeometryComponent &out_component = set_out.get_component_for_write(component->type());
- separate_points_from_component(*component, out_component, mask_name, invert);
- }
- return set_out;
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- bool wait_for_inputs = false;
- wait_for_inputs |= params.lazy_require_input("Geometry");
- wait_for_inputs |= params.lazy_require_input("Mask");
- if (wait_for_inputs) {
- return;
- }
- const std::string mask_attribute_name = params.get_input<std::string>("Mask");
- GeometrySet geometry_set = params.get_input<GeometrySet>("Geometry");
-
- /* TODO: This is not necessary-- the input geometry set can be read only,
- * but it must be rewritten to handle instance groups. */
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (params.lazy_output_is_required("Geometry 1")) {
- params.set_output("Geometry 1",
- separate_geometry_set(geometry_set, mask_attribute_name, true));
- }
- if (params.lazy_output_is_required("Geometry 2")) {
- params.set_output("Geometry 2",
- separate_geometry_set(geometry_set, mask_attribute_name, false));
- }
-}
-
-} // namespace blender::nodes::node_geo_legacy_point_separate_cc
-
-void register_node_type_geo_point_separate()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_point_separate_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_POINT_SEPARATE, "Point Separate", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.geometry_node_execute_supports_laziness = true;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc
deleted file mode 100644
index c1486da3c2e..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_point_translate_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Translation"));
- b.add_input<decl::Vector>(N_("Translation"), "Translation_001").subtype(PROP_TRANSLATION);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE);
-}
-
-static void execute_on_component(GeoNodeExecParams params, GeometryComponent &component)
-{
- OutputAttribute_Typed<float3> position_attribute =
- component.attribute_try_get_for_output<float3>("position", ATTR_DOMAIN_POINT, {0, 0, 0});
- if (!position_attribute) {
- return;
- }
- VArray<float3> attribute = params.get_input_attribute<float3>(
- "Translation", component, ATTR_DOMAIN_POINT, {0, 0, 0});
-
- for (const int i : attribute.index_range()) {
- position_attribute->set(i, position_attribute->get(i) + attribute[i]);
- }
-
- position_attribute.save();
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
- }
- if (geometry_set.has<PointCloudComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<PointCloudComponent>());
- }
- if (geometry_set.has<CurveComponent>()) {
- execute_on_component(params, geometry_set.get_component_for_write<CurveComponent>());
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryPointTranslate *data = MEM_cnew<NodeGeometryPointTranslate>(__func__);
-
- data->input_type = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryPointTranslate &node_storage = *(NodeGeometryPointTranslate *)node->storage;
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Translation", (GeometryNodeAttributeInputMode)node_storage.input_type);
-}
-
-} // namespace blender::nodes::node_geo_legacy_point_translate_cc
-
-void register_node_type_geo_point_translate()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_point_translate_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_POINT_TRANSLATE, "Point Translate", NODE_CLASS_GEOMETRY);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(&ntype,
- "NodeGeometryPointTranslate",
- node_free_standard_storage,
- node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc
deleted file mode 100644
index c83571f1967..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#ifdef WITH_OPENVDB
-# include <openvdb/openvdb.h>
-# include <openvdb/tools/LevelSetUtil.h>
-# include <openvdb/tools/ParticlesToLevelSet.h>
-#endif
-
-#include "node_geometry_util.hh"
-
-#include "BKE_lib_id.h"
-#include "BKE_volume.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-namespace blender::nodes::node_geo_legacy_points_to_volume_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Float>(N_("Density")).default_value(1.0f).min(0.0f);
- b.add_input<decl::Float>(N_("Voxel Size")).default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE);
- b.add_input<decl::Float>(N_("Voxel Amount")).default_value(64.0f).min(0.0f);
- b.add_input<decl::String>(N_("Radius"));
- b.add_input<decl::Float>(N_("Radius"), "Radius_001").default_value(0.5f).min(0.0f);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_radius", 0, IFACE_("Radius"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometryPointsToVolume *data = MEM_cnew<NodeGeometryPointsToVolume>(__func__);
- data->resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT;
- data->input_type_radius = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node->storage = data;
-
- bNodeSocket *radius_attribute_socket = nodeFindSocket(node, SOCK_IN, "Radius");
- bNodeSocketValueString *radius_attribute_socket_value =
- (bNodeSocketValueString *)radius_attribute_socket->default_value;
- STRNCPY(radius_attribute_socket_value->value, "radius");
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)node->storage;
- bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
- bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
- nodeSetSocketAvailability(ntree,
- voxel_amount_socket,
- data->resolution_mode ==
- GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT);
- nodeSetSocketAvailability(ntree,
- voxel_size_socket,
- data->resolution_mode ==
- GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE);
-
- update_attribute_input_socket_availabilities(
- *ntree, *node, "Radius", (GeometryNodeAttributeInputMode)data->input_type_radius);
-}
-
-#ifdef WITH_OPENVDB
-namespace {
-/* Implements the interface required by #openvdb::tools::ParticlesToLevelSet. */
-struct ParticleList {
- using PosType = openvdb::Vec3R;
-
- Span<float3> positions;
- Span<float> radii;
-
- size_t size() const
- {
- return (size_t)positions.size();
- }
-
- void getPos(size_t n, openvdb::Vec3R &xyz) const
- {
- xyz = &positions[n].x;
- }
-
- void getPosRad(size_t n, openvdb::Vec3R &xyz, openvdb::Real &radius) const
- {
- xyz = &positions[n].x;
- radius = radii[n];
- }
-};
-} // namespace
-
-static openvdb::FloatGrid::Ptr generate_volume_from_points(const Span<float3> positions,
- const Span<float> radii,
- const float density)
-{
- /* Create a new grid that will be filled. #ParticlesToLevelSet requires the background value to
- * be positive. It will be set to zero later on. */
- openvdb::FloatGrid::Ptr new_grid = openvdb::FloatGrid::create(1.0f);
-
- /* Create a narrow-band level set grid based on the positions and radii. */
- openvdb::tools::ParticlesToLevelSet op{*new_grid};
- /* Don't ignore particles based on their radius. */
- op.setRmin(0.0f);
- op.setRmax(FLT_MAX);
- ParticleList particles{positions, radii};
- op.rasterizeSpheres(particles);
- op.finalize();
-
- /* Convert the level set to a fog volume. This also sets the background value to zero. Inside the
- * fog there will be a density of 1. */
- openvdb::tools::sdfToFogVolume(*new_grid);
-
- /* Take the desired density into account. */
- openvdb::tools::foreach (new_grid->beginValueOn(),
- [&](const openvdb::FloatGrid::ValueOnIter &iter) {
- iter.modifyValue([&](float &value) { value *= density; });
- });
- return new_grid;
-}
-
-static float compute_voxel_size(const GeoNodeExecParams &params,
- Span<float3> positions,
- const float radius)
-{
- const NodeGeometryPointsToVolume &storage =
- *(const NodeGeometryPointsToVolume *)params.node().storage;
-
- if (storage.resolution_mode == GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE) {
- return params.get_input<float>("Voxel Size");
- }
-
- if (positions.is_empty()) {
- return 0.0f;
- }
-
- float3 min, max;
- INIT_MINMAX(min, max);
- minmax_v3v3_v3_array(min, max, (float(*)[3])positions.data(), positions.size());
-
- const float voxel_amount = params.get_input<float>("Voxel Amount");
- if (voxel_amount <= 1) {
- return 0.0f;
- }
-
- /* The voxel size adapts to the final size of the volume. */
- const float diagonal = math::distance(min, max);
- const float extended_diagonal = diagonal + 2.0f * radius;
- const float voxel_size = extended_diagonal / voxel_amount;
- return voxel_size;
-}
-
-static void gather_point_data_from_component(const GeoNodeExecParams &params,
- const GeometryComponent &component,
- Vector<float3> &r_positions,
- Vector<float> &r_radii)
-{
- VArray<float3> positions = component.attribute_get_for_read<float3>(
- "position", ATTR_DOMAIN_POINT, {0, 0, 0});
- VArray<float> radii = params.get_input_attribute<float>(
- "Radius", component, ATTR_DOMAIN_POINT, 0.0f);
-
- for (const int i : positions.index_range()) {
- r_positions.append(positions[i]);
- r_radii.append(radii[i]);
- }
-}
-
-static void convert_to_grid_index_space(const float voxel_size,
- MutableSpan<float3> positions,
- MutableSpan<float> radii)
-{
- const float voxel_size_inv = 1.0f / voxel_size;
- for (const int i : positions.index_range()) {
- positions[i] *= voxel_size_inv;
- /* Better align generated grid with source points. */
- positions[i] -= float3(0.5f);
- radii[i] *= voxel_size_inv;
- }
-}
-
-static void initialize_volume_component_from_points(const GeometrySet &geometry_set_in,
- GeometrySet &geometry_set_out,
- const GeoNodeExecParams &params)
-{
- Vector<float3> positions;
- Vector<float> radii;
-
- if (geometry_set_in.has<MeshComponent>()) {
- gather_point_data_from_component(
- params, *geometry_set_in.get_component_for_read<MeshComponent>(), positions, radii);
- }
- if (geometry_set_in.has<PointCloudComponent>()) {
- gather_point_data_from_component(
- params, *geometry_set_in.get_component_for_read<PointCloudComponent>(), positions, radii);
- }
- if (geometry_set_in.has<CurveComponent>()) {
- gather_point_data_from_component(
- params, *geometry_set_in.get_component_for_read<CurveComponent>(), positions, radii);
- }
-
- const float max_radius = *std::max_element(radii.begin(), radii.end());
- const float voxel_size = compute_voxel_size(params, positions, max_radius);
- if (voxel_size == 0.0f || positions.is_empty()) {
- return;
- }
-
- Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
- BKE_volume_init_grids(volume);
-
- VolumeGrid *c_density_grid = BKE_volume_grid_add(volume, "density", VOLUME_GRID_FLOAT);
- openvdb::FloatGrid::Ptr density_grid = openvdb::gridPtrCast<openvdb::FloatGrid>(
- BKE_volume_grid_openvdb_for_write(volume, c_density_grid, false));
-
- const float density = params.get_input<float>("Density");
- convert_to_grid_index_space(voxel_size, positions, radii);
- openvdb::FloatGrid::Ptr new_grid = generate_volume_from_points(positions, radii, density);
- /* This merge is cheap, because the #density_grid is empty. */
- density_grid->merge(*new_grid);
- density_grid->transform().postScale(voxel_size);
-
- VolumeComponent &volume_component = geometry_set_out.get_component_for_write<VolumeComponent>();
- volume_component.replace(volume);
-}
-#endif
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set_in = params.extract_input<GeometrySet>("Geometry");
- GeometrySet geometry_set_out;
-
- /* TODO: Read-only access to instances should be supported here, for now they are made real. */
- geometry_set_in = geometry::realize_instances_legacy(geometry_set_in);
-
-#ifdef WITH_OPENVDB
- initialize_volume_component_from_points(geometry_set_in, geometry_set_out, params);
-#endif
-
- params.set_output("Geometry", std::move(geometry_set_out));
-}
-
-} // namespace blender::nodes::node_geo_legacy_points_to_volume_cc
-
-void register_node_type_geo_legacy_points_to_volume()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_points_to_volume_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_POINTS_TO_VOLUME, "Points to Volume", NODE_CLASS_GEOMETRY);
- node_type_storage(&ntype,
- "NodeGeometryPointsToVolume",
- node_free_standard_storage,
- node_copy_standard_storage);
- node_type_size(&ntype, 170, 120, 700);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc
deleted file mode 100644
index 1420edcca0b..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc
+++ /dev/null
@@ -1,313 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "DNA_mesh_types.h"
-
-#include "BKE_bvhutils.h"
-#include "BKE_mesh_sample.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_raycast_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Geometry>(N_("Target Geometry"));
- b.add_input<decl::String>(N_("Ray Direction"));
- b.add_input<decl::Vector>(N_("Ray Direction"), "Ray Direction_001")
- .default_value({0.0f, 0.0f, 1.0f});
- b.add_input<decl::String>(N_("Ray Length"));
- b.add_input<decl::Float>(N_("Ray Length"), "Ray Length_001")
- .default_value(100.0f)
- .min(0.0f)
- .subtype(PROP_DISTANCE);
- b.add_input<decl::String>(N_("Target Attribute"));
- b.add_input<decl::String>(N_("Is Hit"));
- b.add_input<decl::String>(N_("Hit Position"));
- b.add_input<decl::String>(N_("Hit Normal"));
- b.add_input<decl::String>(N_("Hit Distance"));
- b.add_input<decl::String>(N_("Hit Attribute"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "mapping", 0, IFACE_("Mapping"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_ray_direction", 0, IFACE_("Ray Direction"), ICON_NONE);
- uiItemR(layout, ptr, "input_type_ray_length", 0, IFACE_("Ray Length"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryRaycast *data = MEM_cnew<NodeGeometryRaycast>(__func__);
- data->input_type_ray_direction = GEO_NODE_ATTRIBUTE_INPUT_VECTOR;
- data->input_type_ray_length = GEO_NODE_ATTRIBUTE_INPUT_FLOAT;
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryRaycast *node_storage = (NodeGeometryRaycast *)node->storage;
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Ray Direction",
- (GeometryNodeAttributeInputMode)node_storage->input_type_ray_direction);
- update_attribute_input_socket_availabilities(
- *ntree,
- *node,
- "Ray Length",
- (GeometryNodeAttributeInputMode)node_storage->input_type_ray_length);
-}
-
-static void raycast_to_mesh(const Mesh &mesh,
- const VArray<float3> &ray_origins,
- const VArray<float3> &ray_directions,
- const VArray<float> &ray_lengths,
- const MutableSpan<bool> r_hit,
- const MutableSpan<int> r_hit_indices,
- const MutableSpan<float3> r_hit_positions,
- const MutableSpan<float3> r_hit_normals,
- const MutableSpan<float> r_hit_distances)
-{
- BLI_assert(ray_origins.size() == ray_directions.size());
- BLI_assert(ray_origins.size() == ray_lengths.size());
- BLI_assert(ray_origins.size() == r_hit.size() || r_hit.is_empty());
- BLI_assert(ray_origins.size() == r_hit_indices.size() || r_hit_indices.is_empty());
- BLI_assert(ray_origins.size() == r_hit_positions.size() || r_hit_positions.is_empty());
- BLI_assert(ray_origins.size() == r_hit_normals.size() || r_hit_normals.is_empty());
- BLI_assert(ray_origins.size() == r_hit_distances.size() || r_hit_distances.is_empty());
-
- BVHTreeFromMesh tree_data;
- BKE_bvhtree_from_mesh_get(&tree_data, &mesh, BVHTREE_FROM_LOOPTRI, 4);
- if (tree_data.tree == nullptr) {
- free_bvhtree_from_mesh(&tree_data);
- return;
- }
-
- for (const int i : ray_origins.index_range()) {
- const float ray_length = ray_lengths[i];
- const float3 ray_origin = ray_origins[i];
- const float3 ray_direction = math::normalize(ray_directions[i]);
-
- BVHTreeRayHit hit;
- hit.index = -1;
- hit.dist = ray_length;
- if (BLI_bvhtree_ray_cast(tree_data.tree,
- ray_origin,
- ray_direction,
- 0.0f,
- &hit,
- tree_data.raycast_callback,
- &tree_data) != -1) {
- if (!r_hit.is_empty()) {
- r_hit[i] = hit.index >= 0;
- }
- if (!r_hit_indices.is_empty()) {
- /* Index should always be a valid looptri index, use 0 when hit failed. */
- r_hit_indices[i] = max_ii(hit.index, 0);
- }
- if (!r_hit_positions.is_empty()) {
- r_hit_positions[i] = hit.co;
- }
- if (!r_hit_normals.is_empty()) {
- r_hit_normals[i] = hit.no;
- }
- if (!r_hit_distances.is_empty()) {
- r_hit_distances[i] = hit.dist;
- }
- }
- else {
- if (!r_hit.is_empty()) {
- r_hit[i] = false;
- }
- if (!r_hit_indices.is_empty()) {
- r_hit_indices[i] = 0;
- }
- if (!r_hit_positions.is_empty()) {
- r_hit_positions[i] = float3(0.0f, 0.0f, 0.0f);
- }
- if (!r_hit_normals.is_empty()) {
- r_hit_normals[i] = float3(0.0f, 0.0f, 0.0f);
- }
- if (!r_hit_distances.is_empty()) {
- r_hit_distances[i] = ray_length;
- }
- }
- }
-
- free_bvhtree_from_mesh(&tree_data);
-}
-
-static bke::mesh_surface_sample::eAttributeMapMode get_map_mode(
- GeometryNodeRaycastMapMode map_mode)
-{
- switch (map_mode) {
- case GEO_NODE_RAYCAST_INTERPOLATED:
- return bke::mesh_surface_sample::eAttributeMapMode::INTERPOLATED;
- default:
- case GEO_NODE_RAYCAST_NEAREST:
- return bke::mesh_surface_sample::eAttributeMapMode::NEAREST;
- }
-}
-
-static void raycast_from_points(const GeoNodeExecParams &params,
- const GeometrySet &target_geometry,
- GeometryComponent &dst_component,
- const StringRef hit_name,
- const StringRef hit_position_name,
- const StringRef hit_normal_name,
- const StringRef hit_distance_name,
- const Span<std::string> hit_attribute_names,
- const Span<std::string> hit_attribute_output_names)
-{
- BLI_assert(hit_attribute_names.size() == hit_attribute_output_names.size());
-
- const MeshComponent *src_mesh_component =
- target_geometry.get_component_for_read<MeshComponent>();
- if (src_mesh_component == nullptr) {
- return;
- }
- const Mesh *src_mesh = src_mesh_component->get_for_read();
- if (src_mesh == nullptr) {
- return;
- }
- if (src_mesh->totpoly == 0) {
- return;
- }
-
- const NodeGeometryRaycast &storage = *(const NodeGeometryRaycast *)params.node().storage;
- bke::mesh_surface_sample::eAttributeMapMode map_mode = get_map_mode(
- (GeometryNodeRaycastMapMode)storage.mapping);
- const AttributeDomain result_domain = ATTR_DOMAIN_POINT;
-
- VArray<float3> ray_origins = dst_component.attribute_get_for_read<float3>(
- "position", result_domain, {0, 0, 0});
- VArray<float3> ray_directions = params.get_input_attribute<float3>(
- "Ray Direction", dst_component, result_domain, {0, 0, 0});
- VArray<float> ray_lengths = params.get_input_attribute<float>(
- "Ray Length", dst_component, result_domain, 0);
-
- OutputAttribute_Typed<bool> hit_attribute =
- dst_component.attribute_try_get_for_output_only<bool>(hit_name, result_domain);
- OutputAttribute_Typed<float3> hit_position_attribute =
- dst_component.attribute_try_get_for_output_only<float3>(hit_position_name, result_domain);
- OutputAttribute_Typed<float3> hit_normal_attribute =
- dst_component.attribute_try_get_for_output_only<float3>(hit_normal_name, result_domain);
- OutputAttribute_Typed<float> hit_distance_attribute =
- dst_component.attribute_try_get_for_output_only<float>(hit_distance_name, result_domain);
-
- /* Positions and looptri indices are always needed for interpolation,
- * so create temporary arrays if no output attribute is given. */
- Array<int> hit_indices;
- Array<float3> hit_positions_internal;
- if (!hit_attribute_names.is_empty()) {
- hit_indices.reinitialize(ray_origins.size());
-
- if (!hit_position_attribute) {
- hit_positions_internal.reinitialize(ray_origins.size());
- }
- }
- const MutableSpan<bool> is_hit = hit_attribute ? hit_attribute.as_span() : MutableSpan<bool>();
- const MutableSpan<float3> hit_positions = hit_position_attribute ?
- hit_position_attribute.as_span() :
- hit_positions_internal;
- const MutableSpan<float3> hit_normals = hit_normal_attribute ? hit_normal_attribute.as_span() :
- MutableSpan<float3>();
- const MutableSpan<float> hit_distances = hit_distance_attribute ?
- hit_distance_attribute.as_span() :
- MutableSpan<float>();
-
- raycast_to_mesh(*src_mesh,
- ray_origins,
- ray_directions,
- ray_lengths,
- is_hit,
- hit_indices,
- hit_positions,
- hit_normals,
- hit_distances);
-
- hit_attribute.save();
- hit_position_attribute.save();
- hit_normal_attribute.save();
- hit_distance_attribute.save();
-
- /* Custom interpolated attributes */
- bke::mesh_surface_sample::MeshAttributeInterpolator interp(
- src_mesh, IndexMask(ray_origins.size()), hit_positions, hit_indices);
- for (const int i : hit_attribute_names.index_range()) {
- const std::optional<AttributeMetaData> meta_data = src_mesh_component->attribute_get_meta_data(
- hit_attribute_names[i]);
- if (meta_data) {
- ReadAttributeLookup hit_attribute = src_mesh_component->attribute_try_get_for_read(
- hit_attribute_names[i]);
- OutputAttribute hit_attribute_output = dst_component.attribute_try_get_for_output_only(
- hit_attribute_output_names[i], result_domain, meta_data->data_type);
-
- interp.sample_attribute(hit_attribute, hit_attribute_output, map_mode);
-
- hit_attribute_output.save();
- }
- }
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- GeometrySet target_geometry_set = params.extract_input<GeometrySet>("Target Geometry");
-
- const std::string hit_name = params.extract_input<std::string>("Is Hit");
- const std::string hit_position_name = params.extract_input<std::string>("Hit Position");
- const std::string hit_normal_name = params.extract_input<std::string>("Hit Normal");
- const std::string hit_distance_name = params.extract_input<std::string>("Hit Distance");
-
- const Array<std::string> hit_names = {params.extract_input<std::string>("Target Attribute")};
- const Array<std::string> hit_output_names = {params.extract_input<std::string>("Hit Attribute")};
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
- target_geometry_set = geometry::realize_instances_legacy(target_geometry_set);
-
- static const Array<GeometryComponentType> types = {
- GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
- for (const GeometryComponentType type : types) {
- if (geometry_set.has(type)) {
- raycast_from_points(params,
- target_geometry_set,
- geometry_set.get_component_for_write(type),
- hit_name,
- hit_position_name,
- hit_normal_name,
- hit_distance_name,
- hit_names,
- hit_output_names);
- }
- }
-
- params.set_output("Geometry", geometry_set);
-}
-
-} // namespace blender::nodes::node_geo_legacy_raycast_cc
-
-void register_node_type_geo_legacy_raycast()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_raycast_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(&ntype, GEO_NODE_LEGACY_RAYCAST, "Raycast", NODE_CLASS_GEOMETRY);
- node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- node_type_storage(
- &ntype, "NodeGeometryRaycast", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc
deleted file mode 100644
index 150fd56abe3..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "node_geometry_util.hh"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BLI_task.hh"
-
-#include "BKE_material.h"
-
-namespace blender::nodes::node_geo_legacy_select_by_material_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Material>(N_("Material")).hide_label();
- b.add_input<decl::String>(N_("Selection"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void select_mesh_by_material(const Mesh &mesh,
- const Material *material,
- const MutableSpan<bool> r_selection)
-{
- BLI_assert(mesh.totpoly == r_selection.size());
- Vector<int> material_indices;
- for (const int i : IndexRange(mesh.totcol)) {
- if (mesh.mat[i] == material) {
- material_indices.append(i);
- }
- }
- threading::parallel_for(r_selection.index_range(), 1024, [&](IndexRange range) {
- for (const int i : range) {
- r_selection[i] = material_indices.contains(mesh.mpoly[i].mat_nr);
- }
- });
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- Material *material = params.extract_input<Material *>("Material");
- const std::string selection_name = params.extract_input<std::string>("Selection");
-
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (geometry_set.has<MeshComponent>()) {
- MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
- const Mesh *mesh = mesh_component.get_for_read();
- if (mesh != nullptr) {
- OutputAttribute_Typed<bool> selection =
- mesh_component.attribute_try_get_for_output_only<bool>(selection_name, ATTR_DOMAIN_FACE);
- if (selection) {
- select_mesh_by_material(*mesh, material, selection.as_span());
- selection.save();
- }
- }
- }
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_select_by_material_cc
-
-void register_node_type_geo_legacy_select_by_material()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_select_by_material_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_SELECT_BY_MATERIAL, "Select by Material", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc
deleted file mode 100644
index 9eef4b84c36..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "BKE_mesh.h"
-#include "BKE_subdiv.h"
-#include "BKE_subdiv_mesh.h"
-
-#include "DNA_modifier_types.h"
-#include "UI_interface.h"
-#include "UI_resources.h"
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_legacy_subdivision_surface_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Int>(N_("Level")).default_value(1).min(0).max(6);
- b.add_input<decl::Bool>(N_("Use Creases"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
-#ifdef WITH_OPENSUBDIV
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "uv_smooth", 0, nullptr, ICON_NONE);
- uiItemR(layout, ptr, "boundary_smooth", 0, nullptr, ICON_NONE);
-#else
- UNUSED_VARS(layout, ptr);
-#endif
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometrySubdivisionSurface *data = MEM_cnew<NodeGeometrySubdivisionSurface>(__func__);
- data->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES;
- data->boundary_smooth = SUBSURF_BOUNDARY_SMOOTH_ALL;
- node->storage = data;
-}
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
-
- geometry_set = geometry::realize_instances_legacy(geometry_set);
-
- if (!geometry_set.has_mesh()) {
- params.set_output("Geometry", geometry_set);
- return;
- }
-
-#ifndef WITH_OPENSUBDIV
- params.error_message_add(NodeWarningType::Error,
- TIP_("Disabled, Blender was compiled without OpenSubdiv"));
-#else
- const NodeGeometrySubdivisionSurface &storage =
- *(const NodeGeometrySubdivisionSurface *)params.node().storage;
- const int uv_smooth = storage.uv_smooth;
- const int boundary_smooth = storage.boundary_smooth;
- const int subdiv_level = clamp_i(params.extract_input<int>("Level"), 0, 30);
-
- /* Only process subdivision if level is greater than 0. */
- if (subdiv_level == 0) {
- params.set_output("Geometry", std::move(geometry_set));
- return;
- }
-
- const bool use_crease = params.extract_input<bool>("Use Creases");
- const Mesh *mesh_in = geometry_set.get_mesh_for_read();
-
- /* Initialize mesh settings. */
- SubdivToMeshSettings mesh_settings;
- mesh_settings.resolution = (1 << subdiv_level) + 1;
- mesh_settings.use_optimal_display = false;
-
- /* Initialize subdivision settings. */
- SubdivSettings subdiv_settings;
- subdiv_settings.is_simple = false;
- subdiv_settings.is_adaptive = false;
- subdiv_settings.use_creases = use_crease;
- subdiv_settings.level = subdiv_level;
-
- subdiv_settings.vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf(
- boundary_smooth);
- subdiv_settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth(
- uv_smooth);
-
- /* Apply subdivision to mesh. */
- Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, mesh_in);
-
- /* In case of bad topology, skip to input mesh. */
- if (subdiv == nullptr) {
- params.set_output("Geometry", std::move(geometry_set));
- return;
- }
-
- Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
- BKE_mesh_normals_tag_dirty(mesh_out);
-
- MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
- mesh_component.replace(mesh_out);
-
- // BKE_subdiv_stats_print(&subdiv->stats);
- BKE_subdiv_free(subdiv);
-
-#endif
-
- params.set_output("Geometry", std::move(geometry_set));
-}
-
-} // namespace blender::nodes::node_geo_legacy_subdivision_surface_cc
-
-void register_node_type_geo_legacy_subdivision_surface()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_subdivision_surface_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_SUBDIVISION_SURFACE, "Subdivision Surface", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- node_type_init(&ntype, file_ns::node_init);
- node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_storage(&ntype,
- "NodeGeometrySubdivisionSurface",
- node_free_standard_storage,
- node_copy_standard_storage);
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc
deleted file mode 100644
index 768932a7fe7..00000000000
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#include "DEG_depsgraph_query.h"
-#ifdef WITH_OPENVDB
-# include <openvdb/tools/GridTransformer.h>
-# include <openvdb/tools/VolumeToMesh.h>
-#endif
-
-#include "node_geometry_util.hh"
-
-#include "BKE_lib_id.h"
-#include "BKE_material.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
-#include "BKE_volume.h"
-#include "BKE_volume_to_mesh.hh"
-
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-namespace blender::nodes::node_geo_legacy_volume_to_mesh_cc {
-
-static void node_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::String>(N_("Density"));
- b.add_input<decl::Float>(N_("Voxel Size")).default_value(0.3f).min(0.01f).subtype(PROP_DISTANCE);
- b.add_input<decl::Float>(N_("Voxel Amount")).default_value(64.0f).min(0.0f);
- b.add_input<decl::Float>(N_("Threshold")).default_value(0.1f).min(0.0f);
- b.add_input<decl::Float>(N_("Adaptivity")).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "resolution_mode", 0, IFACE_("Resolution"), ICON_NONE);
-}
-
-static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometryVolumeToMesh *data = MEM_cnew<NodeGeometryVolumeToMesh>(__func__);
- data->resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_GRID;
-
- bNodeSocket *grid_socket = nodeFindSocket(node, SOCK_IN, "Density");
- bNodeSocketValueString *grid_socket_value = (bNodeSocketValueString *)grid_socket->default_value;
- STRNCPY(grid_socket_value->value, "density");
-
- node->storage = data;
-}
-
-static void node_update(bNodeTree *ntree, bNode *node)
-{
- NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)node->storage;
-
- bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
- bNodeSocket *voxel_amount_socket = nodeFindSocket(node, SOCK_IN, "Voxel Amount");
- nodeSetSocketAvailability(ntree,
- voxel_amount_socket,
- data->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT);
- nodeSetSocketAvailability(ntree,
- voxel_size_socket,
- data->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE);
-}
-
-#ifdef WITH_OPENVDB
-
-static void create_mesh_from_volume(GeometrySet &geometry_set_in,
- GeometrySet &geometry_set_out,
- GeoNodeExecParams &params)
-{
- if (!geometry_set_in.has<VolumeComponent>()) {
- return;
- }
-
- const NodeGeometryVolumeToMesh &storage =
- *(const NodeGeometryVolumeToMesh *)params.node().storage;
-
- bke::VolumeToMeshResolution resolution;
- resolution.mode = (VolumeToMeshResolutionMode)storage.resolution_mode;
- if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT) {
- resolution.settings.voxel_amount = params.get_input<float>("Voxel Amount");
- if (resolution.settings.voxel_amount <= 0.0f) {
- return;
- }
- }
- else if (resolution.mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE) {
- resolution.settings.voxel_size = params.get_input<float>("Voxel Size");
- if (resolution.settings.voxel_size <= 0.0f) {
- return;
- }
- }
-
- const VolumeComponent *component = geometry_set_in.get_component_for_read<VolumeComponent>();
- const Volume *volume = component->get_for_read();
- if (volume == nullptr) {
- return;
- }
-
- const Main *bmain = DEG_get_bmain(params.depsgraph());
- BKE_volume_load(volume, bmain);
-
- const std::string grid_name = params.get_input<std::string>("Density");
- const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, grid_name.c_str());
- if (volume_grid == nullptr) {
- return;
- }
-
- float threshold = params.get_input<float>("Threshold");
- float adaptivity = params.get_input<float>("Adaptivity");
-
- const openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
- Mesh *mesh = bke::volume_to_mesh(*grid, resolution, threshold, adaptivity);
- if (mesh == nullptr) {
- return;
- }
- BKE_id_material_eval_ensure_default_slot(&mesh->id);
- MeshComponent &dst_component = geometry_set_out.get_component_for_write<MeshComponent>();
- dst_component.replace(mesh);
-}
-
-#endif /* WITH_OPENVDB */
-
-static void node_geo_exec(GeoNodeExecParams params)
-{
- GeometrySet geometry_set_in = params.extract_input<GeometrySet>("Geometry");
- GeometrySet geometry_set_out;
-
-#ifdef WITH_OPENVDB
- create_mesh_from_volume(geometry_set_in, geometry_set_out, params);
-#else
- params.error_message_add(NodeWarningType::Error,
- TIP_("Disabled, Blender was compiled without OpenVDB"));
-#endif
-
- params.set_output("Geometry", geometry_set_out);
-}
-
-} // namespace blender::nodes::node_geo_legacy_volume_to_mesh_cc
-
-void register_node_type_geo_legacy_volume_to_mesh()
-{
- namespace file_ns = blender::nodes::node_geo_legacy_volume_to_mesh_cc;
-
- static bNodeType ntype;
-
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_VOLUME_TO_MESH, "Volume to Mesh", NODE_CLASS_GEOMETRY);
- ntype.declare = file_ns::node_declare;
- node_type_storage(
- &ntype, "NodeGeometryVolumeToMesh", node_free_standard_storage, node_copy_standard_storage);
- node_type_size(&ntype, 170, 120, 700);
- node_type_init(&ntype, file_ns::node_init);
- node_type_update(&ntype, file_ns::node_update);
- ntype.geometry_node_execute = file_ns::node_geo_exec;
- ntype.draw_buttons = file_ns::node_layout;
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
index 1eb18b2f910..5955fe1f3b1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
@@ -12,19 +12,6 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
-void curve_create_default_rotation_attribute(Span<float3> tangents,
- Span<float3> normals,
- MutableSpan<float3> rotations)
-{
- threading::parallel_for(IndexRange(rotations.size()), 512, [&](IndexRange range) {
- for (const int i : range) {
- rotations[i] =
- float4x4::from_normalized_axis_data({0, 0, 0}, normals[i], tangents[i]).to_euler();
- }
- });
-}
-} // namespace blender::nodes
namespace blender::nodes::node_geo_curve_to_points_cc {
@@ -76,6 +63,19 @@ static void node_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, length_socket, mode == GEO_NODE_CURVE_RESAMPLE_LENGTH);
}
+static void curve_create_default_rotation_attribute(Span<float3> tangents,
+ Span<float3> normals,
+ MutableSpan<float3> rotations)
+{
+ threading::parallel_for(IndexRange(rotations.size()), 512, [&](IndexRange range) {
+ for (const int i : range) {
+ rotations[i] =
+ float4x4::from_normalized_axis_data({0, 0, 0}, normals[i], tangents[i]).to_euler();
+ }
+ });
+}
+
+
static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
const GeometryNodeCurveResampleMode mode,
const CurveEval &curve,