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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-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,