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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/geometry')
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt97
-rw-r--r--source/blender/nodes/geometry/node_geometry_tree.cc11
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.cc37
-rw-r--r--source/blender/nodes/geometry/node_geometry_util.hh10
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_align_rotation_to_vector.cc)30
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_clamp.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_color_ramp.cc)26
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_combine_xyz.cc)30
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_compare.cc)42
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_convert.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_curve_map.cc)44
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_fill.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_map_range.cc)24
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_math.cc)35
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_mix.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_proximity.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_randomize.cc)94
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_sample_texture.cc)16
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_separate_xyz.cc)30
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_transfer.cc)32
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_vector_math.cc)36
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_vector_rotate.cc)30
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_endpoints.cc)22
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_reverse.cc)16
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_select_by_handle_type.cc)26
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_set_handles.cc)26
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_spline_type.cc)26
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_curve_to_points.cc)126
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_delete_geometry.cc)46
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_edge_split.cc)16
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_material_assign.cc)16
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_mesh_to_curve.cc)20
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_point_distribute.cc)32
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_point_instance.cc)37
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_point_rotate.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_point_scale.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_point_separate.cc)32
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_point_translate.cc)28
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_points_to_volume.cc)30
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_raycast.cc)30
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_select_by_material.cc)16
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_subdivision_surface.cc)26
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc (renamed from source/blender/nodes/geometry/nodes/legacy/node_geo_volume_to_mesh.cc)26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc96
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc155
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc172
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collection_info.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_common.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc94
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc50
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc77
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_length.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc31
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc49
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc43
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadratic_bezier.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc81
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc44
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc68
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc33
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc (renamed from source/blender/nodes/geometry/nodes/node_geo_curve_parameter.cc)127
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc67
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc88
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc81
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc342
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc847
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_edge_split.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc55
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_image_texture.cc42
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_id.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_index.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_material.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_material_index.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc93
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc188
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc96
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc158
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc101
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc155
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_normal.cc59
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_position.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_radius.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc50
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc111
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc40
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc130
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc72
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc361
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_replace.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_selection.cc65
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc37
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc183
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc106
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc64
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc66
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc140
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc47
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_object_info.cc41
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc16
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc56
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_proximity.cc32
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_raycast.cc88
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc36
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_separate_components.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc54
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_id.cc32
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_material.cc58
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc27
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc122
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc28
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc30
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_string_join.cc14
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc44
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_switch.cc79
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc112
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc82
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc32
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_triangulate.cc20
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_viewer.cc81
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc53
150 files changed, 5461 insertions, 2868 deletions
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 5ee26260790..f9a64381981 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -39,48 +39,49 @@ set(INC
set(SRC
- nodes/legacy/node_geo_align_rotation_to_vector.cc
- nodes/legacy/node_geo_attribute_clamp.cc
- nodes/legacy/node_geo_attribute_color_ramp.cc
- nodes/legacy/node_geo_attribute_combine_xyz.cc
- nodes/legacy/node_geo_attribute_compare.cc
- nodes/legacy/node_geo_attribute_convert.cc
- nodes/legacy/node_geo_attribute_curve_map.cc
- nodes/legacy/node_geo_attribute_fill.cc
- nodes/legacy/node_geo_attribute_map_range.cc
- nodes/legacy/node_geo_attribute_math.cc
- nodes/legacy/node_geo_attribute_mix.cc
- nodes/legacy/node_geo_attribute_proximity.cc
- nodes/legacy/node_geo_attribute_randomize.cc
- nodes/legacy/node_geo_attribute_sample_texture.cc
- nodes/legacy/node_geo_attribute_separate_xyz.cc
- nodes/legacy/node_geo_attribute_transfer.cc
- nodes/legacy/node_geo_attribute_vector_math.cc
- nodes/legacy/node_geo_attribute_vector_rotate.cc
- nodes/legacy/node_geo_curve_endpoints.cc
- nodes/legacy/node_geo_curve_reverse.cc
- nodes/legacy/node_geo_curve_select_by_handle_type.cc
- nodes/legacy/node_geo_curve_set_handles.cc
- nodes/legacy/node_geo_curve_spline_type.cc
- nodes/legacy/node_geo_curve_subdivide.cc
- nodes/legacy/node_geo_curve_to_points.cc
- nodes/legacy/node_geo_delete_geometry.cc
- nodes/legacy/node_geo_edge_split.cc
- nodes/legacy/node_geo_material_assign.cc
- nodes/legacy/node_geo_mesh_to_curve.cc
- nodes/legacy/node_geo_point_distribute.cc
- nodes/legacy/node_geo_point_instance.cc
- nodes/legacy/node_geo_point_rotate.cc
- nodes/legacy/node_geo_point_scale.cc
- nodes/legacy/node_geo_point_separate.cc
- nodes/legacy/node_geo_point_translate.cc
- nodes/legacy/node_geo_points_to_volume.cc
- nodes/legacy/node_geo_raycast.cc
- nodes/legacy/node_geo_select_by_material.cc
- nodes/legacy/node_geo_subdivision_surface.cc
- nodes/legacy/node_geo_volume_to_mesh.cc
+ 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_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_attribute_capture.cc
+ nodes/node_geo_attribute_domain_size.cc
nodes/node_geo_attribute_remove.cc
nodes/node_geo_attribute_statistic.cc
nodes/node_geo_boolean.cc
@@ -93,7 +94,6 @@ set(SRC
nodes/node_geo_curve_fillet.cc
nodes/node_geo_curve_handle_type_selection.cc
nodes/node_geo_curve_length.cc
- nodes/node_geo_curve_parameter.cc
nodes/node_geo_curve_primitive_bezier_segment.cc
nodes/node_geo_curve_primitive_circle.cc
nodes/node_geo_curve_primitive_line.cc
@@ -106,13 +106,16 @@ set(SRC
nodes/node_geo_curve_sample.cc
nodes/node_geo_curve_set_handles.cc
nodes/node_geo_curve_spline_type.cc
+ nodes/node_geo_curve_spline_parameter.cc
nodes/node_geo_curve_subdivide.cc
nodes/node_geo_curve_to_mesh.cc
nodes/node_geo_curve_to_points.cc
nodes/node_geo_curve_trim.cc
nodes/node_geo_delete_geometry.cc
nodes/node_geo_distribute_points_on_faces.cc
+ nodes/node_geo_dual_mesh.cc
nodes/node_geo_edge_split.cc
+ nodes/node_geo_geometry_to_instance.cc
nodes/node_geo_image_texture.cc
nodes/node_geo_input_curve_handles.cc
nodes/node_geo_input_curve_tilt.cc
@@ -120,9 +123,16 @@ set(SRC
nodes/node_geo_input_index.cc
nodes/node_geo_input_material_index.cc
nodes/node_geo_input_material.cc
+ nodes/node_geo_input_mesh_edge_neighbors.cc
+ nodes/node_geo_input_mesh_edge_vertices.cc
+ nodes/node_geo_input_mesh_face_area.cc
+ nodes/node_geo_input_mesh_face_neighbors.cc
+ nodes/node_geo_input_mesh_island.cc
+ nodes/node_geo_input_mesh_vertex_neighbors.cc
nodes/node_geo_input_normal.cc
nodes/node_geo_input_position.cc
nodes/node_geo_input_radius.cc
+ nodes/node_geo_input_scene_time.cc
nodes/node_geo_input_shade_smooth.cc
nodes/node_geo_input_spline_cyclic.cc
nodes/node_geo_input_spline_length.cc
@@ -265,3 +275,8 @@ if(WITH_OPENVDB)
endif()
blender_add_lib(bf_nodes_geometry "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_UNITY_BUILD)
+ set_target_properties(bf_nodes_geometry PROPERTIES UNITY_BUILD ON)
+ set_target_properties(bf_nodes_geometry PROPERTIES UNITY_BUILD_BATCH_SIZE 10)
+endif()
diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc
index 9747bb63773..89ab4d9961e 100644
--- a/source/blender/nodes/geometry/node_geometry_tree.cc
+++ b/source/blender/nodes/geometry/node_geometry_tree.cc
@@ -84,15 +84,16 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
-static bool geometry_node_tree_validate_link(bNodeTree *UNUSED(ntree), bNodeLink *link)
+static bool geometry_node_tree_validate_link(eNodeSocketDatatype type_a,
+ eNodeSocketDatatype type_b)
{
/* Geometry, string, object, material, texture and collection sockets can only be connected to
* themselves. The other types can be converted between each other. */
- if (ELEM(link->fromsock->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT) &&
- ELEM(link->tosock->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT)) {
+ if (ELEM(type_a, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT) &&
+ ELEM(type_b, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT)) {
return true;
}
- return (link->tosock->type == link->fromsock->type);
+ return type_a == type_b;
}
static bool geometry_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
@@ -113,7 +114,7 @@ static bool geometry_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype
SOCK_MATERIAL);
}
-void register_node_tree_type_geo(void)
+void register_node_tree_type_geo()
{
bNodeTreeType *tt = ntreeType_Geometry = static_cast<bNodeTreeType *>(
MEM_callocN(sizeof(bNodeTreeType), "geometry node tree type"));
diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc
index 5c1d507041c..49991a40c1b 100644
--- a/source/blender/nodes/geometry/node_geometry_util.cc
+++ b/source/blender/nodes/geometry/node_geometry_util.cc
@@ -24,17 +24,12 @@
#include "BKE_mesh_runtime.h"
#include "BKE_pointcloud.h"
+#include "NOD_socket_search_link.hh"
+
namespace blender::nodes {
using bke::GeometryInstanceGroup;
-/**
- * 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,
@@ -56,6 +51,31 @@ void update_attribute_input_socket_availabilities(bNodeTree &ntree,
}
}
+std::optional<CustomDataType> node_data_type_to_custom_data_type(const eNodeSocketDatatype type)
+{
+ switch (type) {
+ case SOCK_FLOAT:
+ return CD_PROP_FLOAT;
+ case SOCK_VECTOR:
+ return CD_PROP_FLOAT3;
+ case SOCK_RGBA:
+ return CD_PROP_COLOR;
+ case SOCK_BOOLEAN:
+ return CD_PROP_BOOL;
+ case SOCK_INT:
+ return CD_PROP_INT32;
+ case SOCK_STRING:
+ return CD_PROP_STRING;
+ default:
+ return {};
+ }
+}
+
+std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket)
+{
+ return node_data_type_to_custom_data_type(static_cast<eNodeSocketDatatype>(socket.type));
+}
+
} // namespace blender::nodes
bool geo_node_poll_default(bNodeType *UNUSED(ntype),
@@ -63,7 +83,7 @@ bool geo_node_poll_default(bNodeType *UNUSED(ntype),
const char **r_disabled_hint)
{
if (!STREQ(ntree->idname, "GeometryNodeTree")) {
- *r_disabled_hint = "Not a geometry node tree";
+ *r_disabled_hint = TIP_("Not a geometry node tree");
return false;
}
return true;
@@ -74,4 +94,5 @@ void geo_node_type_base(bNodeType *ntype, int type, const char *name, short ncla
node_type_base(ntype, type, name, nclass, flag);
ntype->poll = geo_node_poll_default;
ntype->insert_link = node_insert_link_default;
+ ntype->gather_link_search_ops = blender::nodes::search_link_ops_for_basic_node;
}
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 79fe2ffc42b..3376b75d05b 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -43,6 +43,13 @@ 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,
@@ -126,4 +133,7 @@ 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);
+
} // namespace blender::nodes
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_align_rotation_to_vector.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc
index dc7c251d034..4366c6f9234 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_align_rotation_to_vector.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_align_rotation_to_vector.cc
@@ -22,9 +22,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_align_rotation_to_vector_cc {
-static void geo_node_align_rotation_to_vector_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Factor"));
@@ -40,9 +40,7 @@ static void geo_node_align_rotation_to_vector_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_align_rotation_to_vector_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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);
@@ -53,7 +51,7 @@ static void geo_node_align_rotation_to_vector_layout(uiLayout *layout,
uiItemR(col, ptr, "input_type_vector", 0, IFACE_("Vector"), ICON_NONE);
}
-static void geo_node_align_rotation_to_vector_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryAlignRotationToVector *node_storage = (NodeGeometryAlignRotationToVector *)
MEM_callocN(sizeof(NodeGeometryAlignRotationToVector), __func__);
@@ -65,7 +63,7 @@ static void geo_node_align_rotation_to_vector_init(bNodeTree *UNUSED(ntree), bNo
node->storage = node_storage;
}
-static void geo_node_align_rotation_to_vector_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryAlignRotationToVector *node_storage = (NodeGeometryAlignRotationToVector *)
node->storage;
@@ -199,11 +197,11 @@ static void align_rotations_on_component(GeometryComponent &component,
rotations.save();
}
-static void geo_node_align_rotation_to_vector_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ 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);
@@ -219,10 +217,12 @@ static void geo_node_align_rotation_to_vector_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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,
@@ -230,14 +230,14 @@ void register_node_type_geo_align_rotation_to_vector()
"Align Rotation to Vector",
NODE_CLASS_GEOMETRY,
0);
- node_type_init(&ntype, blender::nodes::geo_node_align_rotation_to_vector_init);
- node_type_update(&ntype, blender::nodes::geo_node_align_rotation_to_vector_update);
+ 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 = blender::nodes::geo_node_align_rotation_to_vector_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_align_rotation_to_vector_exec;
- ntype.draw_buttons = blender::nodes::geo_node_align_rotation_to_vector_layout;
+ 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_attribute_clamp.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc
index a11a1bd3825..7435152a966 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_clamp.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_clamp.cc
@@ -20,9 +20,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_clamp_cc {
-static void geo_node_attribute_clamp_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute"));
@@ -38,13 +38,13 @@ static void geo_node_attribute_clamp_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_clamp_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+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 geo_node_attribute_clamp_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeClamp *data = (NodeAttributeClamp *)MEM_callocN(sizeof(NodeAttributeClamp),
__func__);
@@ -53,7 +53,7 @@ static void geo_node_attribute_clamp_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_attribute_clamp_update(bNodeTree *ntree, bNode *node)
+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;
@@ -243,11 +243,11 @@ static void clamp_attribute(GeometryComponent &component, const GeoNodeExecParam
attribute_result.save();
}
-static void geo_node_attribute_clamp_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
clamp_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -262,19 +262,21 @@ static void geo_node_attribute_clamp_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_clamp_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_clamp_update);
- ntype.declare = blender::nodes::geo_node_attribute_clamp_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_clamp_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_clamp_layout;
+ 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_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc
index 061f5f3d7ee..4efdf786e4e 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_color_ramp.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_color_ramp.cc
@@ -23,9 +23,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attributes_color_ramp_cc {
-static void geo_node_attribute_color_ramp_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute"));
@@ -33,14 +33,12 @@ static void geo_node_attribute_color_ramp_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_color_ramp_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiTemplateColorRamp(layout, ptr, "color_ramp", false);
}
-static void geo_node_attribute_color_ramp_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeAttributeColorRamp *node_storage = (NodeAttributeColorRamp *)MEM_callocN(
sizeof(NodeAttributeColorRamp), __func__);
@@ -100,11 +98,11 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
attribute_result.save();
}
-static void geo_node_attribute_color_ramp_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
@@ -119,10 +117,12 @@ static void geo_node_attribute_color_ramp_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_legacy_attributes_color_ramp_cc
void register_node_type_geo_attribute_color_ramp()
{
+ namespace file_ns = blender::nodes::node_geo_legacy_attributes_color_ramp_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype,
@@ -132,10 +132,10 @@ void register_node_type_geo_attribute_color_ramp()
0);
node_type_storage(
&ntype, "NodeAttributeColorRamp", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_color_ramp_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- ntype.declare = blender::nodes::geo_node_attribute_color_ramp_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_color_ramp_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_color_ramp_layout;
+ 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_attribute_combine_xyz.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc
index a610356955b..7ba64c8db2b 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_combine_xyz.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_combine_xyz.cc
@@ -19,9 +19,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_combine_xyz_cc {
-static void geo_node_attribute_combine_xyz_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("X"));
@@ -34,9 +34,7 @@ static void geo_node_attribute_combine_xyz_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_combine_xyz_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -46,7 +44,7 @@ static void geo_node_attribute_combine_xyz_layout(uiLayout *layout,
uiItemR(col, ptr, "input_type_z", 0, IFACE_("Z"), ICON_NONE);
}
-static void geo_node_attribute_combine_xyz_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeCombineXYZ *data = (NodeAttributeCombineXYZ *)MEM_callocN(
sizeof(NodeAttributeCombineXYZ), __func__);
@@ -57,7 +55,7 @@ static void geo_node_attribute_combine_xyz_init(bNodeTree *UNUSED(tree), bNode *
node->storage = data;
}
-static void geo_node_attribute_combine_xyz_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeAttributeCombineXYZ *node_storage = (NodeAttributeCombineXYZ *)node->storage;
update_attribute_input_socket_availabilities(
@@ -111,11 +109,11 @@ static void combine_attributes(GeometryComponent &component, const GeoNodeExecPa
attribute_result.save();
}
-static void geo_node_attribute_combine_xyz_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
combine_attributes(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -130,10 +128,12 @@ static void geo_node_attribute_combine_xyz_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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,
@@ -141,13 +141,13 @@ void register_node_type_geo_attribute_combine_xyz()
"Attribute Combine XYZ",
NODE_CLASS_ATTRIBUTE,
0);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_combine_xyz_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_combine_xyz_update);
+ 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 = blender::nodes::geo_node_attribute_combine_xyz_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_combine_xyz_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_combine_xyz_layout;
+ 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_attribute_compare.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc
index a4ffe884999..8aa1adb0cf3 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_compare.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_compare.cc
@@ -21,9 +21,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_compare_cc {
-static void geo_node_attribute_compare_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("A"));
@@ -39,9 +39,7 @@ static void geo_node_attribute_compare_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_compare_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
uiLayoutSetPropSep(layout, true);
@@ -50,11 +48,11 @@ static void geo_node_attribute_compare_layout(uiLayout *layout,
uiItemR(layout, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
}
-static void geo_node_attribute_compare_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeCompare *data = (NodeAttributeCompare *)MEM_callocN(sizeof(NodeAttributeCompare),
__func__);
- data->operation = NODE_FLOAT_COMPARE_GREATER_THAN;
+ 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;
@@ -62,10 +60,10 @@ static void geo_node_attribute_compare_init(bNodeTree *UNUSED(tree), bNode *node
static bool operation_tests_equality(const NodeAttributeCompare &node_storage)
{
- return ELEM(node_storage.operation, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL);
+ return ELEM(node_storage.operation, NODE_COMPARE_EQUAL, NODE_COMPARE_NOT_EQUAL);
}
-static void geo_node_attribute_compare_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeAttributeCompare *node_storage = (NodeAttributeCompare *)node->storage;
update_attribute_input_socket_availabilities(
@@ -79,7 +77,7 @@ static void geo_node_attribute_compare_update(bNodeTree *ntree, bNode *node)
static void do_math_operation(const VArray<float> &input_a,
const VArray<float> &input_b,
- const FloatCompareOperation operation,
+ const NodeCompareOperation operation,
MutableSpan<bool> span_result)
{
const int size = input_a.size();
@@ -243,7 +241,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
{
const bNode &node = params.node();
NodeAttributeCompare *node_storage = (NodeAttributeCompare *)node.storage;
- const FloatCompareOperation operation = static_cast<FloatCompareOperation>(
+ const NodeCompareOperation operation = static_cast<NodeCompareOperation>(
node_storage->operation);
const std::string result_name = params.get_input<std::string>("Result");
@@ -273,7 +271,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
* 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_FLOAT_COMPARE_EQUAL) {
+ 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);
@@ -293,7 +291,7 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
attribute_a.typed<bool>(), attribute_b.typed<bool>(), threshold, result_span);
}
}
- else if (operation == NODE_FLOAT_COMPARE_NOT_EQUAL) {
+ 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);
@@ -322,11 +320,11 @@ static void attribute_compare_calc(GeometryComponent &component, const GeoNodeEx
attribute_result.save();
}
-static void geo_node_attribute_compare_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
attribute_compare_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -341,20 +339,22 @@ static void geo_node_attribute_compare_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_attribute_compare_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_compare_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_compare_layout;
- node_type_update(&ntype, blender::nodes::geo_node_attribute_compare_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_update(&ntype, file_ns::node_update);
node_type_storage(
&ntype, "NodeAttributeCompare", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_compare_init);
+ node_type_init(&ntype, file_ns::node_init);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_convert.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc
index 13ba8d13618..28c133871f7 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_convert.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_convert.cc
@@ -19,9 +19,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_convert_cc {
-static void geo_node_attribute_convert_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute"));
@@ -29,9 +29,7 @@ static void geo_node_attribute_convert_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_convert_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -39,7 +37,7 @@ static void geo_node_attribute_convert_layout(uiLayout *layout,
uiItemR(layout, ptr, "data_type", 0, IFACE_("Type"), ICON_NONE);
}
-static void geo_node_attribute_convert_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeConvert *data = (NodeAttributeConvert *)MEM_callocN(sizeof(NodeAttributeConvert),
__func__);
@@ -130,11 +128,11 @@ static void attribute_convert_calc(GeometryComponent &component,
result_attribute.save();
}
-static void geo_node_attribute_convert_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ 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");
@@ -143,7 +141,7 @@ static void geo_node_attribute_convert_exec(GeoNodeExecParams params)
const AttributeDomain domain = static_cast<AttributeDomain>(node_storage.domain);
if (result_name.empty()) {
- params.set_output("Geometry", geometry_set);
+ params.set_default_remaining_outputs();
return;
}
@@ -175,18 +173,20 @@ static void geo_node_attribute_convert_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_attribute_convert_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_convert_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_convert_layout;
- node_type_init(&ntype, blender::nodes::geo_node_attribute_convert_init);
+ 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);
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_curve_map.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc
index af56df0dc3f..0a7b5dd8463 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_curve_map.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_curve_map.cc
@@ -24,9 +24,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_curve_map_cc {
-static void geo_node_attribute_curve_map_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute"));
@@ -34,9 +34,7 @@ static void geo_node_attribute_curve_map_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_curve_map_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
bNode *node = (bNode *)ptr->data;
@@ -54,7 +52,7 @@ static void geo_node_attribute_curve_map_layout(uiLayout *layout,
}
}
-static void geo_node_attribute_curve_map_free_storage(bNode *node)
+static void node_free_storage(bNode *node)
{
if (node->storage) {
NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
@@ -64,9 +62,9 @@ static void geo_node_attribute_curve_map_free_storage(bNode *node)
}
}
-static void geo_node_attribute_curve_map_copy_storage(bNodeTree *UNUSED(dest_ntree),
- bNode *dest_node,
- const bNode *src_node)
+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;
@@ -75,7 +73,7 @@ static void geo_node_attribute_curve_map_copy_storage(bNodeTree *UNUSED(dest_ntr
dest_data->curve_rgb = BKE_curvemapping_copy(src_data->curve_rgb);
}
-static void geo_node_attribute_curve_map_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)MEM_callocN(sizeof(NodeAttributeCurveMap),
__func__);
@@ -87,7 +85,7 @@ static void geo_node_attribute_curve_map_init(bNodeTree *UNUSED(ntree), bNode *n
node->storage = data;
}
-static void geo_node_attribute_curve_map_update(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_update(bNodeTree *UNUSED(ntree), bNode *node)
{
/* Set the active curve when data type is changed. */
NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)node->storage;
@@ -179,7 +177,7 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
attribute_result.save();
}
-static void geo_node_attribute_curve_map_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const bNode &bnode = params.node();
NodeAttributeCurveMap *data = (NodeAttributeCurveMap *)bnode.storage;
@@ -188,7 +186,7 @@ static void geo_node_attribute_curve_map_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
@@ -203,23 +201,23 @@ static void geo_node_attribute_curve_map_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_curve_map_update);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_curve_map_init);
+ 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",
- blender::nodes::geo_node_attribute_curve_map_free_storage,
- blender::nodes::geo_node_attribute_curve_map_copy_storage);
- ntype.declare = blender::nodes::geo_node_attribute_curve_map_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_curve_map_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_curve_map_layout;
+ 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_attribute_fill.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc
index a1b537e9657..a05bcf1bed8 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_fill.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_fill.cc
@@ -19,9 +19,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_fill_cc {
-static void geo_node_attribute_fill_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute")).is_attribute_name();
@@ -33,7 +33,7 @@ static void geo_node_attribute_fill_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_fill_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -41,13 +41,13 @@ static void geo_node_attribute_fill_layout(uiLayout *layout, bContext *UNUSED(C)
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
-static void geo_node_attribute_fill_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
node->custom1 = CD_PROP_FLOAT;
node->custom2 = ATTR_DOMAIN_AUTO;
}
-static void geo_node_attribute_fill_update(bNodeTree *ntree, bNode *node)
+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;
@@ -127,11 +127,11 @@ static void fill_attribute(GeometryComponent &component, const GeoNodeExecParams
attribute.save();
}
-static void geo_node_attribute_fill_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
fill_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -146,18 +146,20 @@ static void geo_node_attribute_fill_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_fill_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_fill_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_fill_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_fill_layout;
- ntype.declare = blender::nodes::geo_node_attribute_fill_declare;
+ 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_attribute_map_range.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc
index 2c70157d586..8ebcf34ad0b 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_map_range.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_map_range.cc
@@ -22,9 +22,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_map_range_cc {
-static void geo_node_attribute_map_range_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute"));
@@ -49,7 +49,7 @@ static void fn_attribute_map_range_layout(uiLayout *layout, bContext *UNUSED(C),
uiItemR(layout, ptr, "interpolation_type", 0, "", ICON_NONE);
}
-static void geo_node_attribute_map_range_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeAttributeMapRange *data = (NodeAttributeMapRange *)MEM_callocN(sizeof(NodeAttributeMapRange),
__func__);
@@ -58,7 +58,7 @@ static void geo_node_attribute_map_range_init(bNodeTree *UNUSED(ntree), bNode *n
node->storage = data;
}
-static void geo_node_attribute_map_range_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeAttributeMapRange &node_storage = *(NodeAttributeMapRange *)node->storage;
@@ -399,7 +399,7 @@ static void map_range_attribute(GeometryComponent &component, const GeoNodeExecP
attribute_result.save();
}
-static void geo_node_attribute_map_range_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -416,20 +416,22 @@ static void geo_node_attribute_map_range_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_map_range_exec;
- node_type_init(&ntype, blender::nodes::geo_node_attribute_map_range_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_map_range_update);
+ 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 = blender::nodes::geo_node_attribute_map_range_declare;
- ntype.draw_buttons = blender::nodes::fn_attribute_map_range_layout;
+ 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_attribute_math.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc
index 193db7355f9..e0a829b4100 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_math.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_math.cc
@@ -25,9 +25,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_math_cc {
-static void geo_node_attribute_math_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("A"));
@@ -100,7 +100,7 @@ static bool operation_use_input_b(const NodeMathOperation operation)
return false;
}
-static void geo_node_attribute_math_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
NodeAttributeMath *node_storage = (NodeAttributeMath *)node->storage;
@@ -119,7 +119,7 @@ static void geo_node_attribute_math_layout(uiLayout *layout, bContext *UNUSED(C)
}
}
-static void geo_node_attribute_math_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeMath *data = (NodeAttributeMath *)MEM_callocN(sizeof(NodeAttributeMath), __func__);
@@ -130,7 +130,10 @@ static void geo_node_attribute_math_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
+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;
@@ -141,7 +144,7 @@ static void geo_node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *lab
BLI_strncpy(label, IFACE_(name), maxlen);
}
-static void geo_node_attribute_math_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeAttributeMath &node_storage = *(NodeAttributeMath *)node->storage;
NodeMathOperation operation = static_cast<NodeMathOperation>(node_storage.operation);
@@ -278,11 +281,11 @@ static void attribute_math_calc(GeometryComponent &component, const GeoNodeExecP
attribute_result.save();
}
-static void geo_node_attribute_math_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
attribute_math_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -297,20 +300,22 @@ static void geo_node_attribute_math_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_attribute_math_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_math_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_math_layout;
- node_type_label(&ntype, blender::nodes::geo_node_math_label);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_math_update);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_math_init);
+ 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_attribute_mix.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc
index 6c7f2313633..4a110e9690a 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_mix.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_mix.cc
@@ -25,9 +25,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_mix_cc {
-static void geo_node_mix_attribute_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Factor"));
@@ -48,7 +48,7 @@ static void geo_node_mix_attribute_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_mix_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -59,7 +59,7 @@ static void geo_node_attribute_mix_layout(uiLayout *layout, bContext *UNUSED(C),
uiItemR(col, ptr, "input_type_b", 0, IFACE_("B"), ICON_NONE);
}
-static void geo_node_attribute_mix_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeAttributeMix *data = (NodeAttributeMix *)MEM_callocN(sizeof(NodeAttributeMix),
"attribute mix node");
@@ -70,7 +70,7 @@ static void geo_node_attribute_mix_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void geo_node_attribute_mix_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeAttributeMix *node_storage = (NodeAttributeMix *)node->storage;
update_attribute_input_socket_availabilities(
@@ -222,11 +222,11 @@ static void attribute_mix_calc(GeometryComponent &component, const GeoNodeExecPa
attribute_result.save();
}
-static void geo_node_attribute_mix_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
attribute_mix_calc(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -241,19 +241,21 @@ static void geo_node_attribute_mix_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_mix_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_mix_update);
- ntype.declare = blender::nodes::geo_node_mix_attribute_declare;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_mix_layout;
+ 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 = blender::nodes::geo_node_attribute_mix_exec;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_proximity.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc
index 0122f9b7598..080bf38a740 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_proximity.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_proximity.cc
@@ -26,9 +26,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_proximity_cc {
-static void geo_node_attribute_proximity_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Geometry>(N_("Target"));
@@ -37,14 +37,12 @@ static void geo_node_attribute_proximity_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_proximity_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "target_geometry_element", 0, "", ICON_NONE);
}
-static void geo_attribute_proximity_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryAttributeProximity *node_storage = (NodeGeometryAttributeProximity *)MEM_callocN(
sizeof(NodeGeometryAttributeProximity), __func__);
@@ -203,16 +201,16 @@ static void attribute_calc_proximity(GeometryComponent &component,
}
}
-static void geo_node_attribute_proximity_exec(GeoNodeExecParams params)
+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_set_realize_instances(geometry_set);
+ 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_set_realize_instances(geometry_set_target);
+ geometry_set_target = geometry::realize_instances_legacy(geometry_set_target);
if (geometry_set.has<MeshComponent>()) {
attribute_calc_proximity(
@@ -230,22 +228,24 @@ static void geo_node_attribute_proximity_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_attribute_proximity_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(&ntype,
"NodeGeometryAttributeProximity",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_attribute_proximity_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_proximity_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_proximity_layout;
+ 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_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc
index f8d9dcdaf87..ab2bc7b379c 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_randomize.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_randomize.cc
@@ -25,7 +25,41 @@
namespace blender::nodes {
-static void geo_node_legacy_attribute_randomize_declare(NodeDeclarationBuilder &b)
+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"));
@@ -39,15 +73,13 @@ static void geo_node_legacy_attribute_randomize_declare(NodeDeclarationBuilder &
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_legacy_attribute_random_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_legacy_attribute_randomize_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeRandomize *data = (NodeAttributeRandomize *)MEM_callocN(
sizeof(NodeAttributeRandomize), __func__);
@@ -57,7 +89,7 @@ static void geo_node_legacy_attribute_randomize_init(bNodeTree *UNUSED(tree), bN
node->storage = data;
}
-static void geo_node_legacy_attribute_randomize_update(bNodeTree *ntree, bNode *node)
+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;
@@ -174,36 +206,6 @@ static void randomize_attribute_bool(MutableSpan<bool> span,
});
}
-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;
-}
-
static AttributeDomain get_result_domain(const GeometryComponent &component,
const GeoNodeExecParams &params,
const StringRef name)
@@ -280,12 +282,12 @@ static void randomize_attribute_on_component(GeometryComponent &component,
attribute.save();
}
-static void geo_node_legacy_random_attribute_exec(GeoNodeExecParams params)
+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_output("Geometry", geometry_set);
+ params.set_default_remaining_outputs();
return;
}
const int seed = params.get_input<int>("Seed");
@@ -294,7 +296,7 @@ static void geo_node_legacy_random_attribute_exec(GeoNodeExecParams params)
const GeometryNodeAttributeRandomizeMode operation =
static_cast<GeometryNodeAttributeRandomizeMode>(storage.operation);
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
randomize_attribute_on_component(geometry_set.get_component_for_write<MeshComponent>(),
@@ -324,20 +326,22 @@ static void geo_node_legacy_random_attribute_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_legacy_attribute_randomize_init);
- node_type_update(&ntype, blender::nodes::geo_node_legacy_attribute_randomize_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
- ntype.declare = blender::nodes::geo_node_legacy_attribute_randomize_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_legacy_random_attribute_exec;
- ntype.draw_buttons = blender::nodes::geo_node_legacy_attribute_random_layout;
+ 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_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc
index 9748ca3f2ad..bc18cb32e73 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_sample_texture.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_sample_texture.cc
@@ -28,9 +28,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_sample_texture_cc {
-static void geo_node_attribute_sample_texture_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Texture>(N_("Texture")).hide_label();
@@ -100,11 +100,11 @@ static void execute_on_component(GeometryComponent &component, const GeoNodeExec
attribute_out.save();
}
-static void geo_node_attribute_sample_texture_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
execute_on_component(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -119,10 +119,12 @@ static void geo_node_attribute_sample_texture_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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,
@@ -131,7 +133,7 @@ void register_node_type_geo_sample_texture()
NODE_CLASS_ATTRIBUTE,
0);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- ntype.declare = blender::nodes::geo_node_attribute_sample_texture_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_sample_texture_exec;
+ 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_attribute_separate_xyz.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc
index bfc69780bf6..c5aac118baf 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_separate_xyz.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_separate_xyz.cc
@@ -19,9 +19,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_separate_xyz_cc {
-static void geo_node_attribute_separate_xyz_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Vector"));
@@ -32,16 +32,14 @@ static void geo_node_attribute_separate_xyz_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_separate_xyz_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_attribute_separate_xyz_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeSeparateXYZ *data = (NodeAttributeSeparateXYZ *)MEM_callocN(
sizeof(NodeAttributeSeparateXYZ), __func__);
@@ -49,7 +47,7 @@ static void geo_node_attribute_separate_xyz_init(bNodeTree *UNUSED(tree), bNode
node->storage = data;
}
-static void geo_node_attribute_separate_xyz_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeAttributeSeparateXYZ *node_storage = (NodeAttributeSeparateXYZ *)node->storage;
update_attribute_input_socket_availabilities(
@@ -132,11 +130,11 @@ static void separate_attribute(GeometryComponent &component, const GeoNodeExecPa
}
}
-static void geo_node_attribute_separate_xyz_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
separate_attribute(geometry_set.get_component_for_write<MeshComponent>(), params);
@@ -151,10 +149,12 @@ static void geo_node_attribute_separate_xyz_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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,
@@ -162,12 +162,12 @@ void register_node_type_geo_attribute_separate_xyz()
"Attribute Separate XYZ",
NODE_CLASS_ATTRIBUTE,
0);
- ntype.declare = blender::nodes::geo_node_attribute_separate_xyz_declare;
- node_type_init(&ntype, blender::nodes::geo_node_attribute_separate_xyz_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_separate_xyz_update);
+ 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 = blender::nodes::geo_node_attribute_separate_xyz_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_separate_xyz_layout;
+ 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_attribute_transfer.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc
index b8827f82efc..686edc80f62 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_transfer.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_transfer.cc
@@ -29,9 +29,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_transfer_cc {
-static void geo_node_attribute_transfer_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Geometry>(N_("Source Geometry"));
@@ -40,9 +40,7 @@ static void geo_node_attribute_transfer_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_transfer_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -50,7 +48,7 @@ static void geo_node_attribute_transfer_layout(uiLayout *layout,
uiItemR(layout, ptr, "mapping", 0, IFACE_("Mapping"), ICON_NONE);
}
-static void geo_node_attribute_transfer_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryAttributeTransfer *data = (NodeGeometryAttributeTransfer *)MEM_callocN(
sizeof(NodeGeometryAttributeTransfer), __func__);
@@ -405,7 +403,7 @@ static void transfer_attribute_nearest(const GeometrySet &src_geometry,
data_type);
for (const int i : IndexRange(tot_samples)) {
if (pointcloud_distances_sq[i] < mesh_distances_sq[i]) {
- /* Point-cloud point is closer. */
+ /* 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);
@@ -477,7 +475,7 @@ static void transfer_attribute(const GeoNodeExecParams &params,
}
}
-static void geo_node_attribute_transfer_exec(GeoNodeExecParams params)
+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");
@@ -485,12 +483,12 @@ static void geo_node_attribute_transfer_exec(GeoNodeExecParams params)
const std::string dst_attribute_name = params.extract_input<std::string>("Destination");
if (src_attribute_name.empty() || dst_attribute_name.empty()) {
- params.set_output("Geometry", dst_geometry_set);
+ params.set_default_remaining_outputs();
return;
}
- dst_geometry_set = bke::geometry_set_realize_instances(dst_geometry_set);
- src_geometry_set = bke::geometry_set_realize_instances(src_geometry_set);
+ 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,
@@ -510,21 +508,23 @@ static void geo_node_attribute_transfer_exec(GeoNodeExecParams params)
params.set_output("Geometry", dst_geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_transfer_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(&ntype,
"NodeGeometryAttributeTransfer",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_attribute_transfer_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_transfer_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_transfer_layout;
+ 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_attribute_vector_math.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc
index e7fdd0f2eef..68051e81f57 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_vector_math.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_math.cc
@@ -26,9 +26,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_vector_math_cc {
-static void geo_node_attribute_vector_math_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("A"));
@@ -66,9 +66,7 @@ static bool operation_use_input_c(const NodeVectorMathOperation operation)
NODE_VECTOR_MATH_MULTIPLY_ADD);
}
-static void geo_node_attribute_vector_math_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
const NodeAttributeVectorMath &node_storage = *(NodeAttributeVectorMath *)node->storage;
@@ -103,7 +101,7 @@ static CustomDataType operation_get_read_type_c(const NodeVectorMathOperation op
return CD_PROP_FLOAT3;
}
-static void geo_node_attribute_vector_math_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeAttributeVectorMath *data = (NodeAttributeVectorMath *)MEM_callocN(
sizeof(NodeAttributeVectorMath), __func__);
@@ -152,8 +150,8 @@ static CustomDataType operation_get_result_type(const NodeVectorMathOperation op
return CD_PROP_FLOAT3;
}
-static void geo_node_vector_math_label(bNodeTree *UNUSED(ntree),
- bNode *node,
+static void geo_node_vector_math_label(const bNodeTree *UNUSED(ntree),
+ const bNode *node,
char *label,
int maxlen)
{
@@ -166,7 +164,7 @@ static void geo_node_vector_math_label(bNodeTree *UNUSED(ntree),
BLI_snprintf(label, maxlen, IFACE_("Vector %s"), IFACE_(name));
}
-static void geo_node_attribute_vector_math_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage;
const NodeVectorMathOperation operation = (const NodeVectorMathOperation)node_storage->operation;
@@ -531,11 +529,11 @@ static void attribute_vector_math_calc(GeometryComponent &component,
attribute_result.save();
}
-static void geo_node_attribute_vector_math_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ 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);
@@ -551,10 +549,12 @@ static void geo_node_attribute_vector_math_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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,
@@ -562,12 +562,12 @@ void register_node_type_geo_attribute_vector_math()
"Attribute Vector Math",
NODE_CLASS_ATTRIBUTE,
0);
- ntype.declare = blender::nodes::geo_node_attribute_vector_math_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_vector_math_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_vector_math_layout;
- node_type_label(&ntype, blender::nodes::geo_node_vector_math_label);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_vector_math_update);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_vector_math_init);
+ 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);
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_vector_rotate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc
index a6cd24ed72d..1ef50e69775 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_attribute_vector_rotate.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_attribute_vector_rotate.cc
@@ -21,9 +21,9 @@
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_attribute_vector_rotate_cc {
-static void geo_node_attribute_vector_rotate_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Vector"));
@@ -42,9 +42,7 @@ static void geo_node_attribute_vector_rotate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_attribute_vector_rotate_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
const NodeAttributeVectorRotate &node_storage = *(NodeAttributeVectorRotate *)node->storage;
@@ -70,7 +68,7 @@ static void geo_node_attribute_vector_rotate_layout(uiLayout *layout,
}
}
-static void geo_node_attribute_vector_rotate_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
const NodeAttributeVectorRotate *node_storage = (NodeAttributeVectorRotate *)node->storage;
const GeometryNodeAttributeVectorRotateMode mode = (const GeometryNodeAttributeVectorRotateMode)
@@ -112,7 +110,7 @@ static float3 vector_rotate_around_axis(const float3 vector,
return result + center;
}
-static void geo_node_attribute_vector_rotate_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeAttributeVectorRotate *node_storage = (NodeAttributeVectorRotate *)MEM_callocN(
sizeof(NodeAttributeVectorRotate), __func__);
@@ -309,11 +307,11 @@ static void execute_on_component(const GeoNodeExecParams &params, GeometryCompon
attribute_result.save();
}
-static void geo_node_attribute_vector_rotate_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
@@ -328,10 +326,12 @@ static void geo_node_attribute_vector_rotate_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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,
@@ -339,13 +339,13 @@ void register_node_type_geo_attribute_vector_rotate()
"Attribute Vector Rotate",
NODE_CLASS_ATTRIBUTE,
0);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_vector_rotate_update);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_vector_rotate_init);
+ 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 = blender::nodes::geo_node_attribute_vector_rotate_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_vector_rotate_layout;
- ntype.declare = blender::nodes::geo_node_attribute_vector_rotate_declare;
+ 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_curve_endpoints.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc
index 67c8200a9c2..e61dee4bee1 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_endpoints.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_endpoints.cc
@@ -25,9 +25,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_curve_endpoints_cc {
-static void geo_node_curve_endpoints_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Geometry>(N_("Start Points"));
@@ -145,15 +145,14 @@ static void copy_endpoint_attributes(Span<SplinePtr> splines,
});
}
-static void geo_node_curve_endpoints_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_curve()) {
- params.set_output("Start Points", GeometrySet());
- params.set_output("End Points", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -168,8 +167,7 @@ static void geo_node_curve_endpoints_exec(GeoNodeExecParams params)
const int total_size = offsets.size();
if (total_size == 0) {
- params.set_output("Start Points", GeometrySet());
- params.set_output("End Points", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -206,16 +204,18 @@ static void geo_node_curve_endpoints_exec(GeoNodeExecParams params)
params.set_output("End Points", std::move(end_result));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_curve_endpoints_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_endpoints_exec;
+ 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_curve_reverse.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc
index bc4612e2b8b..7c550495b41 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_reverse.cc
@@ -20,19 +20,19 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_curve_reverse_cc {
-static void geo_node_curve_reverse_declare(NodeDeclarationBuilder &b)
+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 geo_node_curve_reverse_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_curve()) {
params.set_output("Curve", geometry_set);
return;
@@ -58,14 +58,16 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
params.set_output("Curve", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_curve_reverse_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_reverse_exec;
+ 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_curve_select_by_handle_type.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc
index 40d827ae141..c702e9ff686 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_select_by_handle_type.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_select_by_handle_type.cc
@@ -23,24 +23,22 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_curve_select_by_handle_type_cc {
-static void geo_node_select_by_handle_type_declare(NodeDeclarationBuilder &b)
+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 geo_node_curve_select_by_handle_type_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_curve_select_by_handle_type_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSelectHandles *data = (NodeGeometryCurveSelectHandles *)MEM_callocN(
sizeof(NodeGeometryCurveSelectHandles), __func__);
@@ -94,7 +92,7 @@ static void select_curve_by_handle_type(const CurveEval &curve,
});
}
-static void geo_node_select_by_handle_type_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const NodeGeometryCurveSelectHandles *storage =
(const NodeGeometryCurveSelectHandles *)params.node().storage;
@@ -103,7 +101,7 @@ static void geo_node_select_by_handle_type_exec(GeoNodeExecParams params)
const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)storage->mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
const CurveEval *curve = curve_component.get_for_read();
@@ -121,10 +119,12 @@ static void geo_node_select_by_handle_type_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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,
@@ -132,14 +132,14 @@ void register_node_type_geo_legacy_select_by_handle_type()
"Select by Handle Type",
NODE_CLASS_GEOMETRY,
0);
- ntype.declare = blender::nodes::geo_node_select_by_handle_type_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_select_by_handle_type_exec;
- node_type_init(&ntype, blender::nodes::geo_node_curve_select_by_handle_type_init);
+ 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 = blender::nodes::geo_node_curve_select_by_handle_type_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_set_handles.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc
index b92db315d94..1e476d01148 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_set_handles.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_set_handles.cc
@@ -21,24 +21,22 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_curve_set_handles_cc {
-static void geo_node_curve_set_handles_decalre(NodeDeclarationBuilder &b)
+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 geo_node_curve_set_handles_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_curve_set_handles_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSetHandles *data = (NodeGeometryCurveSetHandles *)MEM_callocN(
sizeof(NodeGeometryCurveSetHandles), __func__);
@@ -64,7 +62,7 @@ static BezierSpline::HandleType handle_type_from_input_type(GeometryNodeCurveHan
return BezierSpline::HandleType::Auto;
}
-static void geo_node_curve_set_handles_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const NodeGeometryCurveSetHandles *node_storage =
(NodeGeometryCurveSetHandles *)params.node().storage;
@@ -72,7 +70,7 @@ static void geo_node_curve_set_handles_exec(GeoNodeExecParams params)
const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)node_storage->mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_curve()) {
params.set_output("Curve", geometry_set);
return;
@@ -124,21 +122,23 @@ static void geo_node_curve_set_handles_exec(GeoNodeExecParams params)
params.set_output("Curve", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_curve_set_handles_decalre;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_set_handles_exec;
- node_type_init(&ntype, blender::nodes::geo_node_curve_set_handles_init);
+ 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 = blender::nodes::geo_node_curve_set_handles_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc
index 36d4519cac3..f3599f4328f 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_spline_type.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_spline_type.cc
@@ -23,23 +23,21 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_curve_spline_type_cc {
-static void geo_node_legacy_curve_spline_type_declare(NodeDeclarationBuilder &b)
+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 geo_node_legacy_curve_spline_type_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "spline_type", 0, "", ICON_NONE);
}
-static void geo_node_legacy_curve_spline_type_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSplineType *data = (NodeGeometryCurveSplineType *)MEM_callocN(
sizeof(NodeGeometryCurveSplineType), __func__);
@@ -238,14 +236,14 @@ static SplinePtr convert_to_nurbs(const Spline &input)
return {};
}
-static void geo_node_legacy_curve_spline_type_exec(GeoNodeExecParams params)
+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 = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_curve()) {
params.set_output("Curve", geometry_set);
return;
@@ -282,21 +280,23 @@ static void geo_node_legacy_curve_spline_type_exec(GeoNodeExecParams params)
params.set_output("Curve", GeometrySet::create_with_curve(new_curve.release()));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_legacy_curve_spline_type_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_legacy_curve_spline_type_exec;
- node_type_init(&ntype, blender::nodes::geo_node_legacy_curve_spline_type_init);
+ 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 = blender::nodes::geo_node_legacy_curve_spline_type_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc
index 603547a8e69..9878402dd35 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_subdivide.cc
@@ -25,9 +25,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_curve_subdivide_cc {
-static void geo_node_curve_subdivide_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Cuts"));
@@ -35,14 +35,14 @@ static void geo_node_curve_subdivide_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_curve_subdivide_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+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 geo_node_curve_subdivide_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSubdivide *data = (NodeGeometryCurveSubdivide *)MEM_callocN(
sizeof(NodeGeometryCurveSubdivide), __func__);
@@ -51,7 +51,7 @@ static void geo_node_curve_subdivide_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_curve_subdivide_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryPointTranslate &node_storage = *(NodeGeometryPointTranslate *)node->storage;
@@ -347,11 +347,11 @@ static std::unique_ptr<CurveEval> subdivide_curve(const CurveEval &input_curve,
return output_curve;
}
-static void geo_node_subdivide_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_curve()) {
params.set_output("Geometry", geometry_set);
@@ -370,22 +370,24 @@ static void geo_node_subdivide_exec(GeoNodeExecParams params)
params.set_output("Geometry", GeometrySet::create_with_curve(output_curve.release()));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_curve_subdivide_declare;
- ntype.draw_buttons = blender::nodes::geo_node_curve_subdivide_layout;
+ 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, blender::nodes::geo_node_curve_subdivide_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_subdivide_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_subdivide_exec;
+ 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_curve_to_points.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc
index ab51258cc69..3bd03f3cee0 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_curve_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_curve_to_points.cc
@@ -28,7 +28,59 @@
namespace blender::nodes {
-static void geo_node_curve_to_points_declare(NodeDeclarationBuilder &b)
+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);
@@ -36,12 +88,12 @@ static void geo_node_curve_to_points_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_curve_to_points_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void geo_node_curve_to_points_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveToPoints *data = (NodeGeometryCurveToPoints *)MEM_callocN(
sizeof(NodeGeometryCurveToPoints), __func__);
@@ -50,7 +102,7 @@ static void geo_node_curve_to_points_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_curve_to_points_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryCurveToPoints &node_storage = *(NodeGeometryCurveToPoints *)node->storage;
const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
@@ -114,54 +166,6 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
return {0};
}
-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;
-}
-
/**
* 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.
@@ -286,13 +290,13 @@ static void copy_spline_domain_attributes(const CurveComponent &curve_component,
});
}
-static void geo_node_curve_to_points_exec(GeoNodeExecParams params)
+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 = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_curve()) {
params.set_output("Geometry", GeometrySet());
@@ -340,21 +344,23 @@ static void geo_node_curve_to_points_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(result));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_curve_to_points_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_to_points_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_to_points_layout;
+ 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, blender::nodes::geo_node_curve_to_points_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_to_points_update);
+ 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_delete_geometry.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc
index f62a22d7934..abd75e710ae 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_delete_geometry.cc
@@ -29,23 +29,23 @@
using blender::bke::CustomDataAttributes;
/* Code from the mask modifier in MOD_mask.cc. */
-extern void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- blender::Span<int> vertex_map);
-extern void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- blender::Span<int> vertex_map,
- blender::Span<int> edge_map);
-extern void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- blender::Span<int> vertex_map,
- blender::Span<int> edge_map,
- blender::Span<int> masked_poly_indices,
- blender::Span<int> new_loop_starts);
-
-namespace blender::nodes {
-
-static void geo_node_delete_geometry_declare(NodeDeclarationBuilder &b)
+void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
+ Mesh &dst_mesh,
+ blender::Span<int> vertex_map);
+void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
+ Mesh &dst_mesh,
+ blender::Span<int> vertex_map,
+ blender::Span<int> edge_map);
+void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
+ Mesh &dst_mesh,
+ blender::Span<int> vertex_map,
+ blender::Span<int> edge_map,
+ blender::Span<int> masked_poly_indices,
+ blender::Span<int> new_loop_starts);
+
+namespace blender::nodes::node_geo_legacy_delete_geometry_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Selection"));
@@ -627,10 +627,10 @@ static void delete_mesh_selection(MeshComponent &component,
component.replace(mesh_out);
}
-static void geo_node_delete_geometry_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ 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");
@@ -662,16 +662,18 @@ static void geo_node_delete_geometry_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(out_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_delete_geometry_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_delete_geometry_exec;
+ 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_edge_split.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc
index 8f2bf05d2b4..c046fda4686 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_edge_split.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_edge_split.cc
@@ -22,9 +22,9 @@ extern "C" {
Mesh *doEdgeSplit(const Mesh *mesh, EdgeSplitModifierData *emd);
}
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_edge_split_cc {
-static void geo_node_edge_split_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Bool>(N_("Edge Angle")).default_value(true);
@@ -37,11 +37,11 @@ static void geo_node_edge_split_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_edge_split_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_mesh()) {
params.set_output("Geometry", std::move(geometry_set));
@@ -76,14 +76,16 @@ static void geo_node_edge_split_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_edge_split_exec;
- ntype.declare = blender::nodes::geo_node_edge_split_declare;
+ 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_material_assign.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc
index 58374679a95..88e8374f5d6 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_material_assign.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_material_assign.cc
@@ -24,9 +24,9 @@
#include "BKE_material.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_material_assign_cc {
-static void geo_node_legacy_material_assign_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Material>(N_("Material")).hide_label(true);
@@ -59,14 +59,14 @@ static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask,
}
}
-static void geo_node_legacy_material_assign_exec(GeoNodeExecParams params)
+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_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
@@ -81,15 +81,17 @@ static void geo_node_legacy_material_assign_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_legacy_material_assign_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_legacy_material_assign_exec;
+ 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_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc
index 321de24a3dc..2ff7410f3f6 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_mesh_to_curve.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_mesh_to_curve.cc
@@ -18,23 +18,23 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_mesh_to_curve_cc {
-static void geo_node_legacy_mesh_to_curve_declare(NodeDeclarationBuilder &b)
+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 geo_node_legacy_mesh_to_curve_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_mesh()) {
- params.set_output("Curve", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -55,7 +55,7 @@ static void geo_node_legacy_mesh_to_curve_exec(GeoNodeExecParams params)
}
if (selected_edge_indices.size() == 0) {
- params.set_output("Curve", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -65,15 +65,17 @@ static void geo_node_legacy_mesh_to_curve_exec(GeoNodeExecParams params)
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_legacy_mesh_to_curve_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_legacy_mesh_to_curve_exec;
+ 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_point_distribute.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc
index 4e13a490d89..2451a7447ec 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_point_distribute.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_distribute.cc
@@ -36,11 +36,11 @@
#include "node_geometry_util.hh"
-using blender::bke::GeometryInstanceGroup;
+namespace blender::nodes::node_geo_legacy_point_distribute_cc {
-namespace blender::nodes {
+using blender::bke::GeometryInstanceGroup;
-static void geo_node_point_distribute_declare(NodeDeclarationBuilder &b)
+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);
@@ -54,9 +54,7 @@ static void geo_node_point_distribute_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_point_distribute_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE);
}
@@ -541,7 +539,7 @@ static void distribute_points_poisson_disk(Span<GeometryInstanceGroup> set_group
}
}
-static void geo_node_point_distribute_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -554,14 +552,14 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
"Density Attribute");
if (density <= 0.0f) {
- params.set_output("Geometry", GeometrySet());
+ 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_output("Geometry", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -575,7 +573,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
if (set_groups.is_empty()) {
params.error_message_add(NodeWarningType::Error, TIP_("Input geometry must contain a mesh"));
- params.set_output("Geometry", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -625,7 +623,7 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
}
if (final_points_len == 0) {
- params.set_output("Geometry", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -655,17 +653,19 @@ static void geo_node_point_distribute_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set_out));
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_update(&ntype, blender::nodes::node_point_distribute_update);
- ntype.declare = blender::nodes::geo_node_point_distribute_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_point_distribute_exec;
- ntype.draw_buttons = blender::nodes::geo_node_point_distribute_layout;
+ 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_point_instance.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc
index 713971941ea..8915a58feb1 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_instance.cc
@@ -24,9 +24,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_point_instance_cc {
-static void geo_node_point_instance_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Object>(N_("Object")).hide_label();
@@ -36,7 +36,7 @@ static void geo_node_point_instance_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_point_instance_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+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) {
@@ -44,7 +44,7 @@ static void geo_node_point_instance_layout(uiLayout *layout, bContext *UNUSED(C)
}
}
-static void geo_node_point_instance_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryPointInstance *data = (NodeGeometryPointInstance *)MEM_callocN(
sizeof(NodeGeometryPointInstance), __func__);
@@ -53,7 +53,7 @@ static void geo_node_point_instance_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_point_instance_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *object_socket = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
bNodeSocket *collection_socket = object_socket->next;
@@ -173,6 +173,9 @@ static void add_instances_from_component(InstancesComponent &instances,
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});
@@ -186,7 +189,9 @@ static void add_instances_from_component(InstancesComponent &instances,
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);
- MutableSpan<int> instance_ids = instances.instance_ids_ensure().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). */
@@ -213,16 +218,18 @@ static void add_instances_from_component(InstancesComponent &instances,
}
});
}
+
+ instance_id_attribute.save();
}
-static void geo_node_point_instance_exec(GeoNodeExecParams params)
+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_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
const Vector<InstanceReference> possible_references = get_instance_references(params);
if (possible_references.is_empty()) {
@@ -255,20 +262,22 @@ static void geo_node_point_instance_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set_out));
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_point_instance_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(
&ntype, "NodeGeometryPointInstance", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_point_instance_declare;
- ntype.draw_buttons = blender::nodes::geo_node_point_instance_layout;
- node_type_update(&ntype, blender::nodes::geo_node_point_instance_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_point_instance_exec;
+ 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_point_rotate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc
index ab1d68bfe4f..a0a7674797a 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_point_rotate.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_rotate.cc
@@ -21,9 +21,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_point_rotate_cc {
-static void geo_node_point_rotate_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Axis"));
@@ -37,7 +37,7 @@ static void geo_node_point_rotate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_point_rotate_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
NodeGeometryRotatePoints *storage = (NodeGeometryRotatePoints *)((bNode *)ptr->data)->storage;
@@ -57,7 +57,7 @@ static void geo_node_point_rotate_layout(uiLayout *layout, bContext *UNUSED(C),
}
}
-static void geo_node_point_rotate_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryRotatePoints *node_storage = (NodeGeometryRotatePoints *)MEM_callocN(
sizeof(NodeGeometryRotatePoints), __func__);
@@ -71,7 +71,7 @@ static void geo_node_point_rotate_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = node_storage;
}
-static void geo_node_point_rotate_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryRotatePoints *node_storage = (NodeGeometryRotatePoints *)node->storage;
update_attribute_input_socket_availabilities(
@@ -199,11 +199,11 @@ static void point_rotate_on_component(GeometryComponent &component,
rotation_attribute.save();
}
-static void geo_node_point_rotate_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ 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);
@@ -218,19 +218,21 @@ static void geo_node_point_rotate_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_point_rotate_init);
- node_type_update(&ntype, blender::nodes::geo_node_point_rotate_update);
+ 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 = blender::nodes::geo_node_point_rotate_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_point_rotate_exec;
- ntype.draw_buttons = blender::nodes::geo_node_point_rotate_layout;
+ 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_point_scale.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc
index 8d6345ce6b1..d38df124979 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_point_scale.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_scale.cc
@@ -21,9 +21,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_point_scale_cc {
-static void geo_node_point_scale_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Factor"));
@@ -34,14 +34,14 @@ static void geo_node_point_scale_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_point_scale_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+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 geo_node_point_scale_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryPointScale *data = (NodeGeometryPointScale *)MEM_callocN(
sizeof(NodeGeometryPointScale), __func__);
@@ -50,7 +50,7 @@ static void geo_node_point_scale_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_point_scale_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryPointScale &node_storage = *(NodeGeometryPointScale *)node->storage;
@@ -101,11 +101,11 @@ static void execute_on_component(GeoNodeExecParams params, GeometryComponent &co
scale_attribute.save();
}
-static void geo_node_point_scale_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
@@ -120,20 +120,22 @@ static void geo_node_point_scale_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_point_scale_declare;
- node_type_init(&ntype, blender::nodes::geo_node_point_scale_init);
- node_type_update(&ntype, blender::nodes::geo_node_point_scale_update);
+ 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 = blender::nodes::geo_node_point_scale_exec;
- ntype.draw_buttons = blender::nodes::geo_node_point_scale_layout;
+ 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_point_separate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc
index 3539fe2de64..9260928b311 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_point_separate.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_separate.cc
@@ -25,14 +25,6 @@
namespace blender::nodes {
-static void geo_node_point_instance_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"));
-}
-
template<typename T>
static void copy_data_based_on_mask(Span<T> data,
Span<bool> masks,
@@ -78,6 +70,18 @@ void copy_point_attributes_based_on_mask(const GeometryComponent &in_component,
}
}
+} // 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()) {
@@ -133,7 +137,7 @@ static GeometrySet separate_geometry_set(const GeometrySet &set_in,
return set_out;
}
-static void geo_node_point_separate_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
bool wait_for_inputs = false;
wait_for_inputs |= params.lazy_require_input("Geometry");
@@ -146,7 +150,7 @@ static void geo_node_point_separate_exec(GeoNodeExecParams params)
/* 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_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (params.lazy_output_is_required("Geometry 1")) {
params.set_output("Geometry 1",
@@ -158,16 +162,18 @@ static void geo_node_point_separate_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_point_instance_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_point_separate_exec;
+ 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_point_translate.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc
index 3b2959beb86..c70478182ec 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_point_translate.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_point_translate.cc
@@ -19,9 +19,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_point_translate_cc {
-static void geo_node_point_translate_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Translation"));
@@ -29,7 +29,7 @@ static void geo_node_point_translate_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_point_translate_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -53,11 +53,11 @@ static void execute_on_component(GeoNodeExecParams params, GeometryComponent &co
position_attribute.save();
}
-static void geo_node_point_translate_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>());
@@ -72,7 +72,7 @@ static void geo_node_point_translate_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-static void geo_node_point_translate_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryPointTranslate *data = (NodeGeometryPointTranslate *)MEM_callocN(
sizeof(NodeGeometryPointTranslate), __func__);
@@ -81,7 +81,7 @@ static void geo_node_point_translate_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_point_translate_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryPointTranslate &node_storage = *(NodeGeometryPointTranslate *)node->storage;
@@ -89,22 +89,24 @@ static void geo_node_point_translate_update(bNodeTree *ntree, bNode *node)
*ntree, *node, "Translation", (GeometryNodeAttributeInputMode)node_storage.input_type);
}
-} // namespace blender::nodes
+} // 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, 0);
- node_type_init(&ntype, blender::nodes::geo_node_point_translate_init);
- node_type_update(&ntype, blender::nodes::geo_node_point_translate_update);
+ 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 = blender::nodes::geo_node_point_translate_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_point_translate_exec;
- ntype.draw_buttons = blender::nodes::geo_node_point_translate_layout;
+ 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_points_to_volume.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc
index d465a9ab1a8..ec1ab67b530 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_points_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_points_to_volume.cc
@@ -28,9 +28,9 @@
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_points_to_volume_cc {
-static void geo_node_points_to_volume_declare(NodeDeclarationBuilder &b)
+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);
@@ -41,9 +41,7 @@ static void geo_node_points_to_volume_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_points_to_volume_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -51,7 +49,7 @@ static void geo_node_points_to_volume_layout(uiLayout *layout,
uiItemR(layout, ptr, "input_type_radius", 0, IFACE_("Radius"), ICON_NONE);
}
-static void geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)MEM_callocN(
sizeof(NodeGeometryPointsToVolume), __func__);
@@ -65,7 +63,7 @@ static void geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node
STRNCPY(radius_attribute_socket_value->value, "radius");
}
-static void geo_node_points_to_volume_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)node->storage;
bNodeSocket *voxel_size_socket = nodeFindSocket(node, SOCK_IN, "Voxel Size");
@@ -244,13 +242,13 @@ static void initialize_volume_component_from_points(const GeometrySet &geometry_
}
#endif
-static void geo_node_points_to_volume_exec(GeoNodeExecParams params)
+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_set_realize_instances(geometry_set_in);
+ 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);
@@ -259,10 +257,12 @@ static void geo_node_points_to_volume_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set_out));
}
-} // namespace blender::nodes
+} // 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(
@@ -272,10 +272,10 @@ void register_node_type_geo_legacy_points_to_volume()
node_free_standard_storage,
node_copy_standard_storage);
node_type_size(&ntype, 170, 120, 700);
- node_type_init(&ntype, blender::nodes::geo_node_points_to_volume_init);
- node_type_update(&ntype, blender::nodes::geo_node_points_to_volume_update);
- ntype.declare = blender::nodes::geo_node_points_to_volume_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_points_to_volume_exec;
- ntype.draw_buttons = blender::nodes::geo_node_points_to_volume_layout;
+ 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_raycast.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc
index 5aa683ca232..599ffd617a5 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_raycast.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_raycast.cc
@@ -24,9 +24,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_raycast_cc {
-static void geo_node_raycast_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Geometry>(N_("Target Geometry"));
@@ -47,7 +47,7 @@ static void geo_node_raycast_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_raycast_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -56,7 +56,7 @@ static void geo_node_raycast_layout(uiLayout *layout, bContext *UNUSED(C), Point
uiItemR(layout, ptr, "input_type_ray_length", 0, IFACE_("Ray Length"), ICON_NONE);
}
-static void geo_node_raycast_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryRaycast *data = (NodeGeometryRaycast *)MEM_callocN(sizeof(NodeGeometryRaycast),
__func__);
@@ -65,7 +65,7 @@ static void geo_node_raycast_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_raycast_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryRaycast *node_storage = (NodeGeometryRaycast *)node->storage;
update_attribute_input_socket_availabilities(
@@ -272,7 +272,7 @@ static void raycast_from_points(const GeoNodeExecParams &params,
}
}
-static void geo_node_raycast_exec(GeoNodeExecParams params)
+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");
@@ -285,8 +285,8 @@ static void geo_node_raycast_exec(GeoNodeExecParams params)
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 = bke::geometry_set_realize_instances(geometry_set);
- target_geometry_set = bke::geometry_set_realize_instances(target_geometry_set);
+ 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};
@@ -307,20 +307,22 @@ static void geo_node_raycast_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // 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, 0);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- node_type_init(&ntype, blender::nodes::geo_node_raycast_init);
- node_type_update(&ntype, blender::nodes::geo_node_raycast_update);
+ 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 = blender::nodes::geo_node_raycast_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_raycast_exec;
- ntype.draw_buttons = blender::nodes::geo_node_raycast_layout;
+ 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_select_by_material.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc
index a8d6f33a5fd..b61ba5ff67e 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_select_by_material.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_select_by_material.cc
@@ -26,9 +26,9 @@
#include "BKE_material.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_select_by_material_cc {
-static void geo_node_legacy_select_by_material_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Material>(N_("Material")).hide_label();
@@ -54,13 +54,13 @@ static void select_mesh_by_material(const Mesh &mesh,
});
}
-static void geo_node_legacy_select_by_material_exec(GeoNodeExecParams params)
+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_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (geometry_set.has<MeshComponent>()) {
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
@@ -78,15 +78,17 @@ static void geo_node_legacy_select_by_material_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_legacy_select_by_material_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_legacy_select_by_material_exec;
+ 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_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc
index 295cd05fd01..819ffb2c20c 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_subdivision_surface.cc
@@ -23,9 +23,9 @@
#include "UI_resources.h"
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_subdivision_surface_cc {
-static void geo_node_subdivision_surface_declare(NodeDeclarationBuilder &b)
+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);
@@ -33,9 +33,7 @@ static void geo_node_subdivision_surface_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_subdivision_surface_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
#ifdef WITH_OPENSUBDIV
uiLayoutSetPropSep(layout, true);
@@ -47,7 +45,7 @@ static void geo_node_subdivision_surface_layout(uiLayout *layout,
#endif
}
-static void geo_node_subdivision_surface_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometrySubdivisionSurface *data = (NodeGeometrySubdivisionSurface *)MEM_callocN(
sizeof(NodeGeometrySubdivisionSurface), __func__);
@@ -56,11 +54,11 @@ static void geo_node_subdivision_surface_init(bNodeTree *UNUSED(ntree), bNode *n
node->storage = data;
}
-static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = geometry_set_realize_instances(geometry_set);
+ geometry_set = geometry::realize_instances_legacy(geometry_set);
if (!geometry_set.has_mesh()) {
params.set_output("Geometry", geometry_set);
@@ -126,18 +124,20 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_subdivision_surface_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_subdivision_surface_exec;
- ntype.draw_buttons = blender::nodes::geo_node_subdivision_surface_layout;
- node_type_init(&ntype, blender::nodes::geo_node_subdivision_surface_init);
+ 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",
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc
index 6a52b943967..acff0be7126 100644
--- a/source/blender/nodes/geometry/nodes/legacy/node_geo_volume_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_legacy_volume_to_mesh.cc
@@ -35,9 +35,9 @@
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_legacy_volume_to_mesh_cc {
-static void geo_node_volume_to_mesh_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Density"));
@@ -48,14 +48,14 @@ static void geo_node_volume_to_mesh_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_volume_to_mesh_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+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 geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)MEM_callocN(
sizeof(NodeGeometryVolumeToMesh), __func__);
@@ -68,7 +68,7 @@ static void geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void geo_node_volume_to_mesh_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)node->storage;
@@ -140,7 +140,7 @@ static void create_mesh_from_volume(GeometrySet &geometry_set_in,
#endif /* WITH_OPENVDB */
-static void geo_node_volume_to_mesh_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set_in = params.extract_input<GeometrySet>("Geometry");
GeometrySet geometry_set_out;
@@ -155,21 +155,23 @@ static void geo_node_volume_to_mesh_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set_out);
}
-} // namespace blender::nodes
+} // 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, 0);
- ntype.declare = blender::nodes::geo_node_volume_to_mesh_declare;
+ 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, blender::nodes::geo_node_volume_to_mesh_init);
- node_type_update(&ntype, blender::nodes::geo_node_volume_to_mesh_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_volume_to_mesh_exec;
- ntype.draw_buttons = blender::nodes::geo_node_volume_to_mesh_layout;
+ 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_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
index 19deb761948..be0baa706af 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
@@ -19,11 +19,15 @@
#include "BKE_attribute_math.hh"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_attribute_capture_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometryAttributeCapture)
-static void geo_node_attribute_capture_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Vector>(N_("Value")).supports_field();
@@ -40,9 +44,7 @@ static void geo_node_attribute_capture_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").field_source();
}
-static void geo_node_attribute_capture_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -50,7 +52,7 @@ static void geo_node_attribute_capture_layout(uiLayout *layout,
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
-static void geo_node_attribute_capture_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryAttributeCapture *data = (NodeGeometryAttributeCapture *)MEM_callocN(
sizeof(NodeGeometryAttributeCapture), __func__);
@@ -60,10 +62,9 @@ static void geo_node_attribute_capture_init(bNodeTree *UNUSED(tree), bNode *node
node->storage = data;
}
-static void geo_node_attribute_capture_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryAttributeCapture &storage = *(const NodeGeometryAttributeCapture *)
- node->storage;
+ const NodeGeometryAttributeCapture &storage = node_storage(*node);
const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
bNodeSocket *socket_value_geometry = (bNodeSocket *)node->inputs.first;
@@ -93,6 +94,33 @@ static void geo_node_attribute_capture_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, out_socket_value_int32, data_type == CD_PROP_INT32);
}
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+ search_link_ops_for_declarations(params, declaration.outputs().take_front(1));
+
+ const bNodeType &node_type = params.node_type();
+ const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ (eNodeSocketDatatype)params.other_socket().type);
+ if (type && *type != CD_PROP_STRING) {
+ if (params.in_out() == SOCK_OUT) {
+ params.add_item(IFACE_("Attribute"), [node_type, type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node(node_type);
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Attribute");
+ });
+ }
+ else {
+ params.add_item(IFACE_("Value"), [node_type, type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node(node_type);
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Value");
+ });
+ }
+ }
+}
+
static void try_capture_field_on_geometry(GeometryComponent &component,
const AttributeIDRef &attribute_id,
const AttributeDomain domain,
@@ -113,13 +141,11 @@ static void try_capture_field_on_geometry(GeometryComponent &component,
output_attribute.save();
}
-static void geo_node_attribute_capture_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- const bNode &node = params.node();
- const NodeGeometryAttributeCapture &storage = *(const NodeGeometryAttributeCapture *)
- node.storage;
+ const NodeGeometryAttributeCapture &storage = node_storage(params.node());
const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
@@ -147,16 +173,27 @@ static void geo_node_attribute_capture_exec(GeoNodeExecParams params)
WeakAnonymousAttributeID anonymous_id{"Attribute"};
const CPPType &type = field.cpp_type();
- static const Array<GeometryComponentType> types = {
- GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
- geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- for (const GeometryComponentType type : types) {
- if (geometry_set.has(type)) {
- GeometryComponent &component = geometry_set.get_component_for_write(type);
- try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
- }
+ /* Run on the instances component separately to only affect the top level of instances. */
+ if (domain == ATTR_DOMAIN_INSTANCE) {
+ if (geometry_set.has_instances()) {
+ GeometryComponent &component = geometry_set.get_component_for_write(
+ GEO_COMPONENT_TYPE_INSTANCES);
+ try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
}
- });
+ }
+ else {
+ static const Array<GeometryComponentType> types = {
+ GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ for (const GeometryComponentType type : types) {
+ if (geometry_set.has(type)) {
+ GeometryComponent &component = geometry_set.get_component_for_write(type);
+ try_capture_field_on_geometry(component, anonymous_id.get(), domain, field);
+ }
+ }
+ });
+ }
GField output_field{std::make_shared<bke::AnonymousAttributeFieldInput>(
std::move(anonymous_id), type, params.attribute_producer_name())};
@@ -189,10 +226,12 @@ static void geo_node_attribute_capture_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_attribute_capture_cc
void register_node_type_geo_attribute_capture()
{
+ namespace file_ns = blender::nodes::node_geo_attribute_capture_cc;
+
static bNodeType ntype;
geo_node_type_base(
@@ -201,10 +240,11 @@ void register_node_type_geo_attribute_capture()
"NodeGeometryAttributeCapture",
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_attribute_capture_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_capture_update);
- ntype.declare = blender::nodes::geo_node_attribute_capture_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_capture_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_capture_layout;
+ 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;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
new file mode 100644
index 00000000000..d6662e4e637
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc
@@ -0,0 +1,155 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_attribute_domain_size_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_output<decl::Int>("Point Count").make_available([](bNode &node) {
+ node.custom1 = GEO_COMPONENT_TYPE_MESH;
+ });
+ b.add_output<decl::Int>("Edge Count").make_available([](bNode &node) {
+ node.custom1 = GEO_COMPONENT_TYPE_MESH;
+ });
+ b.add_output<decl::Int>("Face Count").make_available([](bNode &node) {
+ node.custom1 = GEO_COMPONENT_TYPE_MESH;
+ });
+ b.add_output<decl::Int>("Face Corner Count").make_available([](bNode &node) {
+ node.custom1 = GEO_COMPONENT_TYPE_MESH;
+ });
+ b.add_output<decl::Int>("Spline Count").make_available([](bNode &node) {
+ node.custom1 = GEO_COMPONENT_TYPE_CURVE;
+ });
+ b.add_output<decl::Int>("Instance Count").make_available([](bNode &node) {
+ node.custom1 = GEO_COMPONENT_TYPE_INSTANCES;
+ });
+}
+
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "component", 0, "", ICON_NONE);
+}
+
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ node->custom1 = GEO_COMPONENT_TYPE_MESH;
+}
+
+static void node_update(bNodeTree *ntree, bNode *node)
+{
+ bNodeSocket *point_socket = (bNodeSocket *)node->outputs.first;
+ bNodeSocket *edge_socket = point_socket->next;
+ bNodeSocket *face_socket = edge_socket->next;
+ bNodeSocket *face_corner_socket = face_socket->next;
+ bNodeSocket *spline_socket = face_corner_socket->next;
+ bNodeSocket *instances_socket = spline_socket->next;
+
+ nodeSetSocketAvailability(ntree,
+ point_socket,
+ ELEM(node->custom1,
+ GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_POINT_CLOUD));
+ nodeSetSocketAvailability(ntree, edge_socket, node->custom1 == GEO_COMPONENT_TYPE_MESH);
+ nodeSetSocketAvailability(ntree, face_socket, node->custom1 == GEO_COMPONENT_TYPE_MESH);
+ nodeSetSocketAvailability(ntree, face_corner_socket, node->custom1 == GEO_COMPONENT_TYPE_MESH);
+ nodeSetSocketAvailability(ntree, spline_socket, node->custom1 == GEO_COMPONENT_TYPE_CURVE);
+ nodeSetSocketAvailability(
+ ntree, instances_socket, node->custom1 == GEO_COMPONENT_TYPE_INSTANCES);
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometryComponentType component = (GeometryComponentType)params.node().custom1;
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+
+ switch (component) {
+ case GEO_COMPONENT_TYPE_MESH: {
+ if (geometry_set.has_mesh()) {
+ const MeshComponent *component = geometry_set.get_component_for_read<MeshComponent>();
+ params.set_output("Point Count", component->attribute_domain_size(ATTR_DOMAIN_POINT));
+ params.set_output("Edge Count", component->attribute_domain_size(ATTR_DOMAIN_EDGE));
+ params.set_output("Face Count", component->attribute_domain_size(ATTR_DOMAIN_FACE));
+ params.set_output("Face Corner Count",
+ component->attribute_domain_size(ATTR_DOMAIN_CORNER));
+ }
+ else {
+ params.set_default_remaining_outputs();
+ }
+ break;
+ }
+ case GEO_COMPONENT_TYPE_CURVE: {
+ if (geometry_set.has_curve()) {
+ const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>();
+ params.set_output("Point Count", component->attribute_domain_size(ATTR_DOMAIN_POINT));
+ params.set_output("Spline Count", component->attribute_domain_size(ATTR_DOMAIN_CURVE));
+ }
+ else {
+ params.set_default_remaining_outputs();
+ }
+ break;
+ }
+ case GEO_COMPONENT_TYPE_POINT_CLOUD: {
+ if (geometry_set.has_pointcloud()) {
+ const PointCloudComponent *component =
+ geometry_set.get_component_for_read<PointCloudComponent>();
+ params.set_output("Point Count", component->attribute_domain_size(ATTR_DOMAIN_POINT));
+ }
+ else {
+ params.set_default_remaining_outputs();
+ }
+ break;
+ }
+ case GEO_COMPONENT_TYPE_INSTANCES: {
+ if (geometry_set.has_instances()) {
+ const InstancesComponent *component =
+ geometry_set.get_component_for_read<InstancesComponent>();
+ params.set_output("Instance Count",
+ component->attribute_domain_size(ATTR_DOMAIN_INSTANCE));
+ }
+ else {
+ params.set_default_remaining_outputs();
+ }
+ break;
+ }
+ default:
+ BLI_assert_unreachable();
+ }
+}
+
+} // namespace blender::nodes::node_geo_attribute_domain_size_cc
+
+void register_node_type_geo_attribute_domain_size()
+{
+ namespace file_ns = blender::nodes::node_geo_attribute_domain_size_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, "Domain Size", NODE_CLASS_ATTRIBUTE, 0);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_layout;
+ node_type_init(&ntype, file_ns::node_init);
+ ntype.updatefunc = file_ns::node_update;
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
index f80b8ccc971..6f26b2c756b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_attribute_remove_cc {
-static void geo_node_attribute_remove_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::String>(N_("Attribute")).multi_input();
@@ -42,7 +42,7 @@ static void remove_attribute(GeometryComponent &component,
}
}
-static void geo_node_attribute_remove_exec(GeoNodeExecParams params)
+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");
@@ -66,15 +66,17 @@ static void geo_node_attribute_remove_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_attribute_remove_cc
void register_node_type_geo_attribute_remove()
{
+ namespace file_ns = blender::nodes::node_geo_attribute_remove_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_ATTRIBUTE_REMOVE, "Attribute Remove", NODE_CLASS_ATTRIBUTE, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_remove_exec;
- ntype.declare = blender::nodes::geo_node_attribute_remove_declare;
+ 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/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
index d9513332078..b79125d43d1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc
@@ -22,13 +22,16 @@
#include "BLI_math_base_safe.h"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_attribute_statistic_cc {
-static void geo_node_attribute_statistic_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
b.add_input<decl::Float>(N_("Attribute")).hide_value().supports_field();
b.add_input<decl::Vector>(N_("Attribute"), "Attribute_001").hide_value().supports_field();
@@ -51,24 +54,23 @@ static void geo_node_attribute_statistic_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Variance"), "Variance_001");
}
-static void geo_node_attribute_statistic_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void geo_node_attribute_statistic_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
node->custom1 = CD_PROP_FLOAT;
node->custom2 = ATTR_DOMAIN_POINT;
}
-static void geo_node_attribute_statistic_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *socket_geo = (bNodeSocket *)node->inputs.first;
- bNodeSocket *socket_float_attr = socket_geo->next;
+ bNodeSocket *socket_selection = socket_geo->next;
+ bNodeSocket *socket_float_attr = socket_selection->next;
bNodeSocket *socket_float3_attr = socket_float_attr->next;
bNodeSocket *socket_float_mean = (bNodeSocket *)node->outputs.first;
@@ -112,6 +114,54 @@ static void geo_node_attribute_statistic_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, socket_vector_variance, data_type == CD_PROP_FLOAT3);
}
+static std::optional<CustomDataType> node_type_from_other_socket(const bNodeSocket &socket)
+{
+ switch (socket.type) {
+ case SOCK_FLOAT:
+ case SOCK_BOOLEAN:
+ case SOCK_INT:
+ return CD_PROP_FLOAT;
+ case SOCK_VECTOR:
+ case SOCK_RGBA:
+ return CD_PROP_FLOAT3;
+ default:
+ return {};
+ }
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const bNodeType &node_type = params.node_type();
+ const std::optional<CustomDataType> type = node_type_from_other_socket(params.other_socket());
+ if (params.in_out() == SOCK_IN) {
+ if (params.other_socket().type == SOCK_GEOMETRY) {
+ params.add_item(IFACE_("Geometry"), [node_type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node(node_type);
+ params.connect_available_socket(node, "Geometry");
+ });
+ }
+ if (type) {
+ params.add_item(IFACE_("Attribute"), [&](LinkSearchOpParams &params) {
+ bNode &node = params.add_node(node_type);
+ node.custom1 = *type;
+ params.update_and_connect_available_socket(node, "Attribute");
+ });
+ }
+ }
+ else if (type) {
+ /* Only use the first 8 declarations since we set the type automatically. */
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ for (const SocketDeclarationPtr &socket_decl : declaration.outputs().take_front(8)) {
+ StringRefNull name = socket_decl->name();
+ params.add_item(IFACE_(name.c_str()), [node_type, name, type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node(node_type);
+ node.custom1 = *type;
+ params.update_and_connect_available_socket(node, name);
+ });
+ }
+ }
+}
+
template<typename T> static T compute_sum(const Span<T> data)
{
return std::accumulate(data.begin(), data.end(), T());
@@ -146,65 +196,40 @@ static float median_of_sorted_span(const Span<float> data)
}
return median;
}
-static void set_empty(CustomDataType data_type, GeoNodeExecParams &params)
-{
- if (data_type == CD_PROP_FLOAT) {
- params.set_output("Mean", 0.0f);
- params.set_output("Median", 0.0f);
- params.set_output("Sum", 0.0f);
- params.set_output("Min", 0.0f);
- params.set_output("Max", 0.0f);
- params.set_output("Range", 0.0f);
- params.set_output("Standard Deviation", 0.0f);
- params.set_output("Variance", 0.0f);
- }
- else if (data_type == CD_PROP_FLOAT3) {
- params.set_output("Mean_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Median_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Sum_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Min_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Max_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Range_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Standard Deviation_001", float3{0.0f, 0.0f, 0.0f});
- params.set_output("Variance_001", float3{0.0f, 0.0f, 0.0f});
- }
-}
-static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.get_input<GeometrySet>("Geometry");
-
const bNode &node = params.node();
const CustomDataType data_type = static_cast<CustomDataType>(node.custom1);
const AttributeDomain domain = static_cast<AttributeDomain>(node.custom2);
-
- int64_t total_size = 0;
Vector<const GeometryComponent *> components = geometry_set.get_components_for_read();
- for (const GeometryComponent *component : components) {
- if (component->attribute_domain_supported(domain)) {
- total_size += component->attribute_domain_size(domain);
- }
- }
- if (total_size == 0) {
- set_empty(data_type, params);
- return;
- }
+ const Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
switch (data_type) {
case CD_PROP_FLOAT: {
const Field<float> input_field = params.get_input<Field<float>>("Attribute");
- Array<float> data = Array<float>(total_size);
- int offset = 0;
+ Vector<float> data;
for (const GeometryComponent *component : components) {
if (component->attribute_domain_supported(domain)) {
GeometryComponentFieldContext field_context{*component, domain};
const int domain_size = component->attribute_domain_size(domain);
+
fn::FieldEvaluator data_evaluator{field_context, domain_size};
- MutableSpan<float> component_result = data.as_mutable_span().slice(offset, domain_size);
- data_evaluator.add_with_destination(input_field, component_result);
+ data_evaluator.add(input_field);
+ data_evaluator.set_selection(selection_field);
data_evaluator.evaluate();
- offset += domain_size;
+ const VArray<float> &component_data = data_evaluator.get_evaluated<float>(0);
+ const IndexMask selection = data_evaluator.get_evaluated_selection_as_mask();
+
+ const int next_data_index = data.size();
+ data.resize(next_data_index + selection.size());
+ MutableSpan<float> selected_data = data.as_mutable_span().slice(next_data_index,
+ selection.size());
+ for (const int i : selection.index_range()) {
+ selected_data[i] = component_data[selection[i]];
+ }
}
}
@@ -225,7 +250,7 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
const bool variance_required = params.output_is_required("Standard Deviation") ||
params.output_is_required("Variance");
- if (total_size != 0) {
+ if (data.size() != 0) {
if (sort_required) {
std::sort(data.begin(), data.end());
median = median_of_sorted_span(data);
@@ -236,7 +261,7 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
}
if (sum_required || variance_required) {
sum = compute_sum<float>(data);
- mean = sum / total_size;
+ mean = sum / data.size();
if (variance_required) {
variance = compute_variance(data, mean);
@@ -263,18 +288,26 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
}
case CD_PROP_FLOAT3: {
const Field<float3> input_field = params.get_input<Field<float3>>("Attribute_001");
-
- Array<float3> data = Array<float3>(total_size);
- int offset = 0;
+ Vector<float3> data;
for (const GeometryComponent *component : components) {
if (component->attribute_domain_supported(domain)) {
GeometryComponentFieldContext field_context{*component, domain};
const int domain_size = component->attribute_domain_size(domain);
+
fn::FieldEvaluator data_evaluator{field_context, domain_size};
- MutableSpan<float3> component_result = data.as_mutable_span().slice(offset, domain_size);
- data_evaluator.add_with_destination(input_field, component_result);
+ data_evaluator.add(input_field);
+ data_evaluator.set_selection(selection_field);
data_evaluator.evaluate();
- offset += domain_size;
+ const VArray<float3> &component_data = data_evaluator.get_evaluated<float3>(0);
+ const IndexMask selection = data_evaluator.get_evaluated_selection_as_mask();
+
+ const int next_data_index = data.size();
+ data.resize(data.size() + selection.size());
+ MutableSpan<float3> selected_data = data.as_mutable_span().slice(next_data_index,
+ selection.size());
+ for (const int i : selection.index_range()) {
+ selected_data[i] = component_data[selection[i]];
+ }
}
}
@@ -299,9 +332,9 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
Array<float> data_y;
Array<float> data_z;
if (sort_required || variance_required) {
- data_x.reinitialize(total_size);
- data_y.reinitialize(total_size);
- data_z.reinitialize(total_size);
+ data_x.reinitialize(data.size());
+ data_y.reinitialize(data.size());
+ data_z.reinitialize(data.size());
for (const int i : data.index_range()) {
data_x[i] = data[i].x;
data_y[i] = data[i].y;
@@ -309,7 +342,7 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
}
}
- if (total_size != 0) {
+ if (data.size() != 0) {
if (sort_required) {
std::sort(data_x.begin(), data_x.end());
std::sort(data_y.begin(), data_y.end());
@@ -326,7 +359,7 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
}
if (sum_required || variance_required) {
sum = compute_sum(data.as_span());
- mean = sum / total_size;
+ mean = sum / data.size();
if (variance_required) {
const float x_variance = compute_variance(data_x, mean.x);
@@ -360,19 +393,22 @@ static void geo_node_attribute_statistic_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_attribute_statistic_cc
void register_node_type_geo_attribute_statistic()
{
+ namespace file_ns = blender::nodes::node_geo_attribute_statistic_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_ATTRIBUTE_STATISTIC, "Attribute Statistic", NODE_CLASS_ATTRIBUTE, 0);
- ntype.declare = blender::nodes::geo_node_attribute_statistic_declare;
- node_type_init(&ntype, blender::nodes::geo_node_attribute_statistic_init);
- node_type_update(&ntype, blender::nodes::geo_node_attribute_statistic_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_attribute_statistic_exec;
- ntype.draw_buttons = blender::nodes::geo_node_attribute_statistic_layout;
+ ntype.declare = file_ns::node_declare;
+ 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.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index dba051fe13d..0947632cc09 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -23,9 +23,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_boolean_cc {
-static void geo_node_boolean_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh 1"))
.only_realized_data()
@@ -36,12 +36,12 @@ static void geo_node_boolean_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void geo_node_boolean_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
}
-static void geo_node_boolean_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
GeometryNodeBooleanOperation operation = (GeometryNodeBooleanOperation)node->custom1;
@@ -63,12 +63,12 @@ static void geo_node_boolean_update(bNodeTree *ntree, bNode *node)
}
}
-static void geo_node_boolean_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
node->custom1 = GEO_NODE_BOOLEAN_DIFFERENCE;
}
-static void geo_node_boolean_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometryNodeBooleanOperation operation = (GeometryNodeBooleanOperation)params.node().custom1;
const bool use_self = params.get_input<bool>("Self Intersection");
@@ -119,17 +119,19 @@ static void geo_node_boolean_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(result));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_boolean_cc
void register_node_type_geo_boolean()
{
+ namespace file_ns = blender::nodes::node_geo_boolean_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_BOOLEAN, "Mesh Boolean", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_boolean_declare;
- ntype.draw_buttons = blender::nodes::geo_node_boolean_layout;
- ntype.updatefunc = blender::nodes::geo_node_boolean_update;
- node_type_init(&ntype, blender::nodes::geo_node_boolean_init);
- ntype.geometry_node_execute = blender::nodes::geo_node_boolean_exec;
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.updatefunc = file_ns::node_update;
+ node_type_init(&ntype, file_ns::node_init);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
index e7c9715934a..da1f9a00c69 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_bounding_box_cc {
-static void geo_node_bounding_box_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Geometry>(N_("Bounding Box"));
@@ -26,7 +26,7 @@ static void geo_node_bounding_box_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Max"));
}
-static void geo_node_bounding_box_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -78,14 +78,16 @@ static void geo_node_bounding_box_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_bounding_box_cc
void register_node_type_geo_bounding_box()
{
+ namespace file_ns = blender::nodes::node_geo_bounding_box_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_BOUNDING_BOX, "Bounding Box", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_bounding_box_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_bounding_box_exec;
+ 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/node_geo_collection_info.cc b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
index 503711fedfe..6b8c895879d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
@@ -27,9 +27,11 @@
#include <algorithm>
-namespace blender::nodes {
+namespace blender::nodes::node_geo_collection_info_cc {
-static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCollectionInfo)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Collection>(N_("Collection")).hide_label();
b.add_input<decl::Bool>(N_("Separate Children"))
@@ -42,12 +44,12 @@ static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_collection_info_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_collection_info_node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCollectionInfo *data = (NodeGeometryCollectionInfo *)MEM_callocN(
sizeof(NodeGeometryCollectionInfo), __func__);
@@ -61,14 +63,12 @@ struct InstanceListEntry {
float4x4 transform;
};
-static void geo_node_collection_info_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Collection *collection = params.get_input<Collection *>("Collection");
- GeometrySet geometry_set_out;
-
if (collection == nullptr) {
- params.set_output("Geometry", geometry_set_out);
+ params.set_default_remaining_outputs();
return;
}
const Object *self_object = params.self_object();
@@ -76,15 +76,15 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
(Object *)self_object);
if (is_recursive) {
params.error_message_add(NodeWarningType::Error, "Collection contains current object");
- params.set_output("Geometry", geometry_set_out);
+ params.set_default_remaining_outputs();
return;
}
- const bNode &bnode = params.node();
- NodeGeometryCollectionInfo *node_storage = (NodeGeometryCollectionInfo *)bnode.storage;
- const bool use_relative_transform = (node_storage->transform_space ==
+ const NodeGeometryCollectionInfo &storage = node_storage(params.node());
+ const bool use_relative_transform = (storage.transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
+ GeometrySet geometry_set_out;
InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
const bool separate_children = params.get_input<bool>("Separate Children");
@@ -155,20 +155,22 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
params.set_output("Geometry", geometry_set_out);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_collection_info_cc
void register_node_type_geo_collection_info()
{
+ namespace file_ns = blender::nodes::node_geo_collection_info_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_COLLECTION_INFO, "Collection Info", NODE_CLASS_INPUT, 0);
- ntype.declare = blender::nodes::geo_node_collection_info_declare;
- node_type_init(&ntype, blender::nodes::geo_node_collection_info_node_init);
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::node_node_init);
node_type_storage(&ntype,
"NodeGeometryCollectionInfo",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.geometry_node_execute = blender::nodes::geo_node_collection_info_exec;
- ntype.draw_buttons = blender::nodes::geo_node_collection_info_layout;
+ 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_common.cc b/source/blender/nodes/geometry/nodes/node_geo_common.cc
index 9ebbdd349de..64b7a80bdb4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_common.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_common.cc
@@ -22,7 +22,7 @@
#include "node_common.h"
#include "node_geometry_util.hh"
-void register_node_type_geo_group(void)
+void register_node_type_geo_group()
{
static bNodeType ntype;
@@ -37,7 +37,7 @@ void register_node_type_geo_group(void)
node_type_socket_templates(&ntype, nullptr, nullptr);
node_type_size(&ntype, 140, 60, 400);
- node_type_label(&ntype, node_group_label);
+ ntype.labelfunc = node_group_label;
node_type_group_update(&ntype, node_group_update);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index 221fb421ab4..56c1e95bd70 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -28,9 +28,9 @@
# include "RBI_hull_api.h"
#endif
-namespace blender::nodes {
+namespace blender::nodes::node_geo_convex_hull_cc {
-static void geo_node_convex_hull_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Geometry>(N_("Convex Hull"));
@@ -296,7 +296,7 @@ static Mesh *convex_hull_from_instances(const GeometrySet &geometry_set)
#endif /* WITH_BULLET */
-static void geo_node_convex_hull_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -312,18 +312,20 @@ static void geo_node_convex_hull_exec(GeoNodeExecParams params)
#else
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without Bullet"));
- params.set_output("Convex Hull", geometry_set);
+ params.set_default_remaining_outputs();
#endif /* WITH_BULLET */
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_convex_hull_cc
void register_node_type_geo_convex_hull()
{
+ namespace file_ns = blender::nodes::node_geo_convex_hull_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CONVEX_HULL, "Convex Hull", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_convex_hull_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_convex_hull_exec;
+ 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/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
index c41b76412e9..fc407414667 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
@@ -21,9 +21,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_endpoint_select_cc {
-static void geo_node_curve_endpoint_selection_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Start Size"))
.min(0)
@@ -51,69 +51,61 @@ static void select_by_spline(const int start, const int end, MutableSpan<bool> r
r_selection.slice(size - end_use, end_use).fill(true);
}
-class EndpointFieldInput final : public fn::FieldInput {
+class EndpointFieldInput final : public GeometryFieldInput {
Field<int> start_size_;
Field<int> end_size_;
public:
EndpointFieldInput(Field<int> start_size, Field<int> end_size)
- : FieldInput(CPPType::get<bool>(), "Endpoint Selection node"),
+ : GeometryFieldInput(CPPType::get<bool>(), "Endpoint Selection node"),
start_size_(start_size),
end_size_(end_size)
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask UNUSED(mask),
- ResourceScope &UNUSED(scope)) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
+ if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
+ return nullptr;
+ }
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
- if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
- return nullptr;
- }
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ const CurveEval *curve = curve_component.get_for_read();
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- const CurveEval *curve = curve_component.get_for_read();
+ Array<int> control_point_offsets = curve->control_point_offsets();
- Array<int> control_point_offsets = curve->control_point_offsets();
+ if (curve == nullptr || control_point_offsets.last() == 0) {
+ return nullptr;
+ }
- if (curve == nullptr || control_point_offsets.last() == 0) {
- return nullptr;
+ GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
+ fn::FieldEvaluator evaluator{size_context, curve->splines().size()};
+ evaluator.add(start_size_);
+ evaluator.add(end_size_);
+ evaluator.evaluate();
+ const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
+ const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
+
+ const int point_size = control_point_offsets.last();
+ Array<bool> selection(point_size, false);
+ int current_point = 0;
+ MutableSpan<bool> selection_span = selection.as_mutable_span();
+ for (int i : IndexRange(curve->splines().size())) {
+ const SplinePtr &spline = curve->splines()[i];
+ if (start_size[i] <= 0 && end_size[i] <= 0) {
+ selection_span.slice(current_point, spline->size()).fill(false);
}
-
- GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
- fn::FieldEvaluator evaluator{size_context, curve->splines().size()};
- evaluator.add(start_size_);
- evaluator.add(end_size_);
- evaluator.evaluate();
- const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
- const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
-
- const int point_size = control_point_offsets.last();
- Array<bool> selection(point_size, false);
- int current_point = 0;
- MutableSpan<bool> selection_span = selection.as_mutable_span();
- for (int i : IndexRange(curve->splines().size())) {
- const SplinePtr &spline = curve->splines()[i];
- if (start_size[i] <= 0 && end_size[i] <= 0) {
- selection_span.slice(current_point, spline->size()).fill(false);
- }
- else {
- int start_use = std::max(start_size[i], 0);
- int end_use = std::max(end_size[i], 0);
- select_by_spline(
- start_use, end_use, selection_span.slice(current_point, spline->size()));
- }
- current_point += spline->size();
+ else {
+ int start_use = std::max(start_size[i], 0);
+ int end_use = std::max(end_size[i], 0);
+ select_by_spline(start_use, end_use, selection_span.slice(current_point, spline->size()));
}
- return VArray<bool>::ForContainer(std::move(selection));
+ current_point += spline->size();
}
- return {};
+ return VArray<bool>::ForContainer(std::move(selection));
};
uint64_t hash() const override
@@ -131,23 +123,25 @@ class EndpointFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_curve_endpoint_selection_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<int> start_size = params.extract_input<Field<int>>("Start Size");
Field<int> end_size = params.extract_input<Field<int>>("End Size");
Field<bool> selection_field{std::make_shared<EndpointFieldInput>(start_size, end_size)};
params.set_output("Selection", std::move(selection_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_endpoint_select_cc
void register_node_type_geo_curve_endpoint_selection()
{
+ namespace file_ns = blender::nodes::node_geo_curve_endpoint_select_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_ENDPOINT_SELECTION, "Endpoint Selection", NODE_CLASS_INPUT, 0);
- ntype.declare = blender::nodes::geo_node_curve_endpoint_selection_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_endpoint_selection_exec;
+ 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/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
index 219effadec4..3aabf8e21eb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
@@ -31,20 +31,22 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_fill_cc {
-static void geo_node_curve_fill_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveFill)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void geo_node_curve_fill_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_fill_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryCurveFill *data = (NodeGeometryCurveFill *)MEM_callocN(sizeof(NodeGeometryCurveFill),
__func__);
@@ -147,11 +149,11 @@ static void curve_fill_calculate(GeometrySet &geometry_set, const GeometryNodeCu
geometry_set.replace_curve(nullptr);
}
-static void geo_node_curve_fill_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- const NodeGeometryCurveFill &storage = *(const NodeGeometryCurveFill *)params.node().storage;
+ const NodeGeometryCurveFill &storage = node_storage(params.node());
const GeometryNodeCurveFillMode mode = (GeometryNodeCurveFillMode)storage.mode;
geometry_set.modify_geometry_sets(
@@ -160,19 +162,21 @@ static void geo_node_curve_fill_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_fill_cc
void register_node_type_geo_curve_fill()
{
+ namespace file_ns = blender::nodes::node_geo_curve_fill_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_FILL_CURVE, "Fill Curve", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_curve_fill_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(
&ntype, "NodeGeometryCurveFill", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_curve_fill_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_fill_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_fill_layout;
+ 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/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index a320f35c539..a438c1d6086 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -25,12 +25,19 @@
#include "BKE_spline.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_fillet_cc {
-static void geo_node_curve_fillet_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveFillet)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
- b.add_input<decl::Int>(N_("Count")).default_value(1).min(1).max(1000).supports_field();
+ b.add_input<decl::Int>(N_("Count"))
+ .default_value(1)
+ .min(1)
+ .max(1000)
+ .supports_field()
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_FILLET_POLY; });
b.add_input<decl::Float>(N_("Radius"))
.min(0.0f)
.max(FLT_MAX)
@@ -41,12 +48,12 @@ static void geo_node_curve_fillet_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_fillet_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_fillet_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveFillet *data = (NodeGeometryCurveFillet *)MEM_callocN(
sizeof(NodeGeometryCurveFillet), __func__);
@@ -76,10 +83,10 @@ struct FilletData {
Array<int> counts;
};
-static void geo_node_curve_fillet_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryCurveFillet &node_storage = *(NodeGeometryCurveFillet *)node->storage;
- const GeometryNodeCurveFilletMode mode = (GeometryNodeCurveFilletMode)node_storage.mode;
+ const NodeGeometryCurveFillet &storage = node_storage(*node);
+ const GeometryNodeCurveFilletMode mode = (GeometryNodeCurveFilletMode)storage.mode;
bNodeSocket *poly_socket = ((bNodeSocket *)node->inputs.first)->next;
@@ -332,14 +339,17 @@ static void copy_common_attributes_by_mapping(const Spline &src,
copy_attribute_by_mapping(src.radii(), dst.radii(), mapping);
copy_attribute_by_mapping(src.tilts(), dst.tilts(), mapping);
- dst.attributes.reallocate(1);
src.attributes.foreach_attribute(
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
std::optional<GSpan> src_attribute = src.attributes.get_for_read(attribute_id);
if (dst.attributes.create(attribute_id, meta_data.data_type)) {
std::optional<GMutableSpan> dst_attribute = dst.attributes.get_for_write(attribute_id);
if (dst_attribute) {
- src_attribute->type().copy_assign(src_attribute->data(), dst_attribute->data());
+ attribute_math::convert_to_static_type(dst_attribute->type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ copy_attribute_by_mapping(
+ src_attribute->typed<T>(), dst_attribute->typed<T>(), mapping);
+ });
return true;
}
}
@@ -607,12 +617,12 @@ static void calculate_curve_fillet(GeometrySet &geometry_set,
geometry_set.replace_curve(output_curve.release());
}
-static void geo_node_fillet_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- NodeGeometryCurveFillet &node_storage = *(NodeGeometryCurveFillet *)params.node().storage;
- const GeometryNodeCurveFilletMode mode = (GeometryNodeCurveFilletMode)node_storage.mode;
+ const NodeGeometryCurveFillet &storage = node_storage(params.node());
+ const GeometryNodeCurveFilletMode mode = (GeometryNodeCurveFilletMode)storage.mode;
Field<float> radius_field = params.extract_input<Field<float>>("Radius");
const bool limit_radius = params.extract_input<bool>("Limit Radius");
@@ -629,19 +639,21 @@ static void geo_node_fillet_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_fillet_cc
void register_node_type_geo_curve_fillet()
{
+ namespace file_ns = blender::nodes::node_geo_curve_fillet_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_FILLET_CURVE, "Fillet Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.draw_buttons = blender::nodes::geo_node_curve_fillet_layout;
+ ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
&ntype, "NodeGeometryCurveFillet", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_curve_fillet_declare;
- node_type_init(&ntype, blender::nodes::geo_node_curve_fillet_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_fillet_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_fillet_exec;
+ ntype.declare = file_ns::node_declare;
+ 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/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
index 5fb17270301..381bb0fc1d0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
@@ -21,22 +21,22 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_handle_type_selection_cc {
-static void geo_node_curve_handle_type_selection_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveSelectHandles)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Bool>(N_("Selection")).field_source();
}
-static void geo_node_curve_handle_type_selection_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_curve_handle_type_selection_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSelectHandles *data = (NodeGeometryCurveSelectHandles *)MEM_callocN(
sizeof(NodeGeometryCurveSelectHandles), __func__);
@@ -85,44 +85,40 @@ static void select_by_handle_type(const CurveEval &curve,
}
}
-class HandleTypeFieldInput final : public fn::FieldInput {
+class HandleTypeFieldInput final : public GeometryFieldInput {
BezierSpline::HandleType type_;
GeometryNodeCurveHandleMode mode_;
public:
HandleTypeFieldInput(BezierSpline::HandleType type, GeometryNodeCurveHandleMode mode)
- : FieldInput(CPPType::get<bool>(), "Handle Type Selection node"), type_(type), mode_(mode)
+ : GeometryFieldInput(CPPType::get<bool>(), "Handle Type Selection node"),
+ type_(type),
+ mode_(mode)
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask mask,
- ResourceScope &UNUSED(scope)) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask mask) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
-
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
- if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
- return {};
- }
+ if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
+ return {};
+ }
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- const CurveEval *curve = curve_component.get_for_read();
- if (curve == nullptr) {
- return {};
- }
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ const CurveEval *curve = curve_component.get_for_read();
+ if (curve == nullptr) {
+ return {};
+ }
- if (domain == ATTR_DOMAIN_POINT) {
- Array<bool> selection(mask.min_array_size());
- select_by_handle_type(*curve, type_, mode_, selection);
- return VArray<bool>::ForContainer(std::move(selection));
- }
+ if (domain == ATTR_DOMAIN_POINT) {
+ Array<bool> selection(mask.min_array_size());
+ select_by_handle_type(*curve, type_, mode_, selection);
+ return VArray<bool>::ForContainer(std::move(selection));
}
return {};
- };
+ }
uint64_t hash() const override
{
@@ -140,34 +136,35 @@ class HandleTypeFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_curve_handle_type_selection_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryCurveSelectHandles *storage =
- (const NodeGeometryCurveSelectHandles *)params.node().storage;
+ const NodeGeometryCurveSelectHandles &storage = node_storage(params.node());
const BezierSpline::HandleType handle_type = handle_type_from_input_type(
- (GeometryNodeCurveHandleType)storage->handle_type);
- const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)storage->mode;
+ (GeometryNodeCurveHandleType)storage.handle_type);
+ const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)storage.mode;
Field<bool> selection_field{std::make_shared<HandleTypeFieldInput>(handle_type, mode)};
params.set_output("Selection", std::move(selection_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_handle_type_selection_cc
void register_node_type_geo_curve_handle_type_selection()
{
+ namespace file_ns = blender::nodes::node_geo_curve_handle_type_selection_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_HANDLE_TYPE_SELECTION, "Handle Type Selection", NODE_CLASS_INPUT, 0);
- ntype.declare = blender::nodes::geo_node_curve_handle_type_selection_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_handle_type_selection_exec;
- node_type_init(&ntype, blender::nodes::geo_node_curve_handle_type_selection_init);
+ 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 = blender::nodes::geo_node_curve_handle_type_selection_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_length.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_length.cc
index 0d0dc0ec89c..73ad8a8cf65 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_length.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_length.cc
@@ -17,19 +17,19 @@
#include "BKE_spline.hh"
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_length_cc {
-static void geo_node_curve_length_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_output<decl::Float>(N_("Length"));
}
-static void geo_node_curve_length_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet curve_set = params.extract_input<GeometrySet>("Curve");
if (!curve_set.has_curve()) {
- params.set_output("Length", 0.0f);
+ params.set_default_remaining_outputs();
return;
}
const CurveEval &curve = *curve_set.get_curve_for_read();
@@ -40,14 +40,16 @@ static void geo_node_curve_length_exec(GeoNodeExecParams params)
params.set_output("Length", length);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_length_cc
void register_node_type_geo_curve_length()
{
+ namespace file_ns = blender::nodes::node_geo_curve_length_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_LENGTH, "Curve Length", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_length_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_length_exec;
+ 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/node_geo_curve_primitive_bezier_segment.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
index 673a5095044..4299b5cc022 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_bezier_segment.cc
@@ -21,9 +21,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_bezier_segment_cc {
-static void geo_node_curve_primitive_bezier_segment_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveBezierSegment)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Resolution"))
.default_value(16)
@@ -53,14 +55,12 @@ static void geo_node_curve_primitive_bezier_segment_declare(NodeDeclarationBuild
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_primitive_bezier_segment_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_primitive_bezier_segment_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurvePrimitiveBezierSegment *data = (NodeGeometryCurvePrimitiveBezierSegment *)
MEM_callocN(sizeof(NodeGeometryCurvePrimitiveBezierSegment), __func__);
@@ -120,12 +120,11 @@ static std::unique_ptr<CurveEval> create_bezier_segment_curve(
return curve;
}
-static void geo_node_curve_primitive_bezier_segment_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryCurvePrimitiveBezierSegment *node_storage =
- (NodeGeometryCurvePrimitiveBezierSegment *)params.node().storage;
+ const NodeGeometryCurvePrimitiveBezierSegment &storage = node_storage(params.node());
const GeometryNodeCurvePrimitiveBezierSegmentMode mode =
- (const GeometryNodeCurvePrimitiveBezierSegmentMode)node_storage->mode;
+ (const GeometryNodeCurvePrimitiveBezierSegmentMode)storage.mode;
std::unique_ptr<CurveEval> curve = create_bezier_segment_curve(
params.extract_input<float3>("Start"),
@@ -137,20 +136,22 @@ static void geo_node_curve_primitive_bezier_segment_exec(GeoNodeExecParams param
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_bezier_segment_cc
void register_node_type_geo_curve_primitive_bezier_segment()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_bezier_segment_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT, "Bezier Segment", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_curve_primitive_bezier_segment_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveBezierSegment",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_curve_primitive_bezier_segment_declare;
- ntype.draw_buttons = blender::nodes::geo_node_curve_primitive_bezier_segment_layout;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_bezier_segment_exec;
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
index 5d8beb9c9d8..70abf4c64a7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_circle.cc
@@ -21,9 +21,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_circle_cc {
-static void geo_node_curve_primitive_circle_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveCircle)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Resolution"))
.default_value(32)
@@ -54,17 +56,17 @@ static void geo_node_curve_primitive_circle_declare(NodeDeclarationBuilder &b)
.subtype(PROP_DISTANCE)
.description(N_("Distance of the points from the origin"));
b.add_output<decl::Geometry>(N_("Curve"));
- b.add_output<decl::Vector>(N_("Center"));
+ b.add_output<decl::Vector>(N_("Center")).make_available([](bNode &node) {
+ node_storage(node).mode = GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS;
+ });
}
-static void geo_node_curve_primitive_circle_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_primitive_circle_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurvePrimitiveCircle *data = (NodeGeometryCurvePrimitiveCircle *)MEM_callocN(
sizeof(NodeGeometryCurvePrimitiveCircle), __func__);
@@ -73,12 +75,11 @@ static void geo_node_curve_primitive_circle_init(bNodeTree *UNUSED(tree), bNode
node->storage = data;
}
-static void geo_node_curve_primitive_circle_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryCurvePrimitiveCircle *node_storage = (NodeGeometryCurvePrimitiveCircle *)
- node->storage;
- const GeometryNodeCurvePrimitiveCircleMode mode = (const GeometryNodeCurvePrimitiveCircleMode)
- node_storage->mode;
+ const NodeGeometryCurvePrimitiveCircle &storage = node_storage(*node);
+ const GeometryNodeCurvePrimitiveCircleMode mode = (GeometryNodeCurvePrimitiveCircleMode)
+ storage.mode;
bNodeSocket *start_socket = ((bNodeSocket *)node->inputs.first)->next;
bNodeSocket *middle_socket = start_socket->next;
@@ -195,13 +196,11 @@ static std::unique_ptr<CurveEval> create_radius_circle_curve(const int resolutio
return curve;
}
-static void geo_node_curve_primitive_circle_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryCurvePrimitiveCircle *node_storage =
- (NodeGeometryCurvePrimitiveCircle *)params.node().storage;
-
+ const NodeGeometryCurvePrimitiveCircle &storage = node_storage(params.node());
const GeometryNodeCurvePrimitiveCircleMode mode = (GeometryNodeCurvePrimitiveCircleMode)
- node_storage->mode;
+ storage.mode;
std::unique_ptr<CurveEval> curve;
if (mode == GEO_NODE_CURVE_PRIMITIVE_CIRCLE_TYPE_POINTS) {
@@ -222,26 +221,28 @@ static void geo_node_curve_primitive_circle_exec(GeoNodeExecParams params)
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
else {
- params.set_output("Curve", GeometrySet());
+ params.set_default_remaining_outputs();
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_circle_cc
void register_node_type_geo_curve_primitive_circle()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_circle_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_PRIMITIVE_CIRCLE, "Curve Circle", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_curve_primitive_circle_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_primitive_circle_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveCircle",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_curve_primitive_circle_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_circle_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_primitive_circle_layout;
+ 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/node_geo_curve_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
index 238fc77e1cc..6d71c97b15a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_line.cc
@@ -21,9 +21,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_line_cc {
-static void geo_node_curve_primitive_line_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveLine)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Vector>(N_("Start"))
.subtype(PROP_TRANSLATION)
@@ -43,14 +45,12 @@ static void geo_node_curve_primitive_line_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_primitive_line_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_primitive_line_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurvePrimitiveLine *data = (NodeGeometryCurvePrimitiveLine *)MEM_callocN(
sizeof(NodeGeometryCurvePrimitiveLine), __func__);
@@ -59,12 +59,10 @@ static void geo_node_curve_primitive_line_init(bNodeTree *UNUSED(tree), bNode *n
node->storage = data;
}
-static void geo_node_curve_primitive_line_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryCurvePrimitiveLine *node_storage = (NodeGeometryCurvePrimitiveLine *)
- node->storage;
- const GeometryNodeCurvePrimitiveLineMode mode = (const GeometryNodeCurvePrimitiveLineMode)
- node_storage->mode;
+ const NodeGeometryCurvePrimitiveLine &storage = node_storage(*node);
+ const GeometryNodeCurvePrimitiveLineMode mode = (GeometryNodeCurvePrimitiveLineMode)storage.mode;
bNodeSocket *p2_socket = ((bNodeSocket *)node->inputs.first)->next;
bNodeSocket *direction_socket = p2_socket->next;
@@ -112,13 +110,10 @@ static std::unique_ptr<CurveEval> create_direction_line_curve(const float3 start
return curve;
}
-static void geo_node_curve_primitive_line_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
-
- const NodeGeometryCurvePrimitiveLine *node_storage =
- (NodeGeometryCurvePrimitiveLine *)params.node().storage;
-
- GeometryNodeCurvePrimitiveLineMode mode = (GeometryNodeCurvePrimitiveLineMode)node_storage->mode;
+ const NodeGeometryCurvePrimitiveLine &storage = node_storage(params.node());
+ const GeometryNodeCurvePrimitiveLineMode mode = (GeometryNodeCurvePrimitiveLineMode)storage.mode;
std::unique_ptr<CurveEval> curve;
if (mode == GEO_NODE_CURVE_PRIMITIVE_LINE_MODE_POINTS) {
@@ -134,20 +129,22 @@ static void geo_node_curve_primitive_line_exec(GeoNodeExecParams params)
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_line_cc
void register_node_type_geo_curve_primitive_line()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_line_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_LINE, "Curve Line", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_curve_primitive_line_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_primitive_line_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveLine",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_curve_primitive_line_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_line_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_primitive_line_layout;
+ 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/node_geo_curve_primitive_quadratic_bezier.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadratic_bezier.cc
index 27bf4a310df..92a9b1b4966 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadratic_bezier.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadratic_bezier.cc
@@ -17,9 +17,9 @@
#include "BKE_spline.hh"
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_quadratic_bezier_cc {
-static void geo_node_curve_primitive_quadratic_bezier_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Resolution"))
.default_value(16)
@@ -64,7 +64,7 @@ static std::unique_ptr<CurveEval> create_quadratic_bezier_curve(const float3 p1,
return curve;
}
-static void geo_node_curve_primitive_quadratic_bezier_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
std::unique_ptr<CurveEval> curve = create_quadratic_bezier_curve(
params.extract_input<float3>("Start"),
@@ -74,17 +74,19 @@ static void geo_node_curve_primitive_quadratic_bezier_exec(GeoNodeExecParams par
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_quadratic_bezier_cc
void register_node_type_geo_curve_primitive_quadratic_bezier()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_quadratic_bezier_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype,
GEO_NODE_CURVE_PRIMITIVE_QUADRATIC_BEZIER,
"Quadratic Bezier",
NODE_CLASS_GEOMETRY,
0);
- ntype.declare = blender::nodes::geo_node_curve_primitive_quadratic_bezier_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_quadratic_bezier_exec;
+ 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/node_geo_curve_primitive_quadrilateral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
index 114ae441d99..ff6294b9b6b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc
@@ -17,11 +17,16 @@
#include "BKE_spline.hh"
#include "UI_interface.h"
#include "UI_resources.h"
+
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_quadrilaterial_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometryCurvePrimitiveQuad)
-static void geo_node_curve_primitive_quadrilateral_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>(N_("Width"))
.default_value(2.0f)
@@ -77,14 +82,12 @@ static void geo_node_curve_primitive_quadrilateral_declare(NodeDeclarationBuilde
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_primitive_quadrilateral_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void geo_node_curve_primitive_quadrilateral_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurvePrimitiveQuad *data = (NodeGeometryCurvePrimitiveQuad *)MEM_callocN(
sizeof(NodeGeometryCurvePrimitiveQuad), __func__);
@@ -92,11 +95,11 @@ static void geo_node_curve_primitive_quadrilateral_init(bNodeTree *UNUSED(tree),
node->storage = data;
}
-static void geo_node_curve_primitive_quadrilateral_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryCurvePrimitiveQuad &node_storage = *(NodeGeometryCurvePrimitiveQuad *)node->storage;
+ const NodeGeometryCurvePrimitiveQuad &storage = node_storage(*node);
GeometryNodeCurvePrimitiveQuadMode mode = static_cast<GeometryNodeCurvePrimitiveQuadMode>(
- node_storage.mode);
+ storage.mode);
bNodeSocket *width = ((bNodeSocket *)node->inputs.first);
bNodeSocket *height = width->next;
@@ -142,6 +145,41 @@ static void geo_node_curve_primitive_quadrilateral_update(bNodeTree *ntree, bNod
}
}
+class SocketSearchOp {
+ public:
+ std::string socket_name;
+ GeometryNodeCurvePrimitiveQuadMode quad_mode;
+ void operator()(LinkSearchOpParams &params)
+ {
+ bNode &node = params.add_node("GeometryNodeCurvePrimitiveQuadrilateral");
+ node_storage(node).mode = quad_mode;
+ params.update_and_connect_available_socket(node, socket_name);
+ }
+};
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ if (params.in_out() == SOCK_OUT) {
+ search_link_ops_for_declarations(params, declaration.outputs());
+ }
+ else if (params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ params.add_item(IFACE_("Width"),
+ SocketSearchOp{"Width", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE});
+ params.add_item(IFACE_("Height"),
+ SocketSearchOp{"Height", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_RECTANGLE});
+ params.add_item(IFACE_("Bottom Width"),
+ SocketSearchOp{"Bottom Width", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_TRAPEZOID});
+ params.add_item(IFACE_("Top Width"),
+ SocketSearchOp{"Top Width", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_TRAPEZOID});
+ params.add_item(IFACE_("Offset"),
+ SocketSearchOp{"Offset", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_PARALLELOGRAM});
+ params.add_item(IFACE_("Point 1"),
+ SocketSearchOp{"Point 1", GEO_NODE_CURVE_PRIMITIVE_QUAD_MODE_POINTS});
+ }
+}
+
static void create_rectangle_curve(MutableSpan<float3> positions,
const float height,
const float width)
@@ -197,12 +235,10 @@ static void create_kite_curve(MutableSpan<float3> positions,
positions[3] = float3(-width / 2.0f, 0, 0);
}
-static void geo_node_curve_primitive_quadrilateral_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryCurvePrimitiveQuad &node_storage =
- *(NodeGeometryCurvePrimitiveQuad *)(params.node()).storage;
- const GeometryNodeCurvePrimitiveQuadMode mode = static_cast<GeometryNodeCurvePrimitiveQuadMode>(
- node_storage.mode);
+ const NodeGeometryCurvePrimitiveQuad &storage = node_storage(params.node());
+ const GeometryNodeCurvePrimitiveQuadMode mode = (GeometryNodeCurvePrimitiveQuadMode)storage.mode;
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
@@ -246,7 +282,7 @@ static void geo_node_curve_primitive_quadrilateral_exec(GeoNodeExecParams params
params.extract_input<float3>("Point 4"));
break;
default:
- params.set_output("Curve", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -255,21 +291,24 @@ static void geo_node_curve_primitive_quadrilateral_exec(GeoNodeExecParams params
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_quadrilaterial_cc
void register_node_type_geo_curve_primitive_quadrilateral()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_quadrilaterial_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_PRIMITIVE_QUADRILATERAL, "Quadrilateral", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_primitive_quadrilateral_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_quadrilateral_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_primitive_quadrilateral_layout;
- node_type_update(&ntype, blender::nodes::geo_node_curve_primitive_quadrilateral_update);
- node_type_init(&ntype, blender::nodes::geo_node_curve_primitive_quadrilateral_init);
+ 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_init(&ntype, file_ns::node_init);
node_type_storage(&ntype,
"NodeGeometryCurvePrimitiveQuad",
node_free_standard_storage,
node_copy_standard_storage);
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
index 1384165e520..d5ae3551904 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
@@ -18,9 +18,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_spiral_cc {
-static void geo_node_curve_primitive_spiral_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Resolution"))
.default_value(32)
@@ -81,11 +81,11 @@ static std::unique_ptr<CurveEval> create_spiral_curve(const float rotations,
return curve;
}
-static void geo_node_curve_primitive_spiral_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const float rotations = std::max(params.extract_input<float>("Rotations"), 0.0f);
if (rotations == 0.0f) {
- params.set_output("Curve", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -99,14 +99,16 @@ static void geo_node_curve_primitive_spiral_exec(GeoNodeExecParams params)
params.set_output("Curve", GeometrySet::create_with_curve(curve.release()));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_spiral_cc
void register_node_type_geo_curve_primitive_spiral()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_spiral_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_SPIRAL, "Spiral", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_primitive_spiral_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_spiral_exec;
+ 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/node_geo_curve_primitive_star.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
index 9004681c246..731be0f0f49 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc
@@ -18,9 +18,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_primitive_star_cc {
-static void geo_node_curve_primitive_star_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Points"))
.default_value(8)
@@ -85,7 +85,7 @@ static void create_selection_output(CurveComponent &component,
attribute.save();
}
-static void geo_node_curve_primitive_star_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
std::unique_ptr<CurveEval> curve = create_star_curve(
std::max(params.extract_input<float>("Inner Radius"), 0.0f),
@@ -103,13 +103,15 @@ static void geo_node_curve_primitive_star_exec(GeoNodeExecParams params)
}
params.set_output("Curve", std::move(output));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_primitive_star_cc
void register_node_type_geo_curve_primitive_star()
{
+ namespace file_ns = blender::nodes::node_geo_curve_primitive_star_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_PRIMITIVE_STAR, "Star", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_primitive_star_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_primitive_star_exec;
+ 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/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
index f72978bae50..7e465714265 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
@@ -26,9 +26,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_resample_cc {
-static void geo_node_curve_resample_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveResample)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
@@ -41,12 +43,12 @@ static void geo_node_curve_resample_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_resample_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void geo_node_curve_resample_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveResample *data = (NodeGeometryCurveResample *)MEM_callocN(
sizeof(NodeGeometryCurveResample), __func__);
@@ -55,10 +57,10 @@ static void geo_node_curve_resample_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_curve_resample_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryCurveResample &node_storage = *(NodeGeometryCurveResample *)node->storage;
- const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
+ const NodeGeometryCurveResample &storage = node_storage(*node);
+ const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
bNodeSocket *count_socket = ((bNodeSocket *)node->inputs.first)->next->next;
bNodeSocket *length_socket = count_socket->next;
@@ -189,7 +191,7 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveComponent *component
threading::parallel_for(input_splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
BLI_assert(mode_param.count);
- if (selections[i]) {
+ if (selections[i] && input_splines[i]->evaluated_points_size() > 0) {
output_splines[i] = resample_spline(*input_splines[i], std::max(cuts[i], 1));
}
else {
@@ -208,7 +210,7 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveComponent *component
threading::parallel_for(input_splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
- if (selections[i]) {
+ if (selections[i] && input_splines[i]->evaluated_points_size() > 0) {
/* Don't allow asymptotic count increase for low resolution values. */
const float divide_length = std::max(lengths[i], 0.0001f);
const float spline_length = input_splines[i]->length();
@@ -229,7 +231,7 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveComponent *component
threading::parallel_for(input_splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
- if (selections[i]) {
+ if (selections[i] && input_splines[i]->evaluated_points_size() > 0) {
output_splines[i] = resample_spline_evaluated(*input_splines[i]);
}
else {
@@ -255,12 +257,12 @@ static void geometry_set_curve_resample(GeometrySet &geometry_set,
geometry_set.replace_curve(output_curve.release());
}
-static void geo_node_resample_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- NodeGeometryCurveResample &node_storage = *(NodeGeometryCurveResample *)params.node().storage;
- const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
+ const NodeGeometryCurveResample &storage = node_storage(params.node());
+ const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
SampleModeParam mode_param;
mode_param.mode = mode;
@@ -269,7 +271,7 @@ static void geo_node_resample_exec(GeoNodeExecParams params)
if (mode == GEO_NODE_CURVE_RESAMPLE_COUNT) {
Field<int> count = params.extract_input<Field<int>>("Count");
if (count < 1) {
- params.set_output("Curve", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
mode_param.count.emplace(count);
@@ -285,19 +287,21 @@ static void geo_node_resample_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_resample_cc
void register_node_type_geo_curve_resample()
{
+ namespace file_ns = blender::nodes::node_geo_curve_resample_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_RESAMPLE_CURVE, "Resample Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_resample_declare;
- ntype.draw_buttons = blender::nodes::geo_node_curve_resample_layout;
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
&ntype, "NodeGeometryCurveResample", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_curve_resample_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_resample_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_resample_exec;
+ 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/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index b1dc45a426a..d07e89ec7f2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -20,16 +20,16 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_reverse_cc {
-static void geo_node_curve_reverse_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
@@ -60,13 +60,15 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_reverse_cc
void register_node_type_geo_curve_reverse()
{
+ namespace file_ns = blender::nodes::node_geo_curve_reverse_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_REVERSE_CURVE, "Reverse Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_reverse_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_reverse_exec;
+ 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/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
index 8f42aacab43..eff760266f5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc
@@ -23,27 +23,37 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_sample_cc {
-static void geo_node_curve_sample_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveSample)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve"))
.only_realized_data()
.supported_type(GEO_COMPONENT_TYPE_CURVE);
- b.add_input<decl::Float>(N_("Factor")).min(0.0f).max(1.0f).subtype(PROP_FACTOR).supports_field();
- b.add_input<decl::Float>(N_("Length")).min(0.0f).subtype(PROP_DISTANCE).supports_field();
-
+ b.add_input<decl::Float>(N_("Factor"))
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR)
+ .supports_field()
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; });
+ b.add_input<decl::Float>(N_("Length"))
+ .min(0.0f)
+ .subtype(PROP_DISTANCE)
+ .supports_field()
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; });
b.add_output<decl::Vector>(N_("Position")).dependent_field();
b.add_output<decl::Vector>(N_("Tangent")).dependent_field();
b.add_output<decl::Vector>(N_("Normal")).dependent_field();
}
-static void geo_node_curve_sample_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_sample_type_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_type_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSample *data = (NodeGeometryCurveSample *)MEM_callocN(
sizeof(NodeGeometryCurveSample), __func__);
@@ -51,10 +61,10 @@ static void geo_node_curve_sample_type_init(bNodeTree *UNUSED(tree), bNode *node
node->storage = data;
}
-static void geo_node_curve_sample_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryCurveSample &node_storage = *(NodeGeometryCurveSample *)node->storage;
- const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)node_storage.mode;
+ const NodeGeometryCurveSample &storage = node_storage(*node);
+ const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
bNodeSocket *factor = ((bNodeSocket *)node->inputs.first)->next;
bNodeSocket *length = factor->next;
@@ -200,8 +210,8 @@ class SampleCurveFunction : public fn::MultiFunction {
static Field<float> get_length_input_field(const GeoNodeExecParams &params,
const float curve_total_length)
{
- const NodeGeometryCurveSample &node_storage = *(NodeGeometryCurveSample *)params.node().storage;
- const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)node_storage.mode;
+ const NodeGeometryCurveSample &storage = node_storage(params.node());
+ const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
/* Just make sure the length is in bounds of the curve. */
@@ -229,34 +239,32 @@ static Field<float> get_length_input_field(const GeoNodeExecParams &params,
return Field<float>(std::move(process_op), 0);
}
-static void geo_node_curve_sample_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
- auto return_default = [&]() {
- params.set_output("Position", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
- params.set_output("Tangent", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
- params.set_output("Normal", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
- };
-
const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>();
if (component == nullptr) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
const CurveEval *curve = component->get_for_read();
if (curve == nullptr) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
if (curve->splines().is_empty()) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
Array<float> spline_lengths = curve->accumulated_spline_lengths();
const float total_length = spline_lengths.last();
if (total_length == 0.0f) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
Field<float> length_field = get_length_input_field(params, total_length);
@@ -271,20 +279,22 @@ static void geo_node_curve_sample_exec(GeoNodeExecParams params)
params.set_output("Normal", Field<float3>(sample_op, 2));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_sample_cc
void register_node_type_geo_curve_sample()
{
+ namespace file_ns = blender::nodes::node_geo_curve_sample_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SAMPLE_CURVE, " Sample Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_sample_exec;
- ntype.declare = blender::nodes::geo_node_curve_sample_declare;
- node_type_init(&ntype, blender::nodes::geo_node_curve_sample_type_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_sample_update);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::node_type_init);
+ node_type_update(&ntype, file_ns::node_update);
node_type_storage(
&ntype, "NodeGeometryCurveSample", node_free_standard_storage, node_copy_standard_storage);
- ntype.draw_buttons = blender::nodes::geo_node_curve_sample_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc
index 8b0a6ca840c..8c0827570c6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handles.cc
@@ -21,24 +21,24 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_set_handles_cc {
-static void geo_node_curve_set_handles_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveSetHandles)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_set_handles_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_curve_set_handles_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSetHandles *data = (NodeGeometryCurveSetHandles *)MEM_callocN(
sizeof(NodeGeometryCurveSetHandles), __func__);
@@ -64,12 +64,11 @@ static BezierSpline::HandleType handle_type_from_input_type(GeometryNodeCurveHan
return BezierSpline::HandleType::Auto;
}
-static void geo_node_curve_set_handles_exec(GeoNodeExecParams params)
+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;
+ const NodeGeometryCurveSetHandles &storage = node_storage(params.node());
+ const GeometryNodeCurveHandleType type = (GeometryNodeCurveHandleType)storage.handle_type;
+ const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)storage.mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -130,21 +129,23 @@ static void geo_node_curve_set_handles_exec(GeoNodeExecParams params)
}
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_set_handles_cc
void register_node_type_geo_curve_set_handles()
{
+ namespace file_ns = blender::nodes::node_geo_curve_set_handles_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_SET_HANDLES, "Set Handle Type", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_set_handles_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_set_handles_exec;
- node_type_init(&ntype, blender::nodes::geo_node_curve_set_handles_init);
+ 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,
"NodeGeometryCurveSetHandles",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.draw_buttons = blender::nodes::geo_node_curve_set_handles_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
index 63518b38090..de352d217ed 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_parameter.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc
@@ -20,9 +20,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_spline_parameter_cc {
-static void geo_node_curve_parameter_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Factor"))
.field_source()
@@ -34,6 +34,9 @@ static void geo_node_curve_parameter_declare(NodeDeclarationBuilder &b)
.description(
N_("For points, the distance along the control point's spline, For splines, the "
"distance along the entire curve"));
+ b.add_output<decl::Int>(N_("Index"))
+ .field_source()
+ .description(N_("Each control point's index on its spline"));
}
/**
@@ -182,29 +185,39 @@ static VArray<float> construct_curve_length_varray(const CurveEval &curve,
return {};
}
-class CurveParameterFieldInput final : public fn::FieldInput {
+static VArray<int> construct_index_on_spline_varray(const CurveEval &curve,
+ const IndexMask UNUSED(mask),
+ const AttributeDomain domain)
+{
+ if (domain == ATTR_DOMAIN_POINT) {
+ Array<int> output(curve.total_control_point_size());
+ int output_index = 0;
+ for (int spline_index : curve.splines().index_range()) {
+ for (int point_index : IndexRange(curve.splines()[spline_index]->size())) {
+ output[output_index++] = point_index;
+ }
+ }
+ return VArray<int>::ForContainer(std::move(output));
+ }
+ return {};
+}
+
+class CurveParameterFieldInput final : public GeometryFieldInput {
public:
- CurveParameterFieldInput() : fn::FieldInput(CPPType::get<float>(), "Curve Parameter node")
+ CurveParameterFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Parameter node")
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask mask,
- ResourceScope &UNUSED(scope)) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask mask) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
-
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
-
- if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- const CurveEval *curve = curve_component.get_for_read();
- if (curve) {
- return construct_curve_parameter_varray(*curve, mask, domain);
- }
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ const CurveEval *curve = curve_component.get_for_read();
+ if (curve) {
+ return construct_curve_parameter_varray(*curve, mask, domain);
}
}
return {};
@@ -222,28 +235,22 @@ class CurveParameterFieldInput final : public fn::FieldInput {
}
};
-class CurveLengthFieldInput final : public fn::FieldInput {
+class CurveLengthFieldInput final : public GeometryFieldInput {
public:
- CurveLengthFieldInput() : fn::FieldInput(CPPType::get<float>(), "Curve Length node")
+ CurveLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Length node")
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask mask,
- ResourceScope &UNUSED(scope)) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask mask) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
-
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
- if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- const CurveEval *curve = curve_component.get_for_read();
- if (curve) {
- return construct_curve_length_varray(*curve, mask, domain);
- }
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ const CurveEval *curve = curve_component.get_for_read();
+ if (curve) {
+ return construct_curve_length_varray(*curve, mask, domain);
}
}
return {};
@@ -261,21 +268,59 @@ class CurveLengthFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_curve_parameter_exec(GeoNodeExecParams params)
+class IndexOnSplineFieldInput final : public GeometryFieldInput {
+ public:
+ IndexOnSplineFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Index")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask mask) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ const CurveEval *curve = curve_component.get_for_read();
+ if (curve) {
+ return construct_index_on_spline_varray(*curve, mask, domain);
+ }
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 4536246522;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const IndexOnSplineFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float> parameter_field{std::make_shared<CurveParameterFieldInput>()};
Field<float> length_field{std::make_shared<CurveLengthFieldInput>()};
+ Field<int> index_on_spline_field{std::make_shared<IndexOnSplineFieldInput>()};
params.set_output("Factor", std::move(parameter_field));
params.set_output("Length", std::move(length_field));
+ params.set_output("Index", std::move(index_on_spline_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_spline_parameter_cc
-void register_node_type_geo_curve_parameter()
+void register_node_type_geo_curve_spline_parameter()
{
+ namespace file_ns = blender::nodes::node_geo_curve_spline_parameter_cc;
+
static bNodeType ntype;
- geo_node_type_base(&ntype, GEO_NODE_CURVE_PARAMETER, "Curve Parameter", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_parameter_exec;
- ntype.declare = blender::nodes::geo_node_curve_parameter_declare;
+ geo_node_type_base(
+ &ntype, GEO_NODE_CURVE_SPLINE_PARAMETER, "Spline Parameter", NODE_CLASS_INPUT, 0);
+ 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/node_geo_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
index ae4453929ac..eef8c1b0db5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
@@ -23,23 +23,23 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_spline_type_cc {
-static void geo_node_curve_spline_type_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryCurveSplineType)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_spline_type_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "spline_type", 0, "", ICON_NONE);
}
-static void geo_node_curve_spline_type_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveSplineType *data = (NodeGeometryCurveSplineType *)MEM_callocN(
sizeof(NodeGeometryCurveSplineType), __func__);
@@ -238,11 +238,10 @@ static SplinePtr convert_to_nurbs(const Spline &input)
return {};
}
-static void geo_node_curve_spline_type_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryCurveSplineType *storage =
- (const NodeGeometryCurveSplineType *)params.node().storage;
- const GeometryNodeSplineType output_type = (const GeometryNodeSplineType)storage->spline_type;
+ const NodeGeometryCurveSplineType &storage = node_storage(params.node());
+ const GeometryNodeSplineType output_type = (const GeometryNodeSplineType)storage.spline_type;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -263,24 +262,28 @@ static void geo_node_curve_spline_type_exec(GeoNodeExecParams params)
const VArray<bool> &selection = selection_evaluator.get_evaluated<bool>(0);
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;
+ new_curve->resize(curve.splines().size());
+
+ threading::parallel_for(curve.splines().index_range(), 512, [&](IndexRange range) {
+ for (const int i : range) {
+ if (selection[i]) {
+ switch (output_type) {
+ case GEO_NODE_SPLINE_TYPE_POLY:
+ new_curve->splines()[i] = convert_to_poly_spline(*curve.splines()[i]);
+ break;
+ case GEO_NODE_SPLINE_TYPE_BEZIER:
+ new_curve->splines()[i] = convert_to_bezier(*curve.splines()[i], params);
+ break;
+ case GEO_NODE_SPLINE_TYPE_NURBS:
+ new_curve->splines()[i] = convert_to_nurbs(*curve.splines()[i]);
+ break;
+ }
+ }
+ else {
+ new_curve->splines()[i] = curve.splines()[i]->copy();
}
}
- else {
- new_curve->add_spline(curve.splines()[i]->copy());
- }
- }
+ });
new_curve->attributes = curve.attributes;
geometry_set.replace_curve(new_curve.release());
});
@@ -288,21 +291,23 @@ static void geo_node_curve_spline_type_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_spline_type_cc
void register_node_type_geo_curve_spline_type()
{
+ namespace file_ns = blender::nodes::node_geo_curve_spline_type_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_CURVE_SPLINE_TYPE, "Set Spline Type", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_spline_type_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_spline_type_exec;
- node_type_init(&ntype, blender::nodes::geo_node_curve_spline_type_init);
+ 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 = blender::nodes::geo_node_curve_spline_type_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
index 7c4c17e69e0..6de188fc1c4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc
@@ -25,9 +25,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_subdivide_cc {
-static void geo_node_curve_subdivide_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Int>(N_("Cuts")).default_value(1).min(0).max(1000).supports_field();
@@ -322,7 +322,7 @@ static std::unique_ptr<CurveEval> subdivide_curve(const CurveEval &input_curve,
return output_curve;
}
-static void geo_node_subdivide_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<int> cuts_field = params.extract_input<Field<int>>("Cuts");
@@ -351,14 +351,16 @@ static void geo_node_subdivide_exec(GeoNodeExecParams params)
params.set_output("Curve", geometry_set);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_subdivide_cc
void register_node_type_geo_curve_subdivide()
{
+ namespace file_ns = blender::nodes::node_geo_curve_subdivide_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SUBDIVIDE_CURVE, "Subdivide Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_subdivide_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_subdivide_exec;
+ 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/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
index 1977b465de4..ff3e85cb6b7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
@@ -23,9 +23,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_curve_to_mesh_cc {
-static void geo_node_curve_to_mesh_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Geometry>(N_("Profile Curve"))
@@ -54,7 +54,7 @@ static void geometry_set_curve_to_mesh(GeometrySet &geometry_set,
}
}
-static void geo_node_curve_to_mesh_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet curve_set = params.extract_input<GeometrySet>("Curve");
GeometrySet profile_set = params.extract_input<GeometrySet>("Profile Curve");
@@ -72,14 +72,16 @@ static void geo_node_curve_to_mesh_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(curve_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_to_mesh_cc
void register_node_type_geo_curve_to_mesh()
{
+ namespace file_ns = blender::nodes::node_geo_curve_to_mesh_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_TO_MESH, "Curve to Mesh", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_to_mesh_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_to_mesh_exec;
+ 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/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
index b9f129a5f75..0e9425246cb 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
@@ -27,24 +27,50 @@
#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 {
+
+NODE_STORAGE_FUNCS(NodeGeometryCurveToPoints)
-static void geo_node_curve_to_points_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
- 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_input<decl::Int>(N_("Count"))
+ .default_value(10)
+ .min(2)
+ .max(100000)
+ .make_available(
+ [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_RESAMPLE_COUNT; });
+ b.add_input<decl::Float>(N_("Length"))
+ .default_value(0.1f)
+ .min(0.001f)
+ .subtype(PROP_DISTANCE)
+ .make_available(
+ [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_RESAMPLE_LENGTH; });
b.add_output<decl::Geometry>(N_("Points"));
b.add_output<decl::Vector>(N_("Tangent")).field_source();
b.add_output<decl::Vector>(N_("Normal")).field_source();
b.add_output<decl::Vector>(N_("Rotation")).field_source();
}
-static void geo_node_curve_to_points_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void geo_node_curve_to_points_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveToPoints *data = (NodeGeometryCurveToPoints *)MEM_callocN(
sizeof(NodeGeometryCurveToPoints), __func__);
@@ -53,10 +79,10 @@ static void geo_node_curve_to_points_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_curve_to_points_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryCurveToPoints &node_storage = *(NodeGeometryCurveToPoints *)node->storage;
- const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
+ const NodeGeometryCurveToPoints &storage = node_storage(*node);
+ const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
bNodeSocket *count_socket = ((bNodeSocket *)node->inputs.first)->next;
bNodeSocket *length_socket = count_socket->next;
@@ -78,9 +104,14 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
return {0};
}
Array<int> offsets(size + 1);
- for (const int i : offsets.index_range()) {
- offsets[i] = count * i;
+ int offset = 0;
+ for (const int i : IndexRange(size)) {
+ offsets[i] = offset;
+ if (splines[i]->evaluated_points_size() > 0) {
+ offset += count;
+ }
}
+ offsets.last() = offset;
return offsets;
}
case GEO_NODE_CURVE_RESAMPLE_LENGTH: {
@@ -90,7 +121,9 @@ static Array<int> calculate_spline_point_offsets(GeoNodeExecParams &params,
int offset = 0;
for (const int i : IndexRange(size)) {
offsets[i] = offset;
- offset += splines[i]->length() / resolution + 1;
+ if (splines[i]->evaluated_points_size() > 0) {
+ offset += splines[i]->length() / resolution + 1;
+ }
}
offsets.last() = offset;
return offsets;
@@ -289,22 +322,10 @@ static void copy_spline_domain_attributes(const CurveEval &curve,
ATTR_DOMAIN_CURVE);
}
-void curve_create_default_rotation_attribute(Span<float3> tangents,
- Span<float3> normals,
- MutableSpan<float3> rotations)
+static void node_geo_exec(GeoNodeExecParams params)
{
- 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 void geo_node_curve_to_points_exec(GeoNodeExecParams params)
-{
- NodeGeometryCurveToPoints &node_storage = *(NodeGeometryCurveToPoints *)params.node().storage;
- const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)node_storage.mode;
+ const NodeGeometryCurveToPoints &storage = node_storage(params.node());
+ const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
AnonymousAttributeIDs attribute_outputs;
@@ -374,20 +395,21 @@ static void geo_node_curve_to_points_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_to_points_cc
void register_node_type_geo_curve_to_points()
{
+ namespace file_ns = blender::nodes::node_geo_curve_to_points_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_CURVE_TO_POINTS, "Curve to Points", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_curve_to_points_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_to_points_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_to_points_layout;
+ 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, blender::nodes::geo_node_curve_to_points_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_to_points_update);
-
+ 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/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
index b281876d314..746392a66cc 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -20,40 +20,52 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
+namespace blender::nodes::node_geo_curve_trim_cc {
+
using blender::attribute_math::mix2;
-namespace blender::nodes {
+NODE_STORAGE_FUNCS(NodeGeometryCurveTrim)
-static void geo_node_curve_trim_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
- b.add_input<decl::Float>(N_("Start")).min(0.0f).max(1.0f).subtype(PROP_FACTOR).supports_field();
+ b.add_input<decl::Float>(N_("Start"))
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR)
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; })
+ .supports_field();
b.add_input<decl::Float>(N_("End"))
.min(0.0f)
.max(1.0f)
.default_value(1.0f)
.subtype(PROP_FACTOR)
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; })
.supports_field();
b.add_input<decl::Float>(N_("Start"), "Start_001")
.min(0.0f)
.subtype(PROP_DISTANCE)
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; })
.supports_field();
b.add_input<decl::Float>(N_("End"), "End_001")
.min(0.0f)
.default_value(1.0f)
.subtype(PROP_DISTANCE)
+ .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; })
.supports_field();
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_curve_trim_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_curve_trim_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryCurveTrim *data = (NodeGeometryCurveTrim *)MEM_callocN(sizeof(NodeGeometryCurveTrim),
__func__);
@@ -62,10 +74,10 @@ static void geo_node_curve_trim_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_curve_trim_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryCurveTrim &node_storage = *(NodeGeometryCurveTrim *)node->storage;
- const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)node_storage.mode;
+ const NodeGeometryCurveTrim &storage = node_storage(*node);
+ const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
bNodeSocket *start_fac = ((bNodeSocket *)node->inputs.first)->next;
bNodeSocket *end_fac = start_fac->next;
@@ -78,6 +90,38 @@ static void geo_node_curve_trim_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, end_len, mode == GEO_NODE_CURVE_SAMPLE_LENGTH);
}
+class SocketSearchOp {
+ public:
+ StringRef socket_name;
+ GeometryNodeCurveSampleMode mode;
+ void operator()(LinkSearchOpParams &params)
+ {
+ bNode &node = params.add_node("GeometryNodeTrimCurve");
+ node_storage(node).mode = mode;
+ params.update_and_connect_available_socket(node, socket_name);
+ }
+};
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+
+ search_link_ops_for_declarations(params, declaration.outputs());
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+
+ if (params.in_out() == SOCK_IN) {
+ if (params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ params.add_item(IFACE_("Start (Factor)"),
+ SocketSearchOp{"Start", GEO_NODE_CURVE_SAMPLE_FACTOR});
+ params.add_item(IFACE_("End (Factor)"), SocketSearchOp{"End", GEO_NODE_CURVE_SAMPLE_FACTOR});
+ params.add_item(IFACE_("Start (Length)"),
+ SocketSearchOp{"Start", GEO_NODE_CURVE_SAMPLE_LENGTH});
+ params.add_item(IFACE_("End (Length)"), SocketSearchOp{"End", GEO_NODE_CURVE_SAMPLE_LENGTH});
+ }
+ }
+}
+
struct TrimLocation {
/* Control point index at the start side of the trim location. */
int left_index;
@@ -532,10 +576,10 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
});
}
-static void geo_node_curve_trim_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryCurveTrim &node_storage = *(NodeGeometryCurveTrim *)params.node().storage;
- const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)node_storage.mode;
+ const NodeGeometryCurveTrim &storage = node_storage(params.node());
+ const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
@@ -557,18 +601,21 @@ static void geo_node_curve_trim_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_curve_trim_cc
void register_node_type_geo_curve_trim()
{
+ namespace file_ns = blender::nodes::node_geo_curve_trim_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_TRIM_CURVE, "Trim Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_curve_trim_exec;
- ntype.draw_buttons = blender::nodes::geo_node_curve_trim_layout;
- ntype.declare = blender::nodes::geo_node_curve_trim_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.declare = file_ns::node_declare;
node_type_storage(
&ntype, "NodeGeometryCurveTrim", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_curve_trim_init);
- node_type_update(&ntype, blender::nodes::geo_node_curve_trim_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
index d07644f8403..1de809b30e4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -29,63 +29,26 @@
#include "node_geometry_util.hh"
-using blender::bke::CustomDataAttributes;
-
-/* Code from the mask modifier in MOD_mask.cc. */
-extern void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- blender::Span<int> vertex_map);
-extern void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- blender::Span<int> vertex_map,
- blender::Span<int> edge_map);
-extern void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
- Mesh &dst_mesh,
- blender::Span<int> vertex_map,
- blender::Span<int> edge_map,
- blender::Span<int> masked_poly_indices,
- blender::Span<int> new_loop_starts);
-
namespace blender::nodes {
-static void geo_node_delete_geometry_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Bool>(N_("Selection"))
- .default_value(true)
- .hide_value()
- .supports_field()
- .description(N_("The parts of the geometry to be deleted"));
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
+using blender::bke::CustomDataAttributes;
-static void geo_node_delete_geometry_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+template<typename T>
+static void copy_data_based_on_mask(Span<T> data, MutableSpan<T> r_data, IndexMask mask)
{
- const bNode *node = static_cast<bNode *>(ptr->data);
- const NodeGeometryDeleteGeometry &storage = *(const NodeGeometryDeleteGeometry *)node->storage;
- const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
-
- uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
- /* Only show the mode when it is relevant. */
- if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE)) {
- uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+ for (const int i_out : mask.index_range()) {
+ r_data[i_out] = data[mask[i_out]];
}
}
-static void geo_node_delete_geometry_init(bNodeTree *UNUSED(tree), bNode *node)
-{
- NodeGeometryDeleteGeometry *data = (NodeGeometryDeleteGeometry *)MEM_callocN(
- sizeof(NodeGeometryDeleteGeometry), __func__);
- data->domain = ATTR_DOMAIN_POINT;
- data->mode = GEO_NODE_DELETE_GEOMETRY_MODE_ALL;
-
- node->storage = data;
-}
-
-template<typename T> static void copy_data(Span<T> data, MutableSpan<T> r_data, IndexMask mask)
+template<typename T>
+static void copy_data_based_on_map(Span<T> src, MutableSpan<T> dst, Span<int> index_map)
{
- for (const int i_out : mask.index_range()) {
- r_data[i_out] = data[mask[i_out]];
+ for (const int i_src : index_map.index_range()) {
+ const int i_dst = index_map[i_src];
+ if (i_dst != -1) {
+ dst[i_dst] = src[i_src];
+ }
}
}
@@ -102,23 +65,6 @@ static IndexMask index_mask_indices(Span<bool> mask, const bool invert, Vector<i
return IndexMask(indices);
}
-/** Utility function for making an IndexMask from an array of integers, where the negative integers
- * are seen as false. The indices vector should live at least as long as the returned IndexMask.
- */
-static IndexMask index_mask_indices(Span<int> mask,
- const int num_indices,
- Vector<int64_t> &indices)
-{
- indices.clear();
- indices.reserve(num_indices);
- for (const int i : mask.index_range()) {
- if (mask[i] >= 0) {
- indices.append_unchecked(i);
- }
- }
- return IndexMask(indices);
-}
-
/**
* Copies the attributes with a domain in `domains` to `result_component`.
*/
@@ -191,12 +137,87 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
using T = decltype(dummy);
VArray_Span<T> span{attribute.varray.typed<T>()};
MutableSpan<T> out_span = result_attribute.as_span<T>();
- copy_data(span, out_span, mask);
+ copy_data_based_on_mask(span, out_span, mask);
});
result_attribute.save();
}
}
+static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind> &attributes,
+ const GeometryComponent &in_component,
+ GeometryComponent &result_component,
+ const AttributeDomain domain,
+ const Span<int> index_map)
+{
+ for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
+ const AttributeIDRef attribute_id = entry.key;
+ ReadAttributeLookup attribute = in_component.attribute_try_get_for_read(attribute_id);
+ if (!attribute) {
+ continue;
+ }
+
+ /* Only copy if it is on a domain we want. */
+ if (domain != attribute.domain) {
+ continue;
+ }
+ const CustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
+
+ OutputAttribute result_attribute = result_component.attribute_try_get_for_output_only(
+ attribute_id, attribute.domain, data_type);
+
+ if (!result_attribute) {
+ continue;
+ }
+
+ attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ VArray_Span<T> span{attribute.varray.typed<T>()};
+ MutableSpan<T> out_span = result_attribute.as_span<T>();
+ copy_data_based_on_map(span, out_span, index_map);
+ });
+ result_attribute.save();
+ }
+}
+
+static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
+ const GeometryComponent &in_component,
+ GeometryComponent &out_component,
+ const int num_selected_loops,
+ const Span<int> selected_poly_indices,
+ const Mesh &mesh_in)
+{
+ Vector<int64_t> indices;
+ indices.reserve(num_selected_loops);
+ for (const int src_poly_index : selected_poly_indices) {
+ const MPoly &src_poly = mesh_in.mpoly[src_poly_index];
+ const int src_loop_start = src_poly.loopstart;
+ const int tot_loop = src_poly.totloop;
+ for (const int i : IndexRange(tot_loop)) {
+ indices.append_unchecked(src_loop_start + i);
+ }
+ }
+ copy_attributes_based_on_mask(
+ attributes, in_component, out_component, ATTR_DOMAIN_CORNER, IndexMask(indices));
+}
+
+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;
+ }
+}
+
static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span<int> edge_map)
{
BLI_assert(src_mesh.totedge == edge_map.size());
@@ -215,6 +236,28 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh,
}
}
+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 (i_dst == -1) {
+ continue;
+ }
+
+ const MEdge &e_src = src_mesh.medge[i_src];
+ MEdge &e_dst = dst_mesh.medge[i_dst];
+
+ e_dst = e_src;
+ e_dst.v1 = vertex_map[e_src.v1];
+ e_dst.v2 = vertex_map[e_src.v2];
+ }
+}
+
/* Faces and edges changed but vertices are the same. */
static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
Mesh &dst_mesh,
@@ -268,29 +311,56 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
}
}
+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];
+
+ 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);
+ copy_data_based_on_mask(spline.positions(), r_spline.positions(), mask);
+ copy_data_based_on_mask(spline.radii(), r_spline.radii(), mask);
+ copy_data_based_on_mask(spline.tilts(), r_spline.tilts(), mask);
switch (spline.type()) {
case Spline::Type::Poly:
break;
case Spline::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);
+ copy_data_based_on_mask(src.handle_positions_left(), dst.handle_positions_left(), mask);
+ copy_data_based_on_mask(src.handle_positions_right(), dst.handle_positions_right(), mask);
+ copy_data_based_on_mask(src.handle_types_left(), dst.handle_types_left(), mask);
+ copy_data_based_on_mask(src.handle_types_right(), dst.handle_types_right(), mask);
break;
}
case Spline::Type::NURBS: {
const NURBSpline &src = static_cast<const NURBSpline &>(spline);
NURBSpline &dst = static_cast<NURBSpline &>(r_spline);
- copy_data(src.weights(), dst.weights(), mask);
+ copy_data_based_on_mask(src.weights(), dst.weights(), mask);
break;
}
}
@@ -316,7 +386,7 @@ static void copy_dynamic_attributes(const CustomDataAttributes &src,
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);
+ copy_data_based_on_mask(src_attribute->typed<T>(), new_attribute->typed<T>(), mask);
});
return true;
},
@@ -986,6 +1056,23 @@ static void do_mesh_separation(GeometrySet &geometry_set,
copy_masked_edges_to_new_mesh(mesh_in, *mesh_out, vertex_map, edge_map);
copy_masked_polys_to_new_mesh(
mesh_in, *mesh_out, vertex_map, edge_map, selected_poly_indices, new_loop_starts);
+
+ /* Copy attributes. */
+ copy_attributes_based_on_map(
+ attributes, in_component, out_component, ATTR_DOMAIN_POINT, vertex_map);
+ copy_attributes_based_on_map(
+ attributes, in_component, out_component, ATTR_DOMAIN_EDGE, edge_map);
+ copy_attributes_based_on_mask(attributes,
+ in_component,
+ out_component,
+ ATTR_DOMAIN_FACE,
+ IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
+ copy_face_corner_attributes(attributes,
+ in_component,
+ out_component,
+ num_selected_loops,
+ selected_poly_indices,
+ mesh_in);
break;
}
case GEO_NODE_DELETE_GEOMETRY_MODE_EDGE_FACE: {
@@ -1041,22 +1128,25 @@ static void do_mesh_separation(GeometrySet &geometry_set,
/* Copy the selected parts of the mesh over to the new mesh. */
memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert));
- copy_attributes(attributes, in_component, out_component, {ATTR_DOMAIN_POINT});
copy_masked_edges_to_new_mesh(mesh_in, *mesh_out, edge_map);
copy_masked_polys_to_new_mesh(
mesh_in, *mesh_out, edge_map, selected_poly_indices, new_loop_starts);
- Vector<int64_t> indices;
+
+ /* Copy attributes. */
+ copy_attributes(attributes, in_component, out_component, {ATTR_DOMAIN_POINT});
+ copy_attributes_based_on_map(
+ attributes, in_component, out_component, ATTR_DOMAIN_EDGE, edge_map);
copy_attributes_based_on_mask(attributes,
in_component,
out_component,
- ATTR_DOMAIN_EDGE,
- index_mask_indices(edge_map, num_selected_edges, indices));
- copy_attributes_based_on_mask(
- attributes,
- in_component,
- out_component,
- ATTR_DOMAIN_FACE,
- index_mask_indices(selected_poly_indices, num_selected_polys, indices));
+ ATTR_DOMAIN_FACE,
+ IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
+ copy_face_corner_attributes(attributes,
+ in_component,
+ out_component,
+ num_selected_loops,
+ selected_poly_indices,
+ mesh_in);
break;
}
case GEO_NODE_DELETE_GEOMETRY_MODE_ONLY_FACE: {
@@ -1100,14 +1190,22 @@ static void do_mesh_separation(GeometrySet &geometry_set,
/* Copy the selected parts of the mesh over to the new mesh. */
memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert));
memcpy(mesh_out->medge, mesh_in.medge, mesh_in.totedge * sizeof(MEdge));
+ copy_masked_polys_to_new_mesh(mesh_in, *mesh_out, selected_poly_indices, new_loop_starts);
+
+ /* Copy attributes. */
copy_attributes(
attributes, in_component, out_component, {ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE});
- copy_masked_polys_to_new_mesh(mesh_in, *mesh_out, selected_poly_indices, new_loop_starts);
- Vector<int64_t> indices;
- const IndexMask mask = index_mask_indices(
- selected_poly_indices, num_selected_polys, indices);
- copy_attributes_based_on_mask(
- attributes, in_component, out_component, ATTR_DOMAIN_FACE, mask);
+ copy_attributes_based_on_mask(attributes,
+ in_component,
+ out_component,
+ ATTR_DOMAIN_FACE,
+ IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
+ copy_face_corner_attributes(attributes,
+ in_component,
+ out_component,
+ num_selected_loops,
+ selected_poly_indices,
+ mesh_in);
break;
}
}
@@ -1177,17 +1275,55 @@ void separate_geometry(GeometrySet &geometry_set,
r_is_error = !some_valid_domain && geometry_set.has_realized_data();
}
-static void geo_node_delete_geometry_exec(GeoNodeExecParams params)
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_delete_geometry_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometryDeleteGeometry)
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Geometry"));
+ b.add_input<decl::Bool>(N_("Selection"))
+ .default_value(true)
+ .hide_value()
+ .supports_field()
+ .description(N_("The parts of the geometry to be deleted"));
+ b.add_output<decl::Geometry>(N_("Geometry"));
+}
+
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ const bNode *node = static_cast<bNode *>(ptr->data);
+ const NodeGeometryDeleteGeometry &storage = node_storage(*node);
+ const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
+
+ uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
+ /* Only show the mode when it is relevant. */
+ if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE)) {
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+ }
+}
+
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+{
+ NodeGeometryDeleteGeometry *data = (NodeGeometryDeleteGeometry *)MEM_callocN(
+ sizeof(NodeGeometryDeleteGeometry), __func__);
+ data->domain = ATTR_DOMAIN_POINT;
+ data->mode = GEO_NODE_DELETE_GEOMETRY_MODE_ALL;
+
+ node->storage = data;
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
- const bNode &node = params.node();
- const NodeGeometryDeleteGeometry &storage = *(const NodeGeometryDeleteGeometry *)node.storage;
+ const NodeGeometryDeleteGeometry &storage = node_storage(params.node());
const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
- const GeometryNodeDeleteGeometryMode mode = static_cast<GeometryNodeDeleteGeometryMode>(
- storage.mode);
+ const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode;
bool all_is_error = false;
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
@@ -1204,10 +1340,12 @@ static void geo_node_delete_geometry_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_delete_geometry_cc
void register_node_type_geo_delete_geometry()
{
+ namespace file_ns = blender::nodes::node_geo_delete_geometry_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_DELETE_GEOMETRY, "Delete Geometry", NODE_CLASS_GEOMETRY, 0);
@@ -1217,10 +1355,10 @@ void register_node_type_geo_delete_geometry()
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_delete_geometry_init);
+ node_type_init(&ntype, file_ns::node_init);
- ntype.declare = blender::nodes::geo_node_delete_geometry_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_delete_geometry_exec;
- ntype.draw_buttons = blender::nodes::geo_node_delete_geometry_layout;
+ 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/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
index b2c76b76590..3537b62c76e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
@@ -36,11 +36,9 @@
#include "node_geometry_util.hh"
-using blender::bke::GeometryInstanceGroup;
+namespace blender::nodes::node_geo_distribute_points_on_faces_cc {
-namespace blender::nodes {
-
-static void geo_node_point_distribute_points_on_faces_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -60,9 +58,7 @@ static void geo_node_point_distribute_points_on_faces_declare(NodeDeclarationBui
b.add_output<decl::Vector>(N_("Rotation")).subtype(PROP_EULER).field_source();
}
-static void geo_node_point_distribute_points_on_faces_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE);
}
@@ -403,16 +399,12 @@ static Array<float> calc_full_density_factors_with_selection(const MeshComponent
GeometryComponentFieldContext field_context{component, attribute_domain};
const int domain_size = component.attribute_domain_size(attribute_domain);
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection_mask = selection_evaluator.get_evaluated_as_mask(0);
-
Array<float> densities(domain_size, 0.0f);
- fn::FieldEvaluator density_evaluator{field_context, &selection_mask};
- density_evaluator.add_with_destination(density_field, densities.as_mutable_span());
- density_evaluator.evaluate();
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(density_field, densities.as_mutable_span());
+ evaluator.evaluate();
return densities;
}
@@ -528,7 +520,7 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
mesh_component, point_component, bary_coords, looptri_indices, attribute_outputs);
}
-static void geo_node_point_distribute_points_on_faces_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
@@ -570,10 +562,12 @@ static void geo_node_point_distribute_points_on_faces_exec(GeoNodeExecParams par
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_distribute_points_on_faces_cc
void register_node_type_geo_distribute_points_on_faces()
{
+ namespace file_ns = blender::nodes::node_geo_distribute_points_on_faces_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype,
@@ -581,10 +575,10 @@ void register_node_type_geo_distribute_points_on_faces()
"Distribute Points on Faces",
NODE_CLASS_GEOMETRY,
0);
- node_type_update(&ntype, blender::nodes::node_point_distribute_points_on_faces_update);
+ node_type_update(&ntype, file_ns::node_point_distribute_points_on_faces_update);
node_type_size(&ntype, 170, 100, 320);
- ntype.declare = blender::nodes::geo_node_point_distribute_points_on_faces_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_point_distribute_points_on_faces_exec;
- ntype.draw_buttons = blender::nodes::geo_node_point_distribute_points_on_faces_layout;
+ 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/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
new file mode 100644
index 00000000000..a3bbeca7af3
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
@@ -0,0 +1,847 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_task.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_dual_mesh_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Mesh").supported_type(GEO_COMPONENT_TYPE_MESH);
+ b.add_input<decl::Bool>("Keep Boundaries")
+ .default_value(false)
+ .description(
+ "Keep non-manifold boundaries of the input mesh in place by avoiding the dual "
+ "transformation there");
+ b.add_output<decl::Geometry>("Dual Mesh");
+}
+
+enum class EdgeType : int8_t {
+ Loose = 0, /* No polygons connected to it. */
+ Boundary = 1, /* An edge connected to exactly one polygon. */
+ Normal = 2, /* A normal edge (connected to two polygons). */
+ NonManifold = 3, /* An edge connected to more than two polygons. */
+};
+
+static EdgeType get_edge_type_with_added_neighbor(EdgeType old_type)
+{
+ switch (old_type) {
+ case EdgeType::Loose:
+ return EdgeType::Boundary;
+ case EdgeType::Boundary:
+ return EdgeType::Normal;
+ case EdgeType::Normal:
+ case EdgeType::NonManifold:
+ return EdgeType::NonManifold;
+ }
+ BLI_assert_unreachable();
+ return EdgeType::Loose;
+}
+
+enum class VertexType : int8_t {
+ Loose = 0, /* Either no edges connected or only loose edges connected. */
+ Normal = 1, /* A normal vertex. */
+ Boundary = 2, /* A vertex on a boundary edge. */
+ NonManifold = 3, /* A vertex on a non-manifold edge. */
+};
+
+static VertexType get_vertex_type_with_added_neighbor(VertexType old_type)
+{
+ switch (old_type) {
+ case VertexType::Loose:
+ return VertexType::Normal;
+ case VertexType::Normal:
+ return VertexType::Boundary;
+ case VertexType::Boundary:
+ case VertexType::NonManifold:
+ return VertexType::NonManifold;
+ }
+ BLI_assert_unreachable();
+ return VertexType::Loose;
+}
+
+/* Copy only where vertex_types is 'normal'. If keep boundaries is selected, also copy from
+ * boundary vertices. */
+template<typename T>
+static void copy_data_based_on_vertex_types(Span<T> data,
+ MutableSpan<T> r_data,
+ const Span<VertexType> vertex_types,
+ const bool keep_boundaries)
+{
+ if (keep_boundaries) {
+ int out_i = 0;
+ for (const int i : data.index_range()) {
+ if (ELEM(vertex_types[i], VertexType::Normal, VertexType::Boundary)) {
+ r_data[out_i] = data[i];
+ out_i++;
+ }
+ }
+ }
+ else {
+ int out_i = 0;
+ for (const int i : data.index_range()) {
+ if (vertex_types[i] == VertexType::Normal) {
+ r_data[out_i] = data[i];
+ out_i++;
+ }
+ }
+ }
+}
+
+template<typename T>
+static void copy_data_based_on_pairs(Span<T> data,
+ MutableSpan<T> r_data,
+ const Span<std::pair<int, int>> new_to_old_map)
+{
+ for (const std::pair<int, int> &pair : new_to_old_map) {
+ r_data[pair.first] = data[pair.second];
+ }
+}
+
+/* Copy using the map. */
+template<typename T>
+static void copy_data_based_on_new_to_old_map(Span<T> data,
+ MutableSpan<T> r_data,
+ const Span<int> new_to_old_map)
+{
+ for (const int i : r_data.index_range()) {
+ const int old_i = new_to_old_map[i];
+ r_data[i] = data[old_i];
+ }
+}
+
+/**
+ * Transfers the attributes from the original mesh to the new mesh using the following logic:
+ * - If the attribute was on the face domain it is now on the point domain, and this is true
+ * for all faces, so we can just copy these.
+ * - If the attribute was on the vertex domain there are three cases:
+ * - It was a 'bad' vertex so it is not in the dual mesh, and we can just ignore it
+ * - It was a normal vertex so it has a corresponding face in the dual mesh to which we can
+ * transfer.
+ * - It was a boundary vertex so it has a corresponding face, if keep_boundaries is true.
+ * Otherwise we can just ignore it.
+ * - If the attribute was on the edge domain we lookup for the new edges which edge it originated
+ * from using `new_to_old_edges_map`. We have to do it in this reverse order, because there can
+ * be more edges in the new mesh if keep boundaries is on.
+ * - We do the same thing for face corners as we do for edges.
+ *
+ * Some of the vertices (on the boundary) in the dual mesh don't come from faces, but from edges or
+ * vertices. For these the `boundary_vertex_to_relevant_face_map` is used, which maps them to the
+ * closest face.
+ */
+static void transfer_attributes(
+ const Map<AttributeIDRef, AttributeKind> &attributes,
+ const Span<VertexType> vertex_types,
+ const bool keep_boundaries,
+ const Span<int> new_to_old_edges_map,
+ const Span<int> new_to_old_face_corners_map,
+ const Span<std::pair<int, int>> boundary_vertex_to_relevant_face_map,
+ const GeometryComponent &src_component,
+ GeometryComponent &dst_component)
+{
+ for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
+ const AttributeIDRef attribute_id = entry.key;
+ ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
+ if (!src_attribute) {
+ continue;
+ }
+
+ AttributeDomain out_domain;
+ if (src_attribute.domain == ATTR_DOMAIN_FACE) {
+ out_domain = ATTR_DOMAIN_POINT;
+ }
+ else if (src_attribute.domain == ATTR_DOMAIN_POINT) {
+ out_domain = ATTR_DOMAIN_FACE;
+ }
+ else {
+ /* Edges and Face Corners. */
+ out_domain = src_attribute.domain;
+ }
+ const CustomDataType data_type = bke::cpp_type_to_custom_data_type(
+ src_attribute.varray.type());
+ OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
+ attribute_id, out_domain, data_type);
+
+ if (!dst_attribute) {
+ continue;
+ }
+
+ attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ VArray_Span<T> span{src_attribute.varray.typed<T>()};
+ MutableSpan<T> dst_span = dst_attribute.as_span<T>();
+ if (src_attribute.domain == ATTR_DOMAIN_FACE) {
+ dst_span.take_front(span.size()).copy_from(span);
+ if (keep_boundaries) {
+ copy_data_based_on_pairs(span, dst_span, boundary_vertex_to_relevant_face_map);
+ }
+ }
+ else if (src_attribute.domain == ATTR_DOMAIN_POINT) {
+ copy_data_based_on_vertex_types(span, dst_span, vertex_types, keep_boundaries);
+ }
+ else if (src_attribute.domain == ATTR_DOMAIN_EDGE) {
+ copy_data_based_on_new_to_old_map(span, dst_span, new_to_old_edges_map);
+ }
+ else {
+ copy_data_based_on_new_to_old_map(span, dst_span, new_to_old_face_corners_map);
+ }
+ });
+ dst_attribute.save();
+ }
+}
+
+/**
+ * Calculates the boundaries of the mesh. Boundary polygons are not computed since we don't need
+ * them later on. We use the following definitions:
+ * - An edge is on a boundary if it is connected to only one polygon.
+ * - A vertex is on a boundary if it is on an edge on a boundary.
+ */
+static void calc_boundaries(const Mesh &mesh,
+ MutableSpan<VertexType> r_vertex_types,
+ MutableSpan<EdgeType> r_edge_types)
+{
+ BLI_assert(r_vertex_types.size() == mesh.totvert);
+ BLI_assert(r_edge_types.size() == mesh.totedge);
+ r_vertex_types.fill(VertexType::Loose);
+ r_edge_types.fill(EdgeType::Loose);
+
+ /* Add up the number of polys connected to each edge. */
+ for (const int i : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[i];
+ for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) {
+ r_edge_types[loop.e] = get_edge_type_with_added_neighbor(r_edge_types[loop.e]);
+ }
+ }
+
+ /* Update vertices. */
+ for (const int i : IndexRange(mesh.totedge)) {
+ const EdgeType edge_type = r_edge_types[i];
+ if (edge_type == EdgeType::Loose) {
+ continue;
+ }
+ const MEdge &edge = mesh.medge[i];
+ if (edge_type == EdgeType::Boundary) {
+ r_vertex_types[edge.v1] = get_vertex_type_with_added_neighbor(r_vertex_types[edge.v1]);
+ r_vertex_types[edge.v2] = get_vertex_type_with_added_neighbor(r_vertex_types[edge.v2]);
+ }
+ else if (edge_type >= EdgeType::NonManifold) {
+ r_vertex_types[edge.v1] = VertexType::NonManifold;
+ r_vertex_types[edge.v2] = VertexType::NonManifold;
+ }
+ }
+
+ /* Normal verts are on a normal edge, and not on boundary edges or non-manifold edges. */
+ for (const int i : IndexRange(mesh.totedge)) {
+ const EdgeType edge_type = r_edge_types[i];
+ if (edge_type == EdgeType::Normal) {
+ const MEdge &edge = mesh.medge[i];
+ if (r_vertex_types[edge.v1] == VertexType::Loose) {
+ r_vertex_types[edge.v1] = VertexType::Normal;
+ }
+ if (r_vertex_types[edge.v2] == VertexType::Loose) {
+ r_vertex_types[edge.v2] = VertexType::Normal;
+ }
+ }
+ }
+}
+
+/**
+ * Stores the indices of the polygons connected to each vertex.
+ */
+static void create_vertex_poly_map(const Mesh &mesh,
+ MutableSpan<Vector<int>> r_vertex_poly_indices)
+{
+ for (const int i : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[i];
+ for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) {
+ r_vertex_poly_indices[loop.v].append(i);
+ }
+ }
+}
+
+/**
+ * Sorts the polygons connected to the given vertex based on polygon adjacency. The ordering is
+ * so such that the normals point in the same way as the original mesh. If the vertex is a
+ * boundary vertex, the first and last polygon have a boundary edge connected to the vertex. The
+ * `r_shared_edges` array at index i is set to the index of the shared edge between the i-th and
+ * `(i+1)-th` sorted polygon. Similarly the `r_sorted_corners` array at index i is set to the
+ * corner in the i-th sorted polygon.
+ *
+ * How the faces are sorted (see diagrams below):
+ * (For this explanation we'll assume all faces are oriented clockwise)
+ * (The vertex whose connected polygons we need to sort is "v0")
+ *
+ * \code{.unparsed}
+ * Normal case: Boundary Vertex case:
+ * v1 ----- v2 ----- v3 | | |
+ * | f3 | f0 | v2 ---- v4 --------- v3---
+ * | | | | / ,-' |
+ * v8 ----- v0 ----- v4 | f0 / f1 ,-' |
+ * | f2 | f1 | | / ,-' |
+ * | | | | / ,-' |
+ * v7 ----- v6 ----- v5 | / ,-' f2 |
+ * | /,-' |
+ * v0 ------------------ v1---
+ * \endcode
+ *
+ * - First we get the two corners of each face that have an edge which contains v0. A corner is
+ * simply a vertex followed by an edge. In this case for the face "f0" for example, we'd end up
+ * with the corners (v: v4, e: v4<->v0) and (v: v0, e: v0<->v2). Note that if the face was
+ * oriented counter-clockwise we'd end up with the corners (v: v0, e: v0<->v4) and (v: v2, e:
+ * v0<->v2) instead.
+ * - Then we need to choose one polygon as our first. If "v0" is not on a boundary we can just
+ * choose any polygon. If it is on a boundary some more care needs to be taken. Here we need to
+ * pick a polygon which lies on the boundary (in the diagram either f0 or f2). To choose between
+ * the two we need the next step.
+ * - In the normal case we use this polygon to set `shared_edge_i` which indicates the index of the
+ * shared edge between this polygon and the next one. There are two possible choices: v0<->v4 and
+ * v2<->v0. To choose we look at the corners. Since the edge v0<->v2 lies on the corner which has
+ * v0, we set `shared_edge_i` to the other edge (v0<->v4), such that the next face will be "f1"
+ * which is the next face in clockwise order.
+ * - In the boundary vertex case, we do something similar, but we are also forced to choose the
+ * edge which is not on the boundary. If this doesn't line up with orientation of the polygon, we
+ * know we'll need to choose the other boundary polygon as our first polygon. If the orientations
+ * don't line up there as well, it means that the mesh normals are not consistent, and we just
+ * have to force an orientation for ourselves. (Imagine if f0 is oriented counter-clockwise and
+ * f2 is oriented clockwise for example)
+ * - Next comes a loop where we look at the other faces and find the one which has the shared
+ * edge. Then we set the next shared edge to the other edge on the polygon connected to "v0", and
+ * continue. Because of the way we've chosen the first shared edge the order of the faces will
+ * have the same orientation as that of the first polygon.
+ * (In this case we'd have f0 -> f1 -> f2 -> f3 which also goes around clockwise).
+ * - Every time we determine a shared edge, we can also add a corner to `r_sorted_corners`. This
+ * will simply be the corner which doesn't contain the shared edge.
+ * - Finally if we are in the normal case we also need to add the last "shared edge" to close the
+ * loop.
+ */
+static void sort_vertex_polys(const Mesh &mesh,
+ const int vertex_index,
+ const bool boundary_vertex,
+ const Span<EdgeType> edge_types,
+ MutableSpan<int> connected_polygons,
+ MutableSpan<int> r_shared_edges,
+ MutableSpan<int> r_sorted_corners)
+{
+ if (connected_polygons.size() <= 2 && (!boundary_vertex || connected_polygons.size() == 0)) {
+ return;
+ }
+
+ /* For each polygon store the two corners whose edge contains the vertex. */
+ Array<std::pair<int, int>> poly_vertex_corners(connected_polygons.size());
+ for (const int i : connected_polygons.index_range()) {
+ const MPoly &poly = mesh.mpoly[connected_polygons[i]];
+ bool first_edge_done = false;
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ if (mesh.medge[loop.e].v1 == vertex_index || mesh.medge[loop.e].v2 == vertex_index) {
+ if (!first_edge_done) {
+ poly_vertex_corners[i].first = loop_index;
+ first_edge_done = true;
+ }
+ else {
+ poly_vertex_corners[i].second = loop_index;
+ break;
+ }
+ }
+ }
+ }
+
+ int shared_edge_i = -1;
+ /* Determine first polygon and orientation. For now the orientation of the whole loop depends
+ * on the one polygon we chose as first. It's probably not worth it to check every polygon in
+ * the loop to determine the 'average' orientation. */
+ if (boundary_vertex) {
+ /* Our first polygon needs to be one which has a boundary edge. */
+ for (const int i : connected_polygons.index_range()) {
+ const MLoop &first_loop = mesh.mloop[poly_vertex_corners[i].first];
+ const MLoop &second_loop = mesh.mloop[poly_vertex_corners[i].second];
+ if (edge_types[first_loop.e] == EdgeType::Boundary && first_loop.v == vertex_index) {
+ shared_edge_i = second_loop.e;
+ r_sorted_corners[0] = poly_vertex_corners[i].first;
+ std::swap(connected_polygons[i], connected_polygons[0]);
+ std::swap(poly_vertex_corners[i], poly_vertex_corners[0]);
+ break;
+ }
+ if (edge_types[second_loop.e] == EdgeType::Boundary && second_loop.v == vertex_index) {
+ shared_edge_i = first_loop.e;
+ r_sorted_corners[0] = poly_vertex_corners[i].second;
+ std::swap(connected_polygons[i], connected_polygons[0]);
+ std::swap(poly_vertex_corners[i], poly_vertex_corners[0]);
+ break;
+ }
+ }
+ if (shared_edge_i == -1) {
+ /* The rotation is inconsistent between the two polygons on the boundary. Just choose one
+ * of the polygon's orientation. */
+ for (const int i : connected_polygons.index_range()) {
+ const MLoop &first_loop = mesh.mloop[poly_vertex_corners[i].first];
+ const MLoop &second_loop = mesh.mloop[poly_vertex_corners[i].second];
+ if (edge_types[first_loop.e] == EdgeType::Boundary) {
+ shared_edge_i = second_loop.e;
+ r_sorted_corners[0] = poly_vertex_corners[i].first;
+ std::swap(connected_polygons[i], connected_polygons[0]);
+ std::swap(poly_vertex_corners[i], poly_vertex_corners[0]);
+ break;
+ }
+ if (edge_types[second_loop.e] == EdgeType::Boundary) {
+ shared_edge_i = first_loop.e;
+ r_sorted_corners[0] = poly_vertex_corners[i].second;
+ std::swap(connected_polygons[i], connected_polygons[0]);
+ std::swap(poly_vertex_corners[i], poly_vertex_corners[0]);
+ break;
+ }
+ }
+ }
+ }
+ else {
+ /* Any polygon can be the first. Just need to check the orientation.*/
+ const MLoop &first_loop = mesh.mloop[poly_vertex_corners[0].first];
+ const MLoop &second_loop = mesh.mloop[poly_vertex_corners[0].second];
+ if (first_loop.v == vertex_index) {
+ shared_edge_i = second_loop.e;
+ r_sorted_corners[0] = poly_vertex_corners[0].first;
+ }
+ else {
+ r_sorted_corners[0] = poly_vertex_corners[0].second;
+ shared_edge_i = first_loop.e;
+ }
+ }
+ BLI_assert(shared_edge_i != -1);
+
+ for (const int i : IndexRange(connected_polygons.size() - 1)) {
+ r_shared_edges[i] = shared_edge_i;
+
+ /* Look at the other polys to see if it has this shared edge. */
+ int j = i + 1;
+ for (; j < connected_polygons.size(); ++j) {
+ const MLoop &first_loop = mesh.mloop[poly_vertex_corners[j].first];
+ const MLoop &second_loop = mesh.mloop[poly_vertex_corners[j].second];
+ if (first_loop.e == shared_edge_i) {
+ r_sorted_corners[i + 1] = poly_vertex_corners[j].first;
+ shared_edge_i = second_loop.e;
+ break;
+ }
+ if (second_loop.e == shared_edge_i) {
+ r_sorted_corners[i + 1] = poly_vertex_corners[j].second;
+ shared_edge_i = first_loop.e;
+ break;
+ }
+ }
+
+ BLI_assert(j != connected_polygons.size());
+
+ std::swap(connected_polygons[i + 1], connected_polygons[j]);
+ std::swap(poly_vertex_corners[i + 1], poly_vertex_corners[j]);
+ }
+
+ if (!boundary_vertex) {
+ /* Shared edge between first and last polygon. */
+ r_shared_edges.last() = shared_edge_i;
+ }
+}
+
+/**
+ * Get the edge on the poly that contains the given vertex and is a boundary edge.
+ */
+static void boundary_edge_on_poly(const MPoly &poly,
+ const Mesh &mesh,
+ const int vertex_index,
+ const Span<EdgeType> edge_types,
+ int &r_edge)
+{
+ for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) {
+ if (edge_types[loop.e] == EdgeType::Boundary) {
+ const MEdge &edge = mesh.medge[loop.e];
+ if (edge.v1 == vertex_index || edge.v2 == vertex_index) {
+ r_edge = loop.e;
+ return;
+ }
+ }
+ }
+}
+
+/**
+ * Get the two edges on the poly that contain the given vertex and are boundary edges. The
+ * orientation of the poly is taken into account.
+ */
+static void boundary_edges_on_poly(const MPoly &poly,
+ const Mesh &mesh,
+ const int vertex_index,
+ const Span<EdgeType> edge_types,
+ int &r_edge1,
+ int &r_edge2)
+{
+ bool edge1_done = false;
+ /* This is set to true if the order in which we encounter the two edges is inconsistent with the
+ * orientation of the polygon. */
+ bool needs_swap = false;
+ for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) {
+ if (edge_types[loop.e] == EdgeType::Boundary) {
+ const MEdge &edge = mesh.medge[loop.e];
+ if (edge.v1 == vertex_index || edge.v2 == vertex_index) {
+ if (edge1_done) {
+ if (needs_swap) {
+ r_edge2 = r_edge1;
+ r_edge1 = loop.e;
+ }
+ else {
+ r_edge2 = loop.e;
+ }
+ return;
+ }
+ r_edge1 = loop.e;
+ edge1_done = true;
+ if (loop.v == vertex_index) {
+ needs_swap = true;
+ }
+ }
+ }
+ }
+}
+
+static void add_edge(const Mesh &mesh,
+ const int old_edge_i,
+ const int v1,
+ const int v2,
+ Vector<int> &new_to_old_edges_map,
+ Vector<MEdge> &new_edges,
+ Vector<int> &loop_edges)
+{
+ MEdge new_edge = MEdge(mesh.medge[old_edge_i]);
+ new_edge.v1 = v1;
+ new_edge.v2 = v2;
+ const int new_edge_i = new_edges.size();
+ new_to_old_edges_map.append(old_edge_i);
+ new_edges.append(new_edge);
+ loop_edges.append(new_edge_i);
+}
+
+/**
+ * Calculate the barycentric dual of a mesh. The dual is only "dual" in terms of connectivity,
+ * i.e. applying the function twice will give the same vertices, edges, and faces, but not the
+ * same positions. When the option "Keep Boundaries" is selected the connectivity is no
+ * longer dual.
+ *
+ * For the dual mesh of a manifold input mesh:
+ * - The vertices are at the centers of the faces of the input mesh.
+ * - The edges connect the two vertices created from the two faces next to the edge in the input
+ * mesh.
+ * - The faces are at the vertices of the input mesh.
+ *
+ * Some special cases are needed for boundaries and non-manifold geometry.
+ */
+static void calc_dual_mesh(GeometrySet &geometry_set,
+ const MeshComponent &in_component,
+ const bool keep_boundaries)
+{
+ const Mesh &mesh_in = *in_component.get_for_read();
+
+ Map<AttributeIDRef, AttributeKind> attributes;
+ geometry_set.gather_attributes_for_propagation(
+ {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_MESH, false, attributes);
+
+ Array<VertexType> vertex_types(mesh_in.totvert);
+ Array<EdgeType> edge_types(mesh_in.totedge);
+ calc_boundaries(mesh_in, vertex_types, edge_types);
+ Array<Vector<int>> vertex_poly_indices(mesh_in.totvert);
+ Array<Array<int>> vertex_shared_edges(mesh_in.totvert);
+ Array<Array<int>> vertex_corners(mesh_in.totvert);
+ create_vertex_poly_map(mesh_in, vertex_poly_indices);
+ threading::parallel_for(vertex_poly_indices.index_range(), 512, [&](IndexRange range) {
+ for (const int i : range) {
+ if (vertex_types[i] == VertexType::Loose || vertex_types[i] >= VertexType::NonManifold ||
+ (!keep_boundaries && vertex_types[i] == VertexType::Boundary)) {
+ /* Bad vertex that we can't work with. */
+ continue;
+ }
+ MutableSpan<int> loop_indices = vertex_poly_indices[i];
+ Array<int> sorted_corners(loop_indices.size());
+ if (vertex_types[i] == VertexType::Normal) {
+ Array<int> shared_edges(loop_indices.size());
+ sort_vertex_polys(
+ mesh_in, i, false, edge_types, loop_indices, shared_edges, sorted_corners);
+ vertex_shared_edges[i] = shared_edges;
+ }
+ else {
+ Array<int> shared_edges(loop_indices.size() - 1);
+ sort_vertex_polys(
+ mesh_in, i, true, edge_types, loop_indices, shared_edges, sorted_corners);
+ vertex_shared_edges[i] = shared_edges;
+ }
+ vertex_corners[i] = sorted_corners;
+ }
+ });
+
+ Vector<float3> vertex_positions(mesh_in.totpoly);
+ for (const int i : IndexRange(mesh_in.totpoly)) {
+ const MPoly poly = mesh_in.mpoly[i];
+ BKE_mesh_calc_poly_center(
+ &poly, &mesh_in.mloop[poly.loopstart], mesh_in.mvert, vertex_positions[i]);
+ }
+
+ Array<int> boundary_edge_midpoint_index;
+ if (keep_boundaries) {
+ /* Only initialize when we actually need it. */
+ boundary_edge_midpoint_index.reinitialize(mesh_in.totedge);
+ /* We need to add vertices at the centers of boundary edges. */
+ for (const int i : IndexRange(mesh_in.totedge)) {
+ if (edge_types[i] == EdgeType::Boundary) {
+ float3 mid;
+ const MEdge &edge = mesh_in.medge[i];
+ mid_v3_v3v3(mid, mesh_in.mvert[edge.v1].co, mesh_in.mvert[edge.v2].co);
+ boundary_edge_midpoint_index[i] = vertex_positions.size();
+ vertex_positions.append(mid);
+ }
+ }
+ }
+
+ Vector<int> loop_lengths;
+ Vector<int> loops;
+ Vector<int> loop_edges;
+ Vector<MEdge> new_edges;
+ /* These are used to transfer attributes. */
+ Vector<int> new_to_old_face_corners_map;
+ Vector<int> new_to_old_edges_map;
+ /* Stores the index of the vertex in the dual and the face it should get the attribute from. */
+ Vector<std::pair<int, int>> boundary_vertex_to_relevant_face_map;
+ /* Since each edge in the dual (except the ones created with keep boundaries) comes from
+ * exactly one edge in the original, we can use this array to keep track of whether it still
+ * needs to be created or not. If it's not -1 it gives the index in `new_edges` of the dual
+ * edge. The edges coming from preserving the boundaries only get added once anyway, so we
+ * don't need a hashmap for that. */
+ Array<int> old_to_new_edges_map(mesh_in.totedge);
+ old_to_new_edges_map.fill(-1);
+ for (const int i : IndexRange(mesh_in.totvert)) {
+ if (vertex_types[i] == VertexType::Loose || vertex_types[i] >= VertexType::NonManifold ||
+ (!keep_boundaries && vertex_types[i] == VertexType::Boundary)) {
+ /* Bad vertex that we can't work with. */
+ continue;
+ }
+
+ Vector<int> loop_indices = vertex_poly_indices[i];
+ Span<int> shared_edges = vertex_shared_edges[i];
+ Span<int> sorted_corners = vertex_corners[i];
+ if (vertex_types[i] == VertexType::Normal) {
+ if (loop_indices.size() <= 2) {
+ /* We can't make a polygon from 2 vertices. */
+ continue;
+ }
+
+ /* Add edges in the loop. */
+ for (const int i : shared_edges.index_range()) {
+ const int old_edge_i = shared_edges[i];
+ if (old_to_new_edges_map[old_edge_i] == -1) {
+ /* This edge has not been created yet. */
+ MEdge new_edge = MEdge(mesh_in.medge[old_edge_i]);
+ new_edge.v1 = loop_indices[i];
+ new_edge.v2 = loop_indices[(i + 1) % loop_indices.size()];
+ new_to_old_edges_map.append(old_edge_i);
+ old_to_new_edges_map[old_edge_i] = new_edges.size();
+ new_edges.append(new_edge);
+ }
+ loop_edges.append(old_to_new_edges_map[old_edge_i]);
+ }
+
+ new_to_old_face_corners_map.extend(sorted_corners);
+ }
+ else {
+ /**
+ * The code handles boundary vertices like the vertex marked "V" in the diagram below.
+ * The first thing that happens is ordering the faces f1,f2 and f3 (stored in
+ * loop_indices), together with their shared edges e3 and e4 (which get stored in
+ * shared_edges). The ordering could end up being clockwise or counterclockwise, for this
+ * we'll assume that the ordering f1->f2->f3 is chosen. After that we add the edges in
+ * between the polygons, in this case the edges f1--f2, and f2--f3. Now we need to merge
+ * these with the boundary edges e1 and e2. To do this we create an edge from f3 to the
+ * midpoint of e2 (computed in a previous step), from this midpoint to V, from V to the
+ * midpoint of e1 and from the midpoint of e1 to f1.
+ *
+ * \code{.unparsed}
+ * | | | | | |
+ * v2 ---- v3 --------- v4--- v2 ---- v3 -------- v4---
+ * | f3 / ,-' | | / ,-'|
+ * | / f2 ,-' | | / ,-' |
+ * e2 | /e3 ,-' e4 | ====> M1-f3-/--f2-.,-' |
+ * | / ,-' | ====> | / ,-'\ |
+ * | / ,-' f1 | | / ,-' f1 |
+ * | /,-' | | /,-' | |
+ * V-------------------- v5--- V------------M2----- v5---
+ * \endcode
+ */
+
+ /* Add the edges in between the polys. */
+ for (const int i : shared_edges.index_range()) {
+ const int old_edge_i = shared_edges[i];
+ if (old_to_new_edges_map[old_edge_i] == -1) {
+ /* This edge has not been created yet. */
+ MEdge new_edge = MEdge(mesh_in.medge[old_edge_i]);
+ new_edge.v1 = loop_indices[i];
+ new_edge.v2 = loop_indices[i + 1];
+ new_to_old_edges_map.append(old_edge_i);
+ old_to_new_edges_map[old_edge_i] = new_edges.size();
+ new_edges.append(new_edge);
+ }
+ loop_edges.append(old_to_new_edges_map[old_edge_i]);
+ }
+
+ new_to_old_face_corners_map.extend(sorted_corners);
+
+ /* Add the vertex and the midpoints of the two boundary edges to the loop. */
+
+ /* Get the boundary edges. */
+ int edge1;
+ int edge2;
+ if (loop_indices.size() >= 2) {
+ /* The first boundary edge is at the end of the chain of polygons. */
+ boundary_edge_on_poly(mesh_in.mpoly[loop_indices.last()], mesh_in, i, edge_types, edge1);
+ boundary_edge_on_poly(mesh_in.mpoly[loop_indices.first()], mesh_in, i, edge_types, edge2);
+ }
+ else {
+ /* If there is only one polygon both edges are in that polygon. */
+ boundary_edges_on_poly(
+ mesh_in.mpoly[loop_indices[0]], mesh_in, i, edge_types, edge1, edge2);
+ }
+
+ const int last_face_center = loop_indices.last();
+ loop_indices.append(boundary_edge_midpoint_index[edge1]);
+ new_to_old_face_corners_map.append(sorted_corners.last());
+ const int first_midpoint = loop_indices.last();
+ if (old_to_new_edges_map[edge1] == -1) {
+ add_edge(mesh_in,
+ edge1,
+ last_face_center,
+ first_midpoint,
+ new_to_old_edges_map,
+ new_edges,
+ loop_edges);
+ old_to_new_edges_map[edge1] = new_edges.size() - 1;
+ boundary_vertex_to_relevant_face_map.append(std::pair(first_midpoint, last_face_center));
+ }
+ else {
+ loop_edges.append(old_to_new_edges_map[edge1]);
+ }
+ loop_indices.append(vertex_positions.size());
+ /* This is sort of arbitrary, but interpolating would be a lot harder to do. */
+ new_to_old_face_corners_map.append(sorted_corners.first());
+ boundary_vertex_to_relevant_face_map.append(
+ std::pair(loop_indices.last(), last_face_center));
+ vertex_positions.append(mesh_in.mvert[i].co);
+ const int boundary_vertex = loop_indices.last();
+ add_edge(mesh_in,
+ edge1,
+ first_midpoint,
+ boundary_vertex,
+ new_to_old_edges_map,
+ new_edges,
+ loop_edges);
+
+ loop_indices.append(boundary_edge_midpoint_index[edge2]);
+ new_to_old_face_corners_map.append(sorted_corners.first());
+ const int second_midpoint = loop_indices.last();
+ add_edge(mesh_in,
+ edge2,
+ boundary_vertex,
+ second_midpoint,
+ new_to_old_edges_map,
+ new_edges,
+ loop_edges);
+
+ if (old_to_new_edges_map[edge2] == -1) {
+ const int first_face_center = loop_indices.first();
+ add_edge(mesh_in,
+ edge2,
+ second_midpoint,
+ first_face_center,
+ new_to_old_edges_map,
+ new_edges,
+ loop_edges);
+ old_to_new_edges_map[edge2] = new_edges.size() - 1;
+ boundary_vertex_to_relevant_face_map.append(std::pair(second_midpoint, first_face_center));
+ }
+ else {
+ loop_edges.append(old_to_new_edges_map[edge2]);
+ }
+ }
+
+ loop_lengths.append(loop_indices.size());
+ for (const int j : loop_indices) {
+ loops.append(j);
+ }
+ }
+ Mesh *mesh_out = BKE_mesh_new_nomain(
+ vertex_positions.size(), new_edges.size(), 0, loops.size(), loop_lengths.size());
+ MeshComponent out_component;
+ out_component.replace(mesh_out, GeometryOwnershipType::Editable);
+ transfer_attributes(attributes,
+ vertex_types,
+ keep_boundaries,
+ new_to_old_edges_map,
+ new_to_old_face_corners_map,
+ boundary_vertex_to_relevant_face_map,
+ in_component,
+ out_component);
+
+ int loop_start = 0;
+ for (const int i : IndexRange(mesh_out->totpoly)) {
+ mesh_out->mpoly[i].loopstart = loop_start;
+ mesh_out->mpoly[i].totloop = loop_lengths[i];
+ loop_start += loop_lengths[i];
+ }
+ for (const int i : IndexRange(mesh_out->totloop)) {
+ mesh_out->mloop[i].v = loops[i];
+ mesh_out->mloop[i].e = loop_edges[i];
+ }
+ for (const int i : IndexRange(mesh_out->totvert)) {
+ copy_v3_v3(mesh_out->mvert[i].co, vertex_positions[i]);
+ }
+ memcpy(mesh_out->medge, new_edges.data(), sizeof(MEdge) * new_edges.size());
+ BKE_mesh_normals_tag_dirty(mesh_out);
+ geometry_set.replace_mesh(mesh_out);
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
+ const bool keep_boundaries = params.extract_input<bool>("Keep Boundaries");
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_mesh()) {
+ const MeshComponent &component = *geometry_set.get_component_for_read<MeshComponent>();
+ calc_dual_mesh(geometry_set, component, keep_boundaries);
+ }
+ });
+ params.set_output("Dual Mesh", std::move(geometry_set));
+}
+
+} // namespace blender::nodes::node_geo_dual_mesh_cc
+
+void register_node_type_geo_dual_mesh()
+{
+ namespace file_ns = blender::nodes::node_geo_dual_mesh_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(&ntype, GEO_NODE_DUAL_MESH, "Dual Mesh", NODE_CLASS_GEOMETRY, 0);
+ 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/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
index ca6254be182..d23a18ba37b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc
@@ -22,9 +22,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_edge_split_cc {
-static void geo_node_edge_split_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -57,7 +57,7 @@ static Mesh *mesh_edge_split(const Mesh &mesh, const IndexMask selection)
return result;
}
-static void geo_node_edge_split_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
@@ -82,14 +82,16 @@ static void geo_node_edge_split_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_edge_split_cc
void register_node_type_geo_edge_split()
{
+ namespace file_ns = blender::nodes::node_geo_edge_split_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SPLIT_EDGES, "Split Edges", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_edge_split_exec;
- ntype.declare = blender::nodes::geo_node_edge_split_declare;
+ 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/node_geo_geometry_to_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc
new file mode 100644
index 00000000000..7faf104737f
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc
@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_geometry_to_instance_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Geometry")).multi_input();
+ b.add_output<decl::Geometry>(N_("Instances"));
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Vector<GeometrySet> geometries = params.extract_multi_input<GeometrySet>("Geometry");
+ GeometrySet instances_geometry;
+ InstancesComponent &instances_component =
+ instances_geometry.get_component_for_write<InstancesComponent>();
+ for (GeometrySet &geometry : geometries) {
+ geometry.ensure_owns_direct_data();
+ const int handle = instances_component.add_reference(std::move(geometry));
+ instances_component.add_instance(handle, float4x4::identity());
+ }
+ params.set_output("Instances", std::move(instances_geometry));
+}
+
+} // namespace blender::nodes::node_geo_geometry_to_instance_cc
+
+void register_node_type_geo_geometry_to_instance()
+{
+ namespace file_ns = blender::nodes::node_geo_geometry_to_instance_cc;
+
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_GEOMETRY_TO_INSTANCE, "Geometry to Instance", NODE_CLASS_GEOMETRY, 0);
+ node_type_size(&ntype, 160, 100, 300);
+ 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/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc
index 7bbe0716f78..0003f15854d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc
@@ -32,9 +32,11 @@
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_image_texture_cc {
-static void geo_node_image_texture_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryImageTexture)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Image>(N_("Image")).hide_label();
b.add_input<decl::Vector>(N_("Vector"))
@@ -45,13 +47,13 @@ static void geo_node_image_texture_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Alpha")).no_muted_links().dependent_field();
}
-static void geo_node_image_texture_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "interpolation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
uiItemR(layout, ptr, "extension", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
-static void geo_node_image_texture_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryImageTexture *tex = (NodeGeometryImageTexture *)MEM_callocN(
sizeof(NodeGeometryImageTexture), __func__);
@@ -370,20 +372,15 @@ class ImageFieldsFunction : public fn::MultiFunction {
}
};
-static void geo_node_image_texture_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- auto return_default = [&]() {
- params.set_output("Color", ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f));
- params.set_output("Alpha", 1.0f);
- };
-
Image *image = params.get_input<Image *>("Image");
if (image == nullptr) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
- const bNode &node = params.node();
- NodeGeometryImageTexture *data = (NodeGeometryImageTexture *)node.storage;
+ const NodeGeometryImageTexture &storage = node_storage(params.node());
ImageUser image_user;
BKE_imageuser_default(&image_user);
@@ -395,10 +392,11 @@ static void geo_node_image_texture_exec(GeoNodeExecParams params)
std::unique_ptr<ImageFieldsFunction> image_fn;
try {
image_fn = std::make_unique<ImageFieldsFunction>(
- data->interpolation, data->extension, *image, image_user);
+ storage.interpolation, storage.extension, *image, image_user);
}
catch (const std::runtime_error &) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
Field<float3> vector_field = params.extract_input<Field<float3>>("Vector");
@@ -410,20 +408,22 @@ static void geo_node_image_texture_exec(GeoNodeExecParams params)
params.set_output("Alpha", Field<float>(image_op, 1));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_image_texture_cc
-void register_node_type_geo_image_texture(void)
+void register_node_type_geo_image_texture()
{
+ namespace file_ns = blender::nodes::node_geo_image_texture_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_IMAGE_TEXTURE, "Image Texture", NODE_CLASS_TEXTURE, 0);
- ntype.declare = blender::nodes::geo_node_image_texture_declare;
- ntype.draw_buttons = blender::nodes::geo_node_image_texture_layout;
- node_type_init(&ntype, blender::nodes::geo_node_image_texture_init);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons = file_ns::node_layout;
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(
&ntype, "NodeGeometryImageTexture", node_free_standard_storage, node_copy_standard_storage);
node_type_size_preset(&ntype, NODE_SIZE_LARGE);
- ntype.geometry_node_execute = blender::nodes::geo_node_image_texture_exec;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
index b8df545d073..dae8fda2099 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
@@ -16,15 +16,15 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_curve_handles_cc {
-static void geo_node_input_curve_handles_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Vector>(N_("Left")).field_source();
b.add_output<decl::Vector>(N_("Right")).field_source();
}
-static void geo_node_input_curve_handles_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float3> left_field = AttributeFieldInput::Create<float3>("handle_left");
Field<float3> right_field = AttributeFieldInput::Create<float3>("handle_right");
@@ -32,15 +32,17 @@ static void geo_node_input_curve_handles_exec(GeoNodeExecParams params)
params.set_output("Right", std::move(right_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_curve_handles_cc
void register_node_type_geo_input_curve_handles()
{
+ namespace file_ns = blender::nodes::node_geo_input_curve_handles_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_INPUT_CURVE_HANDLES, "Curve Handle Positions", NODE_CLASS_INPUT, 0);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_curve_handles_exec;
- ntype.declare = blender::nodes::geo_node_input_curve_handles_declare;
+ 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/node_geo_input_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc
index f32db3842db..5ba85b6f34e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_tilt.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_curve_tilt_cc {
-static void geo_node_input_curve_tilt_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Tilt")).field_source();
}
-static void geo_node_input_curve_tilt_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float> tilt_field = AttributeFieldInput::Create<float>("tilt");
params.set_output("Tilt", std::move(tilt_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_curve_tilt_cc
void register_node_type_geo_input_curve_tilt()
{
+ namespace file_ns = blender::nodes::node_geo_input_curve_tilt_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_CURVE_TILT, "Curve Tilt", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_curve_tilt_exec;
- ntype.declare = blender::nodes::geo_node_input_curve_tilt_declare;
+ 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/node_geo_input_id.cc b/source/blender/nodes/geometry/nodes/node_geo_input_id.cc
index 37d5bac0325..d2e103a093a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_id.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_id.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_id_cc {
-static void geo_node_input_id_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("ID")).field_source();
}
-static void geo_node_input_id_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<int> position_field{std::make_shared<bke::IDAttributeFieldInput>()};
params.set_output("ID", std::move(position_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_id_cc
void register_node_type_geo_input_id()
{
+ namespace file_ns = blender::nodes::node_geo_input_id_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_ID, "ID", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_id_exec;
- ntype.declare = blender::nodes::geo_node_input_id_declare;
+ 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/node_geo_input_index.cc b/source/blender/nodes/geometry/nodes/node_geo_input_index.cc
index 6200ac5e7a8..74cddfc6a4a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_index.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_index_cc {
-static void geo_node_input_index_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("Index")).field_source();
}
-static void geo_node_input_index_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<int> index_field{std::make_shared<fn::IndexFieldInput>()};
params.set_output("Index", std::move(index_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_index_cc
void register_node_type_geo_input_index()
{
+ namespace file_ns = blender::nodes::node_geo_input_index_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_INDEX, "Index", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_index_exec;
- ntype.declare = blender::nodes::geo_node_input_index_declare;
+ 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/node_geo_input_material.cc b/source/blender/nodes/geometry/nodes/node_geo_input_material.cc
index fc41188dee5..1b6e3c8fc68 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_material.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_material.cc
@@ -19,33 +19,35 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_material_cc {
-static void geo_node_input_material_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Material>(N_("Material"));
}
-static void geo_node_input_material_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "material", 0, "", ICON_NONE);
}
-static void geo_node_input_material_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Material *material = (Material *)params.node().id;
params.set_output("Material", material);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_material_cc
void register_node_type_geo_input_material()
{
+ namespace file_ns = blender::nodes::node_geo_input_material_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_MATERIAL, "Material", NODE_CLASS_INPUT, 0);
- ntype.draw_buttons = blender::nodes::geo_node_input_material_layout;
- ntype.declare = blender::nodes::geo_node_input_material_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_input_material_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ 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/node_geo_input_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_input_material_index.cc
index 5d5d9e40032..4df218eb669 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_material_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_material_index.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_material_index_cc {
-static void geo_node_input_material_index_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("Material Index")).field_source();
}
-static void geo_node_input_material_index_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<int> material_index_field = AttributeFieldInput::Create<int>("material_index");
params.set_output("Material Index", std::move(material_index_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_material_index_cc
void register_node_type_geo_input_material_index()
{
+ namespace file_ns = blender::nodes::node_geo_input_material_index_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_MATERIAL_INDEX, "Material Index", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_material_index_exec;
- ntype.declare = blender::nodes::geo_node_input_material_index_declare;
+ 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/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
new file mode 100644
index 00000000000..ede87252312
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc
@@ -0,0 +1,93 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_mesh_edge_neighbors_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Int>(N_("Face Count"))
+ .field_source()
+ .description(N_("Number of faces that contain the edge"));
+}
+
+class EdgeNeighborCountFieldInput final : public GeometryFieldInput {
+ public:
+ EdgeNeighborCountFieldInput()
+ : GeometryFieldInput(CPPType::get<int>(), "Edge Neighbor Count Field")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ Array<int> face_count(mesh->totedge, 0);
+ for (const int i : IndexRange(mesh->totloop)) {
+ face_count[mesh->mloop[i].e]++;
+ }
+
+ return mesh_component.attribute_try_adapt_domain<int>(
+ VArray<int>::ForContainer(std::move(face_count)), ATTR_DOMAIN_EDGE, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 985671075;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const EdgeNeighborCountFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> neighbor_count_field{std::make_shared<EdgeNeighborCountFieldInput>()};
+ params.set_output("Face Count", std::move(neighbor_count_field));
+}
+
+} // namespace blender::nodes::node_geo_input_mesh_edge_neighbors_cc
+
+void register_node_type_geo_input_mesh_edge_neighbors()
+{
+ namespace file_ns = blender::nodes::node_geo_input_mesh_edge_neighbors_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_MESH_EDGE_NEIGHBORS, "Edge Neighbors", NODE_CLASS_INPUT, 0);
+ 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/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
new file mode 100644
index 00000000000..473bef63e92
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc
@@ -0,0 +1,188 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_mesh_edge_vertices_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Int>(N_("Vertex Index 1"))
+ .field_source()
+ .description(N_("The index of the first vertex in the edge"));
+ b.add_output<decl::Int>(N_("Vertex Index 2"))
+ .field_source()
+ .description(N_("The index of the second vertex in the edge"));
+ b.add_output<decl::Vector>(N_("Position 1"))
+ .field_source()
+ .description(N_("The position of the first vertex in the edge"));
+ b.add_output<decl::Vector>(N_("Position 2"))
+ .field_source()
+ .description(N_("The position of the second vertex in the edge"));
+}
+
+enum VertexNumber { VERTEX_ONE, VERTEX_TWO };
+
+static VArray<int> construct_edge_vertices_gvarray(const MeshComponent &component,
+ const VertexNumber vertex,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+ if (domain == ATTR_DOMAIN_EDGE) {
+
+ if (vertex == VERTEX_ONE) {
+ return VArray<int>::ForFunc(mesh->totpoly,
+ [mesh](const int i) -> int { return mesh->medge[i].v1; });
+ }
+ return VArray<int>::ForFunc(mesh->totpoly,
+ [mesh](const int i) -> int { return mesh->medge[i].v2; });
+ }
+ return {};
+}
+
+class EdgeVerticesFieldInput final : public GeometryFieldInput {
+ private:
+ VertexNumber vertex_;
+
+ public:
+ EdgeVerticesFieldInput(VertexNumber vertex)
+ : GeometryFieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex)
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_edge_vertices_gvarray(mesh_component, vertex_, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ return vertex_ == VERTEX_ONE ? 23847562893465 : 92384598734567;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ if (const EdgeVerticesFieldInput *other_field = dynamic_cast<const EdgeVerticesFieldInput *>(
+ &other)) {
+ return vertex_ == other_field->vertex_;
+ }
+ return false;
+ }
+};
+
+static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &component,
+ const VertexNumber vertex,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ if (vertex == VERTEX_ONE) {
+ return component.attribute_try_adapt_domain<float3>(
+ VArray<float3>::ForFunc(
+ mesh->totedge,
+ [mesh](const int i) { return float3(mesh->mvert[mesh->medge[i].v1].co); }),
+ ATTR_DOMAIN_EDGE,
+ domain);
+ }
+ return component.attribute_try_adapt_domain<float3>(
+ VArray<float3>::ForFunc(
+ mesh->totedge,
+ [mesh](const int i) { return float3(mesh->mvert[mesh->medge[i].v2].co); }),
+ ATTR_DOMAIN_EDGE,
+ domain);
+}
+
+class EdgePositionFieldInput final : public GeometryFieldInput {
+ private:
+ VertexNumber vertex_;
+
+ public:
+ EdgePositionFieldInput(VertexNumber vertex)
+ : GeometryFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_edge_positions_gvarray(mesh_component, vertex_, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ return vertex_ == VERTEX_ONE ? 987456978362 : 374587679866;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ if (const EdgePositionFieldInput *other_field = dynamic_cast<const EdgePositionFieldInput *>(
+ &other)) {
+ return vertex_ == other_field->vertex_;
+ }
+ return false;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> vertex_field_1{std::make_shared<EdgeVerticesFieldInput>(VERTEX_ONE)};
+ Field<int> vertex_field_2{std::make_shared<EdgeVerticesFieldInput>(VERTEX_TWO)};
+ Field<float3> position_field_1{std::make_shared<EdgePositionFieldInput>(VERTEX_ONE)};
+ Field<float3> position_field_2{std::make_shared<EdgePositionFieldInput>(VERTEX_TWO)};
+
+ params.set_output("Vertex Index 1", std::move(vertex_field_1));
+ params.set_output("Vertex Index 2", std::move(vertex_field_2));
+ params.set_output("Position 1", std::move(position_field_1));
+ params.set_output("Position 2", std::move(position_field_2));
+}
+
+} // namespace blender::nodes::node_geo_input_mesh_edge_vertices_cc
+
+void register_node_type_geo_input_mesh_edge_vertices()
+{
+ namespace file_ns = blender::nodes::node_geo_input_mesh_edge_vertices_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_MESH_EDGE_VERTICES, "Edge Vertices", NODE_CLASS_INPUT, 0);
+ 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/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
new file mode 100644
index 00000000000..538b9e9682d
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc
@@ -0,0 +1,96 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_mesh_face_area_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>(N_("Area"))
+ .field_source()
+ .description(N_("The surface area of each of the mesh's faces"));
+}
+
+static VArray<float> construct_face_area_gvarray(const MeshComponent &component,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ auto area_fn = [mesh](const int i) -> float {
+ const MPoly *mp = &mesh->mpoly[i];
+ return BKE_mesh_calc_poly_area(mp, &mesh->mloop[mp->loopstart], mesh->mvert);
+ };
+
+ return component.attribute_try_adapt_domain<float>(
+ VArray<float>::ForFunc(mesh->totpoly, area_fn), ATTR_DOMAIN_FACE, domain);
+}
+
+class FaceAreaFieldInput final : public GeometryFieldInput {
+ public:
+ FaceAreaFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Face Area Field")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_face_area_gvarray(mesh_component, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 1346334523;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const FaceAreaFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ params.set_output("Area", Field<float>(std::make_shared<FaceAreaFieldInput>()));
+}
+
+} // namespace blender::nodes::node_geo_input_mesh_face_area_cc
+
+void register_node_type_geo_input_mesh_face_area()
+{
+ namespace file_ns = blender::nodes::node_geo_input_mesh_face_area_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(&ntype, GEO_NODE_INPUT_MESH_FACE_AREA, "Face Area", NODE_CLASS_INPUT, 0);
+ 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/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
new file mode 100644
index 00000000000..80bb25dc7ca
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc
@@ -0,0 +1,158 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_mesh_face_neighbors_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Int>(N_("Vertex Count"))
+ .field_source()
+ .description(N_("Number of edges or points in the face"));
+ b.add_output<decl::Int>(N_("Face Count"))
+ .field_source()
+ .description(N_("Number of faces which share an edge with the face"));
+}
+
+static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &component,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ Array<int> edge_count(mesh->totedge, 0);
+ for (const int i : IndexRange(mesh->totloop)) {
+ edge_count[mesh->mloop[i].e]++;
+ }
+
+ Array<int> poly_count(mesh->totpoly, 0);
+ for (const int poly_num : IndexRange(mesh->totpoly)) {
+ MPoly &poly = mesh->mpoly[poly_num];
+ for (const int loop_num : IndexRange(poly.loopstart, poly.totloop)) {
+ poly_count[poly_num] += edge_count[mesh->mloop[loop_num].e] - 1;
+ }
+ }
+
+ return component.attribute_try_adapt_domain<int>(
+ VArray<int>::ForContainer(std::move(poly_count)), ATTR_DOMAIN_FACE, domain);
+}
+
+class FaceNeighborCountFieldInput final : public GeometryFieldInput {
+ public:
+ FaceNeighborCountFieldInput()
+ : GeometryFieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_neighbor_count_gvarray(mesh_component, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 823543774;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const FaceNeighborCountFieldInput *>(&other) != nullptr;
+ }
+};
+
+static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ return component.attribute_try_adapt_domain<int>(
+ VArray<int>::ForFunc(mesh->totpoly,
+ [mesh](const int i) -> float { return mesh->mpoly[i].totloop; }),
+ ATTR_DOMAIN_FACE,
+ domain);
+}
+
+class FaceVertexCountFieldInput final : public GeometryFieldInput {
+ public:
+ FaceVertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_vertex_count_gvarray(mesh_component, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 236235463634;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const FaceVertexCountFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> vertex_count_field{std::make_shared<FaceVertexCountFieldInput>()};
+ Field<int> neighbor_count_field{std::make_shared<FaceNeighborCountFieldInput>()};
+ params.set_output("Vertex Count", std::move(vertex_count_field));
+ params.set_output("Face Count", std::move(neighbor_count_field));
+}
+
+} // namespace blender::nodes::node_geo_input_mesh_face_neighbors_cc
+
+void register_node_type_geo_input_mesh_face_neighbors()
+{
+ namespace file_ns = blender::nodes::node_geo_input_mesh_face_neighbors_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_MESH_FACE_NEIGHBORS, "Face Neighbors", NODE_CLASS_INPUT, 0);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ 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/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
new file mode 100644
index 00000000000..3c713ef6ca9
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc
@@ -0,0 +1,101 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "BLI_disjoint_set.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_mesh_island_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Int>(N_("Index"))
+ .field_source()
+ .description(N_("Island indices are based on the order of the lowest-numbered vertex "
+ "contained in each island"));
+}
+
+class IslandFieldInput final : public GeometryFieldInput {
+ public:
+ IslandFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Island Index")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() != GEO_COMPONENT_TYPE_MESH) {
+ return {};
+ }
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ DisjointSet islands(mesh->totvert);
+ for (const int i : IndexRange(mesh->totedge)) {
+ islands.join(mesh->medge[i].v1, mesh->medge[i].v2);
+ }
+
+ Array<int> output(mesh->totvert);
+ VectorSet<int> ordered_roots;
+ for (const int i : IndexRange(mesh->totvert)) {
+ const int64_t root = islands.find_root(i);
+ output[i] = ordered_roots.index_of_or_add(root);
+ }
+
+ return mesh_component.attribute_try_adapt_domain<int>(
+ VArray<int>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain);
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 635467354;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const IslandFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> island_field{std::make_shared<IslandFieldInput>()};
+ params.set_output("Index", std::move(island_field));
+}
+
+} // namespace blender::nodes::node_geo_input_mesh_island_cc
+
+void register_node_type_geo_input_mesh_island()
+{
+ namespace file_ns = blender::nodes::node_geo_input_mesh_island_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(&ntype, GEO_NODE_INPUT_MESH_ISLAND, "Mesh Island", NODE_CLASS_INPUT, 0);
+ 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/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
new file mode 100644
index 00000000000..05140c92205
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc
@@ -0,0 +1,155 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_mesh.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_mesh_vertex_neighbors_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Int>(N_("Vertex Count"))
+ .field_source()
+ .description(N_("Vertex count and edge count are equal"));
+ b.add_output<decl::Int>(N_("Face Count"))
+ .field_source()
+ .description(N_("Number of faces that contain the vertex"));
+}
+
+static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ if (domain == ATTR_DOMAIN_POINT) {
+ Array<int> vertices(mesh->totvert, 0);
+ for (const int i : IndexRange(mesh->totedge)) {
+ vertices[mesh->medge[i].v1]++;
+ vertices[mesh->medge[i].v2]++;
+ }
+ return VArray<int>::ForContainer(std::move(vertices));
+ }
+ return {};
+}
+
+class VertexCountFieldInput final : public GeometryFieldInput {
+ public:
+ VertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_vertex_count_gvarray(mesh_component, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 23574528465;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const VertexCountFieldInput *>(&other) != nullptr;
+ }
+};
+
+static VArray<int> construct_face_count_gvarray(const MeshComponent &component,
+ const AttributeDomain domain)
+{
+ const Mesh *mesh = component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ if (domain == ATTR_DOMAIN_POINT) {
+ Array<int> vertices(mesh->totvert, 0);
+ for (const int i : IndexRange(mesh->totloop)) {
+ int vertex = mesh->mloop[i].v;
+ vertices[vertex]++;
+ }
+ return VArray<int>::ForContainer(std::move(vertices));
+ }
+ return {};
+}
+
+class VertexFaceCountFieldInput final : public GeometryFieldInput {
+ public:
+ VertexFaceCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Face Count Field")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ return construct_face_count_gvarray(mesh_component, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 3462374322;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const VertexFaceCountFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ Field<int> vertex_field{std::make_shared<VertexCountFieldInput>()};
+ Field<int> face_field{std::make_shared<VertexFaceCountFieldInput>()};
+
+ params.set_output("Vertex Count", std::move(vertex_field));
+ params.set_output("Face Count", std::move(face_field));
+}
+
+} // namespace blender::nodes::node_geo_input_mesh_vertex_neighbors_cc
+
+void register_node_type_geo_input_mesh_vertex_neighbors()
+{
+ namespace file_ns = blender::nodes::node_geo_input_mesh_vertex_neighbors_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(
+ &ntype, GEO_NODE_INPUT_MESH_VERTEX_NEIGHBORS, "Vertex Neighbors", NODE_CLASS_INPUT, 0);
+ 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/node_geo_input_normal.cc b/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
index 6c95ad73bf7..1cc508d9d9d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_normal.cc
@@ -24,9 +24,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_normal_cc {
-static void geo_node_input_normal_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Vector>(N_("Normal")).field_source();
}
@@ -93,8 +93,7 @@ static VArray<float3> mesh_vertex_normals(const Mesh &mesh,
static VArray<float3> construct_mesh_normals_gvarray(const MeshComponent &mesh_component,
const Mesh &mesh,
const IndexMask mask,
- const AttributeDomain domain,
- ResourceScope &UNUSED(scope))
+ const AttributeDomain domain)
{
Span<MVert> verts{mesh.mvert, mesh.totvert};
Span<MEdge> edges{mesh.medge, mesh.totedge};
@@ -199,8 +198,7 @@ static Array<float3> curve_normal_point_domain(const CurveEval &curve)
}
static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &component,
- const AttributeDomain domain,
- ResourceScope &UNUSED(scope))
+ const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -231,36 +229,29 @@ static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &compo
return nullptr;
}
-class NormalFieldInput final : public fn::FieldInput {
+class NormalFieldInput final : public GeometryFieldInput {
public:
- NormalFieldInput() : fn::FieldInput(CPPType::get<float3>(), "Normal node")
+ NormalFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Normal node")
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask mask,
- ResourceScope &scope) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask mask) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
-
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
-
- if (component.type() == GEO_COMPONENT_TYPE_MESH) {
- const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
- const Mesh *mesh = mesh_component.get_for_read();
- if (mesh == nullptr) {
- return {};
- }
-
- return construct_mesh_normals_gvarray(mesh_component, *mesh, mask, domain, scope);
- }
- if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- return construct_curve_normal_gvarray(curve_component, domain, scope);
+ if (component.type() == GEO_COMPONENT_TYPE_MESH) {
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
}
+
+ return construct_mesh_normals_gvarray(mesh_component, *mesh, mask, domain);
+ }
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ return construct_curve_normal_gvarray(curve_component, domain);
}
return {};
}
@@ -277,20 +268,22 @@ class NormalFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_input_normal_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float3> normal_field{std::make_shared<NormalFieldInput>()};
params.set_output("Normal", std::move(normal_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_normal_cc
void register_node_type_geo_input_normal()
{
+ namespace file_ns = blender::nodes::node_geo_input_normal_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_NORMAL, "Normal", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_normal_exec;
- ntype.declare = blender::nodes::geo_node_input_normal_declare;
+ 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/node_geo_input_position.cc b/source/blender/nodes/geometry/nodes/node_geo_input_position.cc
index a8477d4bc4f..8322831a871 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_position.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_position_cc {
-static void geo_node_input_position_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Vector>(N_("Position")).field_source();
}
-static void geo_node_input_position_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float3> position_field{AttributeFieldInput::Create<float3>("position")};
params.set_output("Position", std::move(position_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_position_cc
void register_node_type_geo_input_position()
{
+ namespace file_ns = blender::nodes::node_geo_input_position_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_POSITION, "Position", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_position_exec;
- ntype.declare = blender::nodes::geo_node_input_position_declare;
+ 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/node_geo_input_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_input_radius.cc
index 6d2c4c38cbe..26fb74f5a5b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_radius.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_radius.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_radius_cc {
-static void geo_node_input_radius_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Radius")).default_value(1.0f).min(0.0f).field_source();
}
-static void geo_node_input_radius_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float> radius_field = AttributeFieldInput::Create<float>("radius");
params.set_output("Radius", std::move(radius_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_radius_cc
void register_node_type_geo_input_radius()
{
+ namespace file_ns = blender::nodes::node_geo_input_radius_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_RADIUS, "Radius", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_radius_exec;
- ntype.declare = blender::nodes::geo_node_input_radius_declare;
+ 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/node_geo_input_scene_time.cc b/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc
new file mode 100644
index 00000000000..cfc1a81f7b9
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc
@@ -0,0 +1,50 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BKE_scene.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_input_scene_time_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_output<decl::Float>(N_("Seconds"));
+ b.add_output<decl::Float>(N_("Frame"));
+}
+
+static void node_exec(GeoNodeExecParams params)
+{
+ const Scene *scene = DEG_get_input_scene(params.depsgraph());
+ const float scene_ctime = BKE_scene_ctime_get(scene);
+ const double frame_rate = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base);
+ params.set_output("Seconds", float(scene_ctime / frame_rate));
+ params.set_output("Frame", scene_ctime);
+}
+
+} // namespace blender::nodes::node_geo_input_scene_time_cc
+
+void register_node_type_geo_input_scene_time()
+{
+ static bNodeType ntype;
+ namespace file_ns = blender::nodes::node_geo_input_scene_time_cc;
+ geo_node_type_base(&ntype, GEO_NODE_INPUT_SCENE_TIME, "Scene Time", NODE_CLASS_INPUT, 0);
+ ntype.geometry_node_execute = file_ns::node_exec;
+ ntype.declare = file_ns::node_declare;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc
index dcd14b1c054..3efe8577e51 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_shade_smooth.cc
@@ -16,27 +16,29 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_shade_smooth_cc {
-static void geo_node_input_shade_smooth_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Bool>(N_("Smooth")).field_source();
}
-static void geo_node_input_shade_smooth_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<bool> shade_smooth_field = AttributeFieldInput::Create<bool>("shade_smooth");
params.set_output("Smooth", std::move(shade_smooth_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_shade_smooth_cc
void register_node_type_geo_input_shade_smooth()
{
+ namespace file_ns = blender::nodes::node_geo_input_shade_smooth_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_SHADE_SMOOTH, "Is Shade Smooth", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_shade_smooth_exec;
- ntype.declare = blender::nodes::geo_node_input_shade_smooth_declare;
+ 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/node_geo_input_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc
index a8ee6dd8b12..5f833445a76 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_cyclic.cc
@@ -16,28 +16,30 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_spline_cyclic_cc {
-static void geo_node_input_spline_cyclic_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Bool>(N_("Cyclic")).field_source();
}
-static void geo_node_input_spline_cyclic_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<bool> cyclic_field = AttributeFieldInput::Create<bool>("cyclic");
params.set_output("Cyclic", std::move(cyclic_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_spline_cyclic_cc
void register_node_type_geo_input_spline_cyclic()
{
+ namespace file_ns = blender::nodes::node_geo_input_spline_cyclic_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_INPUT_SPLINE_CYCLIC, "Is Spline Cyclic", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_spline_cyclic_exec;
- ntype.declare = blender::nodes::geo_node_input_spline_cyclic_declare;
+ 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/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
index a976e0b193f..810d6e2fddd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
@@ -18,16 +18,20 @@
#include "BKE_spline.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_spline_length_cc {
-static void geo_node_input_spline_length_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Float>(N_("Length")).field_source();
+ b.add_output<decl::Int>(N_("Point Count")).field_source();
}
+/* --------------------------------------------------------------------
+ * Spline Length
+ */
+
static VArray<float> construct_spline_length_gvarray(const CurveComponent &component,
- const AttributeDomain domain,
- ResourceScope &UNUSED(scope))
+ const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -46,29 +50,23 @@ static VArray<float> construct_spline_length_gvarray(const CurveComponent &compo
std::move(length), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
}
- return nullptr;
+ return {};
}
-class SplineLengthFieldInput final : public fn::FieldInput {
+class SplineLengthFieldInput final : public GeometryFieldInput {
public:
- SplineLengthFieldInput() : fn::FieldInput(CPPType::get<float>(), "Spline Length node")
+ SplineLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Spline Length node")
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask UNUSED(mask),
- ResourceScope &scope) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
-
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
- if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- return construct_spline_length_gvarray(curve_component, domain, scope);
- }
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ return construct_spline_length_gvarray(curve_component, domain);
}
return {};
}
@@ -85,20 +83,81 @@ class SplineLengthFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_input_spline_length_exec(GeoNodeExecParams params)
+/* --------------------------------------------------------------------
+ * Spline Count
+ */
+
+static VArray<int> construct_spline_count_gvarray(const CurveComponent &component,
+ const AttributeDomain domain)
+{
+ const CurveEval *curve = component.get_for_read();
+ if (curve == nullptr) {
+ return {};
+ }
+
+ Span<SplinePtr> splines = curve->splines();
+ auto count_fn = [splines](int i) { return splines[i]->size(); };
+
+ if (domain == ATTR_DOMAIN_CURVE) {
+ return VArray<int>::ForFunc(splines.size(), count_fn);
+ }
+ if (domain == ATTR_DOMAIN_POINT) {
+ VArray<int> count = VArray<int>::ForFunc(splines.size(), count_fn);
+ return component.attribute_try_adapt_domain<int>(
+ std::move(count), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
+ }
+
+ return {};
+}
+
+class SplineCountFieldInput final : public GeometryFieldInput {
+ public:
+ SplineCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Point Count")
+ {
+ category_ = Category::Generated;
+ }
+
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
+ {
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ return construct_spline_count_gvarray(curve_component, domain);
+ }
+ return {};
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 456364322625;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const SplineCountFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void node_geo_exec(GeoNodeExecParams params)
{
- Field<float> length_field{std::make_shared<SplineLengthFieldInput>()};
- params.set_output("Length", std::move(length_field));
+ Field<float> spline_length_field{std::make_shared<SplineLengthFieldInput>()};
+ Field<int> spline_count_field{std::make_shared<SplineCountFieldInput>()};
+
+ params.set_output("Length", std::move(spline_length_field));
+ params.set_output("Point Count", std::move(spline_count_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_spline_length_cc
void register_node_type_geo_input_spline_length()
{
- static bNodeType ntype;
+ namespace file_ns = blender::nodes::node_geo_input_spline_length_cc;
+ static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_SPLINE_LENGTH, "Spline Length", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_spline_length_exec;
- ntype.declare = blender::nodes::geo_node_input_spline_length_declare;
+ 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/node_geo_input_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc
index 75fb8a13d38..77b6e27e6a2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_resolution.cc
@@ -16,28 +16,30 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_spline_resolution_cc {
-static void geo_node_input_spline_resolution_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Int>(N_("Resolution")).field_source();
}
-static void geo_node_input_spline_resolution_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<int> resolution_field = AttributeFieldInput::Create<int>("resolution");
params.set_output("Resolution", std::move(resolution_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_spline_resolution_cc
void register_node_type_geo_input_spline_resolution()
{
+ namespace file_ns = blender::nodes::node_geo_input_spline_resolution_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_INPUT_SPLINE_RESOLUTION, "Spline Resolution", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_spline_resolution_exec;
- ntype.declare = blender::nodes::geo_node_input_spline_resolution_declare;
+ 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/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
index 49885f29d44..86f882df3cd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc
@@ -20,9 +20,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_input_tangent_cc {
-static void geo_node_input_tangent_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Vector>(N_("Tangent")).field_source();
}
@@ -85,8 +85,7 @@ static Array<float3> curve_tangent_point_domain(const CurveEval &curve)
}
static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component,
- const AttributeDomain domain,
- ResourceScope &UNUSED(scope))
+ const AttributeDomain domain)
{
const CurveEval *curve = component.get_for_read();
if (curve == nullptr) {
@@ -118,27 +117,20 @@ static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &comp
return nullptr;
}
-class TangentFieldInput final : public fn::FieldInput {
+class TangentFieldInput final : public GeometryFieldInput {
public:
- TangentFieldInput() : fn::FieldInput(CPPType::get<float3>(), "Tangent node")
+ TangentFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Tangent node")
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask UNUSED(mask),
- ResourceScope &scope) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask UNUSED(mask)) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
-
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
-
- if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
- const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
- return construct_curve_tangent_gvarray(curve_component, domain, scope);
- }
+ if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
+ const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
+ return construct_curve_tangent_gvarray(curve_component, domain);
}
return {};
}
@@ -155,20 +147,22 @@ class TangentFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_input_tangent_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Field<float3> tangent_field{std::make_shared<TangentFieldInput>()};
params.set_output("Tangent", std::move(tangent_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_input_tangent_cc
void register_node_type_geo_input_tangent()
{
+ namespace file_ns = blender::nodes::node_geo_input_tangent_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_INPUT_TANGENT, "Curve Tangent", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_input_tangent_exec;
- ntype.declare = blender::nodes::geo_node_input_tangent_declare;
+ 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/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
index 2a68030aba7..486f90760f5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
@@ -22,11 +22,13 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "BKE_attribute_math.hh"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_instance_on_points_cc {
-static void geo_node_instance_on_points_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Points")).description(N_("Points to instance on"));
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
@@ -53,20 +55,34 @@ static void geo_node_instance_on_points_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Instances"));
}
-static void add_instances_from_component(InstancesComponent &dst_component,
- const GeometryComponent &src_component,
- const GeometrySet &instance,
- const GeoNodeExecParams &params)
+static void add_instances_from_component(
+ InstancesComponent &dst_component,
+ const GeometryComponent &src_component,
+ const GeometrySet &instance,
+ const GeoNodeExecParams &params,
+ const Map<AttributeIDRef, AttributeKind> &attributes_to_propagate)
{
const AttributeDomain domain = ATTR_DOMAIN_POINT;
const int domain_size = src_component.attribute_domain_size(domain);
+ VArray<bool> pick_instance;
+ VArray<int> indices;
+ VArray<float3> rotations;
+ VArray<float3> scales;
+
GeometryComponentFieldContext field_context{src_component, domain};
const Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ /* The evaluator could use the component's stable IDs as a destination directly, but only the
+ * selected indices should be copied. */
+ evaluator.add(params.get_input<Field<bool>>("Pick Instance"), &pick_instance);
+ evaluator.add(params.get_input<Field<int>>("Instance Index"), &indices);
+ evaluator.add(params.get_input<Field<float3>>("Rotation"), &rotations);
+ evaluator.add(params.get_input<Field<float3>>("Scale"), &scales);
+ evaluator.evaluate();
+
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
/* The initial size of the component might be non-zero when this function is called for multiple
* component types. */
@@ -79,19 +95,6 @@ static void add_instances_from_component(InstancesComponent &dst_component,
MutableSpan<float4x4> dst_transforms = dst_component.instance_transforms().slice(start_len,
select_len);
- FieldEvaluator field_evaluator{field_context, domain_size};
- VArray<bool> pick_instance;
- VArray<int> indices;
- VArray<float3> rotations;
- VArray<float3> scales;
- /* The evaluator could use the component's stable IDs as a destination directly, but only the
- * selected indices should be copied. */
- field_evaluator.add(params.get_input<Field<bool>>("Pick Instance"), &pick_instance);
- field_evaluator.add(params.get_input<Field<int>>("Instance Index"), &indices);
- field_evaluator.add(params.get_input<Field<float3>>("Rotation"), &rotations);
- field_evaluator.add(params.get_input<Field<float3>>("Scale"), &scales);
- field_evaluator.evaluate();
-
VArray<float3> positions = src_component.attribute_get_for_read<float3>(
"position", domain, {0, 0, 0});
@@ -154,17 +157,6 @@ static void add_instances_from_component(InstancesComponent &dst_component,
}
});
- VArray<int> ids = src_component
- .attribute_try_get_for_read("id", ATTR_DOMAIN_POINT, CD_PROP_INT32)
- .typed<int>();
- if (ids) {
- VArray_Span<int> ids_span{ids};
- MutableSpan<int> dst_ids = dst_component.instance_ids_ensure();
- for (const int64_t i : selection.index_range()) {
- dst_ids[i] = ids_span[selection[i]];
- }
- }
-
if (pick_instance.is_single()) {
if (pick_instance.get_internal_single()) {
if (instance.has_realized_data()) {
@@ -174,9 +166,40 @@ static void add_instances_from_component(InstancesComponent &dst_component,
}
}
}
+
+ bke::CustomDataAttributes &instance_attributes = dst_component.attributes();
+ for (const auto item : attributes_to_propagate.items()) {
+ const AttributeIDRef &attribute_id = item.key;
+ const AttributeKind attribute_kind = item.value;
+
+ const GVArray src_attribute = src_component.attribute_get_for_read(
+ attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
+ BLI_assert(src_attribute);
+ std::optional<GMutableSpan> dst_attribute_opt = instance_attributes.get_for_write(
+ attribute_id);
+ if (!dst_attribute_opt) {
+ if (!instance_attributes.create(attribute_id, attribute_kind.data_type)) {
+ continue;
+ }
+ dst_attribute_opt = instance_attributes.get_for_write(attribute_id);
+ }
+ BLI_assert(dst_attribute_opt);
+ const GMutableSpan dst_attribute = dst_attribute_opt->slice(start_len, select_len);
+ threading::parallel_for(selection.index_range(), 1024, [&](IndexRange selection_range) {
+ attribute_math::convert_to_static_type(attribute_kind.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ VArray<T> src = src_attribute.typed<T>();
+ MutableSpan<T> dst = dst_attribute.typed<T>();
+ for (const int range_i : selection_range) {
+ const int i = selection[range_i];
+ dst[range_i] = src[i];
+ }
+ });
+ });
+ }
}
-static void geo_node_instance_on_points_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
GeometrySet instance = params.get_input<GeometrySet>("Instance");
@@ -185,23 +208,36 @@ static void geo_node_instance_on_points_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+ Map<AttributeIDRef, AttributeKind> attributes_to_propagate;
+ geometry_set.gather_attributes_for_propagation(
+ {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE},
+ GEO_COMPONENT_TYPE_INSTANCES,
+ false,
+ attributes_to_propagate);
+ attributes_to_propagate.remove("position");
+
if (geometry_set.has<MeshComponent>()) {
- add_instances_from_component(
- instances, *geometry_set.get_component_for_read<MeshComponent>(), instance, params);
- geometry_set.remove(GEO_COMPONENT_TYPE_MESH);
+ add_instances_from_component(instances,
+ *geometry_set.get_component_for_read<MeshComponent>(),
+ instance,
+ params,
+ attributes_to_propagate);
}
if (geometry_set.has<PointCloudComponent>()) {
add_instances_from_component(instances,
*geometry_set.get_component_for_read<PointCloudComponent>(),
instance,
- params);
- geometry_set.remove(GEO_COMPONENT_TYPE_POINT_CLOUD);
+ params,
+ attributes_to_propagate);
}
if (geometry_set.has<CurveComponent>()) {
- add_instances_from_component(
- instances, *geometry_set.get_component_for_read<CurveComponent>(), instance, params);
- geometry_set.remove(GEO_COMPONENT_TYPE_CURVE);
+ add_instances_from_component(instances,
+ *geometry_set.get_component_for_read<CurveComponent>(),
+ instance,
+ params,
+ attributes_to_propagate);
}
+ geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
});
/* Unused references may have been added above. Remove those now so that other nodes don't
@@ -214,15 +250,17 @@ static void geo_node_instance_on_points_exec(GeoNodeExecParams params)
params.set_output("Instances", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_instance_on_points_cc
void register_node_type_geo_instance_on_points()
{
+ namespace file_ns = blender::nodes::node_geo_instance_on_points_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_INSTANCE_ON_POINTS, "Instance on Points", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_instance_on_points_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_instance_on_points_exec;
+ 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/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
index c3955426e69..9942e388ba5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
@@ -14,14 +14,16 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "BKE_pointcloud.h"
#include "DNA_pointcloud_types.h"
+#include "BKE_attribute_math.hh"
+#include "BKE_pointcloud.h"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_instances_to_points_cc {
-static void geo_node_instances_to_points_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Instances")).only_instances();
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -51,14 +53,15 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
{
const InstancesComponent &instances = *geometry_set.get_component_for_read<InstancesComponent>();
- const AttributeDomain attribute_domain = ATTR_DOMAIN_POINT;
- GeometryComponentFieldContext field_context{instances, attribute_domain};
- const int domain_size = instances.attribute_domain_size(attribute_domain);
+ GeometryComponentFieldContext field_context{instances, ATTR_DOMAIN_INSTANCE};
+ const int domain_size = instances.attribute_domain_size(ATTR_DOMAIN_INSTANCE);
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(std::move(selection_field));
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(std::move(selection_field));
+ evaluator.add(std::move(position_field));
+ evaluator.add(std::move(radius_field));
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
if (selection.is_empty()) {
return;
}
@@ -68,27 +71,40 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
PointCloudComponent &points = geometry_set.get_component_for_write<PointCloudComponent>();
- fn::FieldEvaluator evaluator{field_context, &selection};
- evaluator.add(std::move(position_field));
- evaluator.add(std::move(radius_field));
- evaluator.evaluate();
const VArray<float3> &positions = evaluator.get_evaluated<float3>(0);
copy_attribute_to_points(positions, selection, {(float3 *)pointcloud->co, pointcloud->totpoint});
const VArray<float> &radii = evaluator.get_evaluated<float>(1);
copy_attribute_to_points(radii, selection, {pointcloud->radius, pointcloud->totpoint});
- if (!instances.instance_ids().is_empty()) {
- OutputAttribute_Typed<int> id_attribute = points.attribute_try_get_for_output<int>(
- "id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
- MutableSpan<int> ids = id_attribute.as_span();
- for (const int i : selection.index_range()) {
- ids[i] = instances.instance_ids()[selection[i]];
- }
- id_attribute.save();
+ Map<AttributeIDRef, AttributeKind> attributes_to_propagate;
+ geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES},
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ false,
+ attributes_to_propagate);
+ /* These two attributes are added by the implicit inputs above. */
+ attributes_to_propagate.remove("position");
+ attributes_to_propagate.remove("radius");
+
+ for (const auto item : attributes_to_propagate.items()) {
+ const AttributeIDRef &attribute_id = item.key;
+ const AttributeKind attribute_kind = item.value;
+
+ const GVArray src = instances.attribute_get_for_read(
+ attribute_id, ATTR_DOMAIN_INSTANCE, attribute_kind.data_type);
+ BLI_assert(src);
+ OutputAttribute dst = points.attribute_try_get_for_output_only(
+ attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
+ BLI_assert(dst);
+
+ attribute_math::convert_to_static_type(attribute_kind.data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ copy_attribute_to_points(src.typed<T>(), selection, dst.as_span().typed<T>());
+ });
+ dst.save();
}
}
-static void geo_node_instances_to_points_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
@@ -101,19 +117,21 @@ static void geo_node_instances_to_points_exec(GeoNodeExecParams params)
params.set_output("Points", std::move(geometry_set));
}
else {
- params.set_output("Points", GeometrySet());
+ params.set_default_remaining_outputs();
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_instances_to_points_cc
void register_node_type_geo_instances_to_points()
{
+ namespace file_ns = blender::nodes::node_geo_instances_to_points_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_INSTANCES_TO_POINTS, "Instances to Points", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_instances_to_points_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_instances_to_points_exec;
+ 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/node_geo_is_viewport.cc b/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc
index 8e0e98f7bd5..5925d440317 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_is_viewport.cc
@@ -18,14 +18,14 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_is_viewport_cc {
-static void geo_node_is_viewport_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Bool>(N_("Is Viewport"));
}
-static void geo_node_is_viewport_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const Depsgraph *depsgraph = params.depsgraph();
const eEvaluationMode mode = DEG_get_mode(depsgraph);
@@ -34,14 +34,16 @@ static void geo_node_is_viewport_exec(GeoNodeExecParams params)
params.set_output("Is Viewport", is_viewport);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_is_viewport_cc
void register_node_type_geo_is_viewport()
{
+ namespace file_ns = blender::nodes::node_geo_is_viewport_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_IS_VIEWPORT, "Is Viewport", NODE_CLASS_INPUT, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_is_viewport_exec;
- ntype.declare = blender::nodes::geo_node_is_viewport_declare;
+ 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/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index fcdf7c2da01..bf7a9f49829 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -19,127 +19,23 @@
#include "BKE_mesh_runtime.h"
#include "BKE_pointcloud.h"
#include "BKE_spline.hh"
+#include "BKE_type_conversions.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "NOD_type_conversions.hh"
+#include "GEO_realize_instances.hh"
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_join_geometry_cc {
-static void geo_node_join_geometry_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).multi_input();
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent *> src_components)
-{
- int totverts = 0;
- int totloops = 0;
- int totedges = 0;
- int totpolys = 0;
-
- int64_t cd_dirty_vert = 0;
- int64_t cd_dirty_poly = 0;
- int64_t cd_dirty_edge = 0;
- int64_t cd_dirty_loop = 0;
-
- VectorSet<Material *> materials;
-
- for (const MeshComponent *mesh_component : src_components) {
- const Mesh *mesh = mesh_component->get_for_read();
- totverts += mesh->totvert;
- totloops += mesh->totloop;
- totedges += mesh->totedge;
- totpolys += mesh->totpoly;
- cd_dirty_vert |= mesh->runtime.cd_dirty_vert;
- cd_dirty_poly |= mesh->runtime.cd_dirty_poly;
- cd_dirty_edge |= mesh->runtime.cd_dirty_edge;
- cd_dirty_loop |= mesh->runtime.cd_dirty_loop;
-
- for (const int slot_index : IndexRange(mesh->totcol)) {
- Material *material = mesh->mat[slot_index];
- materials.add(material);
- }
- }
-
- const Mesh *first_input_mesh = src_components[0]->get_for_read();
- Mesh *new_mesh = BKE_mesh_new_nomain(totverts, totedges, 0, totloops, totpolys);
- BKE_mesh_copy_parameters_for_eval(new_mesh, first_input_mesh);
-
- for (const int i : IndexRange(materials.size())) {
- Material *material = materials[i];
- BKE_id_material_eval_assign(&new_mesh->id, i + 1, material);
- }
-
- new_mesh->runtime.cd_dirty_vert = cd_dirty_vert;
- new_mesh->runtime.cd_dirty_poly = cd_dirty_poly;
- new_mesh->runtime.cd_dirty_edge = cd_dirty_edge;
- new_mesh->runtime.cd_dirty_loop = cd_dirty_loop;
-
- int vert_offset = 0;
- int loop_offset = 0;
- int edge_offset = 0;
- int poly_offset = 0;
- for (const MeshComponent *mesh_component : src_components) {
- const Mesh *mesh = mesh_component->get_for_read();
- if (mesh == nullptr) {
- continue;
- }
-
- Array<int> material_index_map(mesh->totcol);
- for (const int i : IndexRange(mesh->totcol)) {
- Material *material = mesh->mat[i];
- const int new_material_index = materials.index_of(material);
- material_index_map[i] = new_material_index;
- }
-
- for (const int i : IndexRange(mesh->totvert)) {
- const MVert &old_vert = mesh->mvert[i];
- MVert &new_vert = new_mesh->mvert[vert_offset + i];
- new_vert = old_vert;
- }
-
- for (const int i : IndexRange(mesh->totedge)) {
- const MEdge &old_edge = mesh->medge[i];
- MEdge &new_edge = new_mesh->medge[edge_offset + i];
- new_edge = old_edge;
- new_edge.v1 += vert_offset;
- new_edge.v2 += vert_offset;
- }
- for (const int i : IndexRange(mesh->totloop)) {
- const MLoop &old_loop = mesh->mloop[i];
- MLoop &new_loop = new_mesh->mloop[loop_offset + i];
- new_loop = old_loop;
- new_loop.v += vert_offset;
- new_loop.e += edge_offset;
- }
- for (const int i : IndexRange(mesh->totpoly)) {
- const MPoly &old_poly = mesh->mpoly[i];
- MPoly &new_poly = new_mesh->mpoly[poly_offset + i];
- new_poly = old_poly;
- new_poly.loopstart += loop_offset;
- if (old_poly.mat_nr >= 0 && old_poly.mat_nr < mesh->totcol) {
- new_poly.mat_nr = material_index_map[new_poly.mat_nr];
- }
- else {
- /* The material index was invalid before. */
- new_poly.mat_nr = 0;
- }
- }
-
- vert_offset += mesh->totvert;
- loop_offset += mesh->totloop;
- edge_offset += mesh->totedge;
- poly_offset += mesh->totpoly;
- }
-
- return new_mesh;
-}
-
template<typename Component>
static Array<const GeometryComponent *> to_base_components(Span<const Component *> components)
{
@@ -223,33 +119,6 @@ static void join_attributes(Span<const GeometryComponent *> src_components,
}
}
-static void join_components(Span<const MeshComponent *> src_components, GeometrySet &result)
-{
- Mesh *new_mesh = join_mesh_topology_and_builtin_attributes(src_components);
-
- MeshComponent &dst_component = result.get_component_for_write<MeshComponent>();
- dst_component.replace(new_mesh);
-
- /* Don't copy attributes that are stored directly in the mesh data structs. */
- join_attributes(to_base_components(src_components),
- dst_component,
- {"position", "material_index", "normal", "shade_smooth", "crease"});
-}
-
-static void join_components(Span<const PointCloudComponent *> src_components, GeometrySet &result)
-{
- int totpoints = 0;
- for (const PointCloudComponent *pointcloud_component : src_components) {
- totpoints += pointcloud_component->attribute_domain_size(ATTR_DOMAIN_POINT);
- }
-
- PointCloudComponent &dst_component = result.get_component_for_write<PointCloudComponent>();
- PointCloud *pointcloud = BKE_pointcloud_new_nomain(totpoints);
- dst_component.replace(pointcloud);
-
- join_attributes(to_base_components(src_components), dst_component);
-}
-
static void join_components(Span<const InstancesComponent *> src_components, GeometrySet &result)
{
InstancesComponent &dst_component = result.get_component_for_write<InstancesComponent>();
@@ -288,192 +157,6 @@ static void join_components(Span<const VolumeComponent *> src_components, Geomet
UNUSED_VARS(src_components, dst_component);
}
-/**
- * \note This takes advantage of the fact that creating attributes on joined curves never
- * changes a point attribute into a spline attribute; it is always the other way around.
- */
-static void ensure_control_point_attribute(const AttributeIDRef &attribute_id,
- const CustomDataType data_type,
- Span<CurveComponent *> src_components,
- CurveEval &result)
-{
- MutableSpan<SplinePtr> splines = result.splines();
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- /* In order to fill point attributes with spline domain attribute values where necessary, keep
- * track of the curve each spline came from while iterating over the splines in the result. */
- int src_component_index = 0;
- int spline_index_in_component = 0;
- const CurveEval *current_curve = src_components[src_component_index]->get_for_read();
-
- for (SplinePtr &spline : splines) {
- std::optional<GSpan> attribute = spline->attributes.get_for_read(attribute_id);
-
- if (attribute) {
- if (attribute->type() != type) {
- /* In this case, the attribute exists, but it has the wrong type. So create a buffer
- * for the converted values, do the conversion, and then replace the attribute. */
- void *converted_buffer = MEM_mallocN_aligned(
- spline->size() * type.size(), type.alignment(), __func__);
-
- const DataTypeConversions &conversions = blender::nodes::get_implicit_type_conversions();
- conversions.try_convert(GVArray::ForSpan(*attribute), type).materialize(converted_buffer);
-
- spline->attributes.remove(attribute_id);
- spline->attributes.create_by_move(attribute_id, data_type, converted_buffer);
- }
- }
- else {
- spline->attributes.create(attribute_id, data_type);
-
- if (current_curve->attributes.get_for_read(attribute_id)) {
- /* In this case the attribute did not exist, but there is a spline domain attribute
- * we can retrieve a value from, as a spline to point domain conversion. So fill the
- * new attribute with the value for this spline. */
- GVArray current_curve_attribute = current_curve->attributes.get_for_read(
- attribute_id, data_type, nullptr);
-
- BLI_assert(spline->attributes.get_for_read(attribute_id));
- std::optional<GMutableSpan> new_attribute = spline->attributes.get_for_write(attribute_id);
-
- BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
- current_curve_attribute.get(spline_index_in_component, buffer);
- type.fill_assign_n(buffer, new_attribute->data(), new_attribute->size());
- }
- }
-
- /* Move to the next spline and maybe the next input component. */
- spline_index_in_component++;
- if (spline != splines.last() && spline_index_in_component >= current_curve->splines().size()) {
- src_component_index++;
- spline_index_in_component = 0;
-
- current_curve = src_components[src_component_index]->get_for_read();
- }
- }
-}
-
-/**
- * Curve point domain attributes must be in the same order on every spline. The order might have
- * been different on separate instances, so ensure that all splines have the same order. Note that
- * because #Map is used, the order is not necessarily consistent every time, but it is the same for
- * every spline, and that's what matters.
- */
-static void sort_curve_point_attributes(const Map<AttributeIDRef, AttributeMetaData> &info,
- MutableSpan<SplinePtr> splines)
-{
- Vector<AttributeIDRef> new_order;
- for (Map<AttributeIDRef, AttributeMetaData>::Item item : info.items()) {
- if (item.value.domain == ATTR_DOMAIN_POINT) {
- /* Only sort attributes stored on splines. */
- new_order.append(item.key);
- }
- }
- for (SplinePtr &spline : splines) {
- spline->attributes.reorder(new_order);
- }
-}
-
-/**
- * Fill data for an attribute on the new curve based on all source curves.
- */
-static void ensure_spline_attribute(const AttributeIDRef &attribute_id,
- const CustomDataType data_type,
- Span<CurveComponent *> src_components,
- CurveEval &result)
-{
- const CPPType &type = *bke::custom_data_type_to_cpp_type(data_type);
-
- result.attributes.create(attribute_id, data_type);
- GMutableSpan result_attribute = *result.attributes.get_for_write(attribute_id);
-
- int offset = 0;
- for (const CurveComponent *component : src_components) {
- const CurveEval &curve = *component->get_for_read();
- const int size = curve.splines().size();
- if (size == 0) {
- continue;
- }
- GVArray read_attribute = curve.attributes.get_for_read(attribute_id, data_type, nullptr);
- GVArray_GSpan src_span{read_attribute};
-
- const void *src_buffer = src_span.data();
- type.copy_assign_n(src_buffer, result_attribute[offset], size);
-
- offset += size;
- }
-}
-
-/**
- * Special handling for copying spline attributes. This is necessary because we move the splines
- * out of the source components instead of copying them, meaning we can no longer access point
- * domain attributes on the source components.
- *
- * \warning Splines have been moved out of the source components at this point, so it
- * is important to only read curve-level data (spline domain attributes) from them.
- */
-static void join_curve_attributes(const Map<AttributeIDRef, AttributeMetaData> &info,
- Span<CurveComponent *> src_components,
- CurveEval &result)
-{
- for (const Map<AttributeIDRef, AttributeMetaData>::Item item : info.items()) {
- const AttributeIDRef attribute_id = item.key;
- const AttributeMetaData meta_data = item.value;
-
- if (meta_data.domain == ATTR_DOMAIN_CURVE) {
- ensure_spline_attribute(attribute_id, meta_data.data_type, src_components, result);
- }
- else {
- ensure_control_point_attribute(attribute_id, meta_data.data_type, src_components, result);
- }
- }
-
- sort_curve_point_attributes(info, result.splines());
-}
-
-static void join_curve_components(MutableSpan<GeometrySet> src_geometry_sets, GeometrySet &result)
-{
- Vector<CurveComponent *> src_components;
- for (GeometrySet &geometry_set : src_geometry_sets) {
- if (geometry_set.has_curve()) {
- /* Retrieving with write access seems counterintuitive, but it can allow avoiding a copy
- * in the case where the input spline has no other users, because the splines can be
- * moved from the source curve rather than copied from a read-only source. Retrieving
- * the curve for write will make a copy only when it has a user elsewhere. */
- CurveComponent &component = geometry_set.get_component_for_write<CurveComponent>();
- src_components.append(&component);
- }
- }
-
- if (src_components.size() == 0) {
- return;
- }
- if (src_components.size() == 1) {
- result.add(*src_components[0]);
- return;
- }
-
- /* Retrieve attribute info before moving the splines out of the input components. */
- const Map<AttributeIDRef, AttributeMetaData> info = get_final_attribute_info(
- {(const GeometryComponent **)src_components.data(), src_components.size()},
- {"position", "radius", "tilt", "handle_left", "handle_right", "cyclic", "resolution"});
-
- CurveComponent &dst_component = result.get_component_for_write<CurveComponent>();
- CurveEval *dst_curve = new CurveEval();
- for (CurveComponent *component : src_components) {
- CurveEval *src_curve = component->get_for_write();
- for (SplinePtr &spline : src_curve->splines()) {
- dst_curve->add_spline(std::move(spline));
- }
- }
- dst_curve->attributes.reallocate(dst_curve->splines().size());
-
- join_curve_attributes(info, src_components, *dst_curve);
- dst_curve->assert_valid_point_attributes();
-
- dst_component.replace(dst_curve);
-}
-
template<typename Component>
static void join_component_type(Span<GeometrySet> src_geometry_sets, GeometrySet &result)
{
@@ -492,10 +175,32 @@ static void join_component_type(Span<GeometrySet> src_geometry_sets, GeometrySet
result.add(*components[0]);
return;
}
- join_components(components, result);
+
+ GeometrySet instances_geometry_set;
+ InstancesComponent &instances =
+ instances_geometry_set.get_component_for_write<InstancesComponent>();
+
+ if constexpr (std::is_same_v<Component, InstancesComponent> ||
+ std::is_same_v<Component, VolumeComponent>) {
+ join_components(components, result);
+ }
+ else {
+ for (const Component *component : components) {
+ GeometrySet tmp_geo;
+ tmp_geo.add(*component);
+ const int handle = instances.add_reference(InstanceReference{tmp_geo});
+ instances.add_instance(handle, float4x4::identity());
+ }
+
+ geometry::RealizeInstancesOptions options;
+ options.keep_original_ids = true;
+ options.realize_instance_attributes = false;
+ GeometrySet joined_components = geometry::realize_instances(instances_geometry_set, options);
+ result.add(joined_components.get_component_for_write<Component>());
+ }
}
-static void geo_node_join_geometry_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Vector<GeometrySet> geometry_sets = params.extract_multi_input<GeometrySet>("Geometry");
@@ -504,18 +209,20 @@ static void geo_node_join_geometry_exec(GeoNodeExecParams params)
join_component_type<PointCloudComponent>(geometry_sets, geometry_set_result);
join_component_type<InstancesComponent>(geometry_sets, geometry_set_result);
join_component_type<VolumeComponent>(geometry_sets, geometry_set_result);
- join_curve_components(geometry_sets, geometry_set_result);
+ join_component_type<CurveComponent>(geometry_sets, geometry_set_result);
params.set_output("Geometry", std::move(geometry_set_result));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_join_geometry_cc
void register_node_type_geo_join_geometry()
{
+ namespace file_ns = blender::nodes::node_geo_join_geometry_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_JOIN_GEOMETRY, "Join Geometry", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_join_geometry_exec;
- ntype.declare = blender::nodes::geo_node_join_geometry_declare;
+ 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/node_geo_material_replace.cc b/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc
index e4a62bd5267..5a334126350 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc
@@ -24,9 +24,9 @@
#include "BKE_material.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_material_replace_cc {
-static void geo_node_material_replace_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Material>(N_("Old"));
@@ -34,7 +34,7 @@ static void geo_node_material_replace_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_material_replace_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Material *old_material = params.extract_input<Material *>("Old");
Material *new_material = params.extract_input<Material *>("New");
@@ -55,15 +55,17 @@ static void geo_node_material_replace_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_material_replace_cc
void register_node_type_geo_material_replace()
{
+ namespace file_ns = blender::nodes::node_geo_material_replace_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_REPLACE_MATERIAL, "Replace Material", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_material_replace_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_material_replace_exec;
+ 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/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
index 12ffa21762e..2aad68e7c25 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
@@ -26,9 +26,9 @@
#include "BKE_material.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_material_selection_cc {
-static void geo_node_material_selection_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Material>(N_("Material")).hide_label(true);
b.add_output<decl::Bool>(N_("Selection")).field_source();
@@ -54,45 +54,40 @@ static void select_mesh_by_material(const Mesh &mesh,
});
}
-class MaterialSelectionFieldInput final : public fn::FieldInput {
+class MaterialSelectionFieldInput final : public GeometryFieldInput {
Material *material_;
public:
MaterialSelectionFieldInput(Material *material)
- : fn::FieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
+ : GeometryFieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
{
category_ = Category::Generated;
}
- GVArray get_varray_for_context(const fn::FieldContext &context,
- IndexMask mask,
- ResourceScope &UNUSED(scope)) const final
+ GVArray get_varray_for_context(const GeometryComponent &component,
+ const AttributeDomain domain,
+ IndexMask mask) const final
{
- if (const GeometryComponentFieldContext *geometry_context =
- dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
- const GeometryComponent &component = geometry_context->geometry_component();
- const AttributeDomain domain = geometry_context->domain();
- if (component.type() != GEO_COMPONENT_TYPE_MESH) {
- return {};
- }
- const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
- const Mesh *mesh = mesh_component.get_for_read();
- if (mesh == nullptr) {
- return {};
- }
-
- if (domain == ATTR_DOMAIN_FACE) {
- Array<bool> selection(mask.min_array_size());
- select_mesh_by_material(*mesh, material_, mask, selection);
- return VArray<bool>::ForContainer(std::move(selection));
- }
-
- Array<bool> selection(mesh->totpoly);
- select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
- return mesh_component.attribute_try_adapt_domain<bool>(
- VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
+ if (component.type() != GEO_COMPONENT_TYPE_MESH) {
+ return {};
+ }
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return {};
+ }
+
+ if (domain == ATTR_DOMAIN_FACE) {
+ Array<bool> selection(mask.min_array_size());
+ select_mesh_by_material(*mesh, material_, mask, selection);
+ return VArray<bool>::ForContainer(std::move(selection));
}
+ Array<bool> selection(mesh->totpoly);
+ select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
+ return mesh_component.attribute_try_adapt_domain<bool>(
+ VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
+
return nullptr;
}
@@ -111,22 +106,24 @@ class MaterialSelectionFieldInput final : public fn::FieldInput {
}
};
-static void geo_node_material_selection_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
Field<bool> material_field{std::make_shared<MaterialSelectionFieldInput>(material)};
params.set_output("Selection", std::move(material_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_material_selection_cc
void register_node_type_geo_material_selection()
{
+ namespace file_ns = blender::nodes::node_geo_material_selection_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MATERIAL_SELECTION, "Material Selection", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_material_selection_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_material_selection_exec;
+ 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/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
index f1f95be107a..7a1cb8a62a3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc
@@ -25,9 +25,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_primitive_circle_cc {
-static void geo_node_mesh_primitive_circle_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryMeshCircle)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Vertices"))
.default_value(32)
@@ -41,16 +43,14 @@ static void geo_node_mesh_primitive_circle_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void geo_node_mesh_primitive_circle_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
}
-static void geo_node_mesh_primitive_circle_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryMeshCircle *node_storage = (NodeGeometryMeshCircle *)MEM_callocN(
sizeof(NodeGeometryMeshCircle), __func__);
@@ -199,42 +199,41 @@ static Mesh *create_circle_mesh(const float radius,
return mesh;
}
-static void geo_node_mesh_primitive_circle_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const bNode &node = params.node();
- const NodeGeometryMeshCircle &storage = *(const NodeGeometryMeshCircle *)node.storage;
-
- const GeometryNodeMeshCircleFillType fill_type = (const GeometryNodeMeshCircleFillType)
- storage.fill_type;
+ const NodeGeometryMeshCircle &storage = node_storage(params.node());
+ const GeometryNodeMeshCircleFillType fill = (GeometryNodeMeshCircleFillType)storage.fill_type;
const float radius = params.extract_input<float>("Radius");
const int verts_num = params.extract_input<int>("Vertices");
if (verts_num < 3) {
params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3"));
- params.set_output("Mesh", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
- Mesh *mesh = create_circle_mesh(radius, verts_num, fill_type);
+ Mesh *mesh = create_circle_mesh(radius, verts_num, fill);
BLI_assert(BKE_mesh_is_valid(mesh));
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_circle_cc
void register_node_type_geo_mesh_primitive_circle()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_circle_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MESH_PRIMITIVE_CIRCLE, "Mesh Circle", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_mesh_primitive_circle_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(
&ntype, "NodeGeometryMeshCircle", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_circle_exec;
- ntype.draw_buttons = blender::nodes::geo_node_mesh_primitive_circle_layout;
- ntype.declare = blender::nodes::geo_node_mesh_primitive_circle_declare;
+ 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/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
index fc93f6e72b5..70b093798f8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc
@@ -29,75 +29,6 @@
namespace blender::nodes {
-static void geo_node_mesh_primitive_cone_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Int>(N_("Vertices"))
- .default_value(32)
- .min(3)
- .max(512)
- .description(N_("Number of points on the circle at the top and bottom"));
- b.add_input<decl::Int>(N_("Side Segments"))
- .default_value(1)
- .min(1)
- .max(512)
- .description(N_("The number of edges running vertically along the side of the cone"));
- b.add_input<decl::Int>(N_("Fill Segments"))
- .default_value(1)
- .min(1)
- .max(512)
- .description(N_("Number of concentric rings used to fill the round face"));
- b.add_input<decl::Float>(N_("Radius Top"))
- .min(0.0f)
- .subtype(PROP_DISTANCE)
- .description(N_("Radius of the top circle of the cone"));
- b.add_input<decl::Float>(N_("Radius Bottom"))
- .default_value(1.0f)
- .min(0.0f)
- .subtype(PROP_DISTANCE)
- .description(N_("Radius of the bottom circle of the cone"));
- b.add_input<decl::Float>(N_("Depth"))
- .default_value(2.0f)
- .min(0.0f)
- .subtype(PROP_DISTANCE)
- .description(N_("Height of the generated cone"));
- b.add_output<decl::Geometry>(N_("Mesh"));
- b.add_output<decl::Bool>(N_("Top")).field_source();
- b.add_output<decl::Bool>(N_("Bottom")).field_source();
- b.add_output<decl::Bool>(N_("Side")).field_source();
-}
-
-static void geo_node_mesh_primitive_cone_init(bNodeTree *UNUSED(ntree), bNode *node)
-{
- NodeGeometryMeshCone *node_storage = (NodeGeometryMeshCone *)MEM_callocN(
- sizeof(NodeGeometryMeshCone), __func__);
-
- node_storage->fill_type = GEO_NODE_MESH_CIRCLE_FILL_NGON;
-
- node->storage = node_storage;
-}
-
-static void geo_node_mesh_primitive_cone_update(bNodeTree *ntree, bNode *node)
-{
- bNodeSocket *vertices_socket = (bNodeSocket *)node->inputs.first;
- bNodeSocket *rings_socket = vertices_socket->next;
- bNodeSocket *fill_subdiv_socket = rings_socket->next;
-
- const NodeGeometryMeshCone &storage = *(const NodeGeometryMeshCone *)node->storage;
- const GeometryNodeMeshCircleFillType fill_type =
- static_cast<const GeometryNodeMeshCircleFillType>(storage.fill_type);
- const bool has_fill = fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
- nodeSetSocketAvailability(ntree, fill_subdiv_socket, has_fill);
-}
-
-static void geo_node_mesh_primitive_cone_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
-{
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
- uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
-}
-
struct ConeConfig {
float radius_top;
float radius_bottom;
@@ -794,37 +725,103 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
return mesh;
}
-static void geo_node_mesh_primitive_cone_exec(GeoNodeExecParams params)
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_mesh_primitive_cone_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometryMeshCone)
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Int>(N_("Vertices"))
+ .default_value(32)
+ .min(3)
+ .max(512)
+ .description(N_("Number of points on the circle at the top and bottom"));
+ b.add_input<decl::Int>(N_("Side Segments"))
+ .default_value(1)
+ .min(1)
+ .max(512)
+ .description(N_("The number of edges running vertically along the side of the cone"));
+ b.add_input<decl::Int>(N_("Fill Segments"))
+ .default_value(1)
+ .min(1)
+ .max(512)
+ .description(N_("Number of concentric rings used to fill the round face"));
+ b.add_input<decl::Float>(N_("Radius Top"))
+ .min(0.0f)
+ .subtype(PROP_DISTANCE)
+ .description(N_("Radius of the top circle of the cone"));
+ b.add_input<decl::Float>(N_("Radius Bottom"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .subtype(PROP_DISTANCE)
+ .description(N_("Radius of the bottom circle of the cone"));
+ b.add_input<decl::Float>(N_("Depth"))
+ .default_value(2.0f)
+ .min(0.0f)
+ .subtype(PROP_DISTANCE)
+ .description(N_("Height of the generated cone"));
+ b.add_output<decl::Geometry>(N_("Mesh"));
+ b.add_output<decl::Bool>(N_("Top")).field_source();
+ b.add_output<decl::Bool>(N_("Bottom")).field_source();
+ b.add_output<decl::Bool>(N_("Side")).field_source();
+}
+
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
- const bNode &node = params.node();
- const NodeGeometryMeshCone &storage = *(const NodeGeometryMeshCone *)node.storage;
- const GeometryNodeMeshCircleFillType fill_type = (const GeometryNodeMeshCircleFillType)
- storage.fill_type;
-
- auto return_default = [&]() {
- params.set_output("Top", fn::make_constant_field<bool>(false));
- params.set_output("Bottom", fn::make_constant_field<bool>(false));
- params.set_output("Side", fn::make_constant_field<bool>(false));
- params.set_output("Mesh", GeometrySet());
- };
+ NodeGeometryMeshCone *node_storage = (NodeGeometryMeshCone *)MEM_callocN(
+ sizeof(NodeGeometryMeshCone), __func__);
+
+ node_storage->fill_type = GEO_NODE_MESH_CIRCLE_FILL_NGON;
+
+ node->storage = node_storage;
+}
+
+static void node_update(bNodeTree *ntree, bNode *node)
+{
+ bNodeSocket *vertices_socket = (bNodeSocket *)node->inputs.first;
+ bNodeSocket *rings_socket = vertices_socket->next;
+ bNodeSocket *fill_subdiv_socket = rings_socket->next;
+
+ const NodeGeometryMeshCone &storage = node_storage(*node);
+ const GeometryNodeMeshCircleFillType fill = (GeometryNodeMeshCircleFillType)storage.fill_type;
+ const bool has_fill = fill != GEO_NODE_MESH_CIRCLE_FILL_NONE;
+ nodeSetSocketAvailability(ntree, fill_subdiv_socket, has_fill);
+}
+
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+ uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ const NodeGeometryMeshCone &storage = node_storage(params.node());
+ const GeometryNodeMeshCircleFillType fill = (GeometryNodeMeshCircleFillType)storage.fill_type;
const int circle_segments = params.extract_input<int>("Vertices");
if (circle_segments < 3) {
params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
const int side_segments = params.extract_input<int>("Side Segments");
if (side_segments < 1) {
params.error_message_add(NodeWarningType::Info, TIP_("Side Segments must be at least 1"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
- const bool no_fill = fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE;
+ const bool no_fill = fill == GEO_NODE_MESH_CIRCLE_FILL_NONE;
const int fill_segments = no_fill ? 1 : params.extract_input<int>("Fill Segments");
if (fill_segments < 1) {
params.error_message_add(NodeWarningType::Info, TIP_("Fill Segments must be at least 1"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
const float radius_top = params.extract_input<float>("Radius Top");
@@ -848,7 +845,7 @@ static void geo_node_mesh_primitive_cone_exec(GeoNodeExecParams params)
circle_segments,
side_segments,
fill_segments,
- fill_type,
+ fill,
attribute_outputs);
/* Transform the mesh so that the base of the cone is at the origin. */
@@ -874,19 +871,21 @@ static void geo_node_mesh_primitive_cone_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_cone_cc
void register_node_type_geo_mesh_primitive_cone()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_cone_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CONE, "Cone", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_mesh_primitive_cone_init);
- node_type_update(&ntype, blender::nodes::geo_node_mesh_primitive_cone_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
node_type_storage(
&ntype, "NodeGeometryMeshCone", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_cone_exec;
- ntype.draw_buttons = blender::nodes::geo_node_mesh_primitive_cone_layout;
- ntype.declare = blender::nodes::geo_node_mesh_primitive_cone_declare;
+ 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/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
index b5903f7b71e..2542542c919 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
@@ -24,31 +24,6 @@
namespace blender::nodes {
-static void geo_node_mesh_primitive_cube_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Vector>(N_("Size"))
- .default_value(float3(1))
- .min(0.0f)
- .subtype(PROP_TRANSLATION)
- .description(N_("Side length along each axis"));
- b.add_input<decl::Int>(N_("Vertices X"))
- .default_value(2)
- .min(2)
- .max(1000)
- .description(N_("Number of vertices for the X side of the shape"));
- b.add_input<decl::Int>(N_("Vertices Y"))
- .default_value(2)
- .min(2)
- .max(1000)
- .description(N_("Number of vertices for the Y side of the shape"));
- b.add_input<decl::Int>(N_("Vertices Z"))
- .default_value(2)
- .min(2)
- .max(1000)
- .description(N_("Number of vertices for the Z side of the shape"));
- b.add_output<decl::Geometry>(N_("Mesh"));
-}
-
struct CuboidConfig {
float3 size;
int verts_x;
@@ -102,23 +77,37 @@ static void calculate_vertices(const CuboidConfig &config, MutableSpan<MVert> ve
int vert_index = 0;
- /* Though looping over all possible coordinates inside the cube only to skip them may be slow,
- * the alternative is similar complexity to below in the poly index calculation. If this loop
- * becomes a problem in the future it could be optimized, though only after proper performance
- * testing. */
for (const int z : IndexRange(config.verts_z)) {
- for (const int y : IndexRange(config.verts_y)) {
- for (const int x : IndexRange(config.verts_x)) {
- /* Only plot vertices on the surface of the cuboid. */
- if (ELEM(z, 0, config.edges_z) || ELEM(x, 0, config.edges_x) ||
- ELEM(y, 0, config.edges_y)) {
-
+ if (ELEM(z, 0, config.edges_z)) {
+ /* Fill bottom and top. */
+ const float z_pos = z_bottom + z_delta * z;
+ for (const int y : IndexRange(config.verts_y)) {
+ const float y_pos = y_front + y_delta * y;
+ for (const int x : IndexRange(config.verts_x)) {
const float x_pos = x_left + x_delta * x;
+ copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos));
+ }
+ }
+ }
+ else {
+ for (const int y : IndexRange(config.verts_y)) {
+ if (ELEM(y, 0, config.edges_y)) {
+ /* Fill y-sides. */
const float y_pos = y_front + y_delta * y;
const float z_pos = z_bottom + z_delta * z;
- copy_v3_v3(verts[vert_index].co, float3(x_pos, y_pos, z_pos));
-
- vert_index++;
+ for (const int x : IndexRange(config.verts_x)) {
+ const float x_pos = x_left + x_delta * x;
+ copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos));
+ }
+ }
+ else {
+ /* Fill x-sides. */
+ const float x_pos = x_left;
+ const float y_pos = y_front + y_delta * y;
+ const float z_pos = z_bottom + z_delta * z;
+ copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos));
+ const float x_pos2 = x_left + x_delta * config.edges_x;
+ copy_v3_v3(verts[vert_index++].co, float3(x_pos2, y_pos, z_pos));
}
}
}
@@ -439,6 +428,35 @@ Mesh *create_cuboid_mesh(const float3 size,
return mesh;
}
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_mesh_primitive_cube_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Vector>(N_("Size"))
+ .default_value(float3(1))
+ .min(0.0f)
+ .subtype(PROP_TRANSLATION)
+ .description(N_("Side length along each axis"));
+ b.add_input<decl::Int>(N_("Vertices X"))
+ .default_value(2)
+ .min(2)
+ .max(1000)
+ .description(N_("Number of vertices for the X side of the shape"));
+ b.add_input<decl::Int>(N_("Vertices Y"))
+ .default_value(2)
+ .min(2)
+ .max(1000)
+ .description(N_("Number of vertices for the Y side of the shape"));
+ b.add_input<decl::Int>(N_("Vertices Z"))
+ .default_value(2)
+ .min(2)
+ .max(1000)
+ .description(N_("Number of vertices for the Z side of the shape"));
+ b.add_output<decl::Geometry>(N_("Mesh"));
+}
+
static Mesh *create_cube_mesh(const float3 size,
const int verts_x,
const int verts_y,
@@ -484,7 +502,7 @@ static Mesh *create_cube_mesh(const float3 size,
return create_cuboid_mesh(size, verts_x, verts_y, verts_z);
}
-static void geo_node_mesh_primitive_cube_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const float3 size = params.extract_input<float3>("Size");
const int verts_x = params.extract_input<int>("Vertices X");
@@ -492,7 +510,7 @@ static void geo_node_mesh_primitive_cube_exec(GeoNodeExecParams params)
const int verts_z = params.extract_input<int>("Vertices Z");
if (verts_x < 1 || verts_y < 1 || verts_z < 1) {
params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 1"));
- params.set_output("Mesh", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -501,14 +519,16 @@ static void geo_node_mesh_primitive_cube_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_cube_cc
void register_node_type_geo_mesh_primitive_cube()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_cube_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CUBE, "Cube", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_primitive_cube_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_cube_exec;
+ 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/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
index a2ac46190b3..b8d2ed3be92 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc
@@ -25,9 +25,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_primitive_cylinder_cc {
-static void geo_node_mesh_primitive_cylinder_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryMeshCylinder)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Vertices"))
.default_value(32)
@@ -60,16 +62,14 @@ static void geo_node_mesh_primitive_cylinder_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Bool>(N_("Bottom")).field_source();
}
-static void geo_node_mesh_primitive_cylinder_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "fill_type", 0, nullptr, ICON_NONE);
}
-static void geo_node_mesh_primitive_cylinder_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryMeshCylinder *node_storage = (NodeGeometryMeshCylinder *)MEM_callocN(
sizeof(NodeGeometryMeshCylinder), __func__);
@@ -79,53 +79,45 @@ static void geo_node_mesh_primitive_cylinder_init(bNodeTree *UNUSED(ntree), bNod
node->storage = node_storage;
}
-static void geo_node_mesh_primitive_cylinder_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *vertices_socket = (bNodeSocket *)node->inputs.first;
bNodeSocket *rings_socket = vertices_socket->next;
bNodeSocket *fill_subdiv_socket = rings_socket->next;
- const NodeGeometryMeshCone &storage = *(const NodeGeometryMeshCone *)node->storage;
- const GeometryNodeMeshCircleFillType fill_type =
- static_cast<const GeometryNodeMeshCircleFillType>(storage.fill_type);
- const bool has_fill = fill_type != GEO_NODE_MESH_CIRCLE_FILL_NONE;
+ const NodeGeometryMeshCylinder &storage = node_storage(*node);
+ const GeometryNodeMeshCircleFillType fill = (GeometryNodeMeshCircleFillType)storage.fill_type;
+ const bool has_fill = fill != GEO_NODE_MESH_CIRCLE_FILL_NONE;
nodeSetSocketAvailability(ntree, fill_subdiv_socket, has_fill);
}
-static void geo_node_mesh_primitive_cylinder_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const bNode &node = params.node();
- const NodeGeometryMeshCylinder &storage = *(const NodeGeometryMeshCylinder *)node.storage;
-
- const GeometryNodeMeshCircleFillType fill_type = (const GeometryNodeMeshCircleFillType)
- storage.fill_type;
-
- auto return_default = [&]() {
- params.set_output("Top", fn::make_constant_field<bool>(false));
- params.set_output("Bottom", fn::make_constant_field<bool>(false));
- params.set_output("Side", fn::make_constant_field<bool>(false));
- params.set_output("Mesh", GeometrySet());
- };
+ const NodeGeometryMeshCylinder &storage = node_storage(params.node());
+ const GeometryNodeMeshCircleFillType fill = (GeometryNodeMeshCircleFillType)storage.fill_type;
const float radius = params.extract_input<float>("Radius");
const float depth = params.extract_input<float>("Depth");
const int circle_segments = params.extract_input<int>("Vertices");
if (circle_segments < 3) {
params.error_message_add(NodeWarningType::Info, TIP_("Vertices must be at least 3"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
const int side_segments = params.extract_input<int>("Side Segments");
if (side_segments < 1) {
params.error_message_add(NodeWarningType::Info, TIP_("Side Segments must be at least 1"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
- const bool no_fill = fill_type == GEO_NODE_MESH_CIRCLE_FILL_NONE;
+ const bool no_fill = fill == GEO_NODE_MESH_CIRCLE_FILL_NONE;
const int fill_segments = no_fill ? 1 : params.extract_input<int>("Fill Segments");
if (fill_segments < 1) {
params.error_message_add(NodeWarningType::Info, TIP_("Fill Segments must be at least 1"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
ConeAttributeOutputs attribute_outputs;
@@ -146,7 +138,7 @@ static void geo_node_mesh_primitive_cylinder_exec(GeoNodeExecParams params)
circle_segments,
side_segments,
fill_segments,
- fill_type,
+ fill,
attribute_outputs);
if (attribute_outputs.top_id) {
@@ -169,18 +161,20 @@ static void geo_node_mesh_primitive_cylinder_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_cylinder_cc
void register_node_type_geo_mesh_primitive_cylinder()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_cylinder_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_CYLINDER, "Cylinder", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_node_mesh_primitive_cylinder_init);
- node_type_update(&ntype, blender::nodes::geo_node_mesh_primitive_cylinder_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
node_type_storage(
&ntype, "NodeGeometryMeshCylinder", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_mesh_primitive_cylinder_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_cylinder_exec;
- ntype.draw_buttons = blender::nodes::geo_node_mesh_primitive_cylinder_layout;
+ 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/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
index 73c679e18f8..77634a03af6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc
@@ -27,31 +27,6 @@
namespace blender::nodes {
-static void geo_node_mesh_primitive_grid_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Float>(N_("Size X"))
- .default_value(1.0f)
- .min(0.0f)
- .subtype(PROP_DISTANCE)
- .description(N_("Side length of the plane in the X direction"));
- b.add_input<decl::Float>(N_("Size Y"))
- .default_value(1.0f)
- .min(0.0f)
- .subtype(PROP_DISTANCE)
- .description(N_("Side length of the plane in the Y direction"));
- b.add_input<decl::Int>(N_("Vertices X"))
- .default_value(3)
- .min(2)
- .max(1000)
- .description(N_("Number of vertices in the X direction"));
- b.add_input<decl::Int>(N_("Vertices Y"))
- .default_value(3)
- .min(2)
- .max(1000)
- .description(N_("Number of vertices in the Y direction"));
- b.add_output<decl::Geometry>(N_("Mesh"));
-}
-
static void calculate_uvs(
Mesh *mesh, Span<MVert> verts, Span<MLoop> loops, const float size_x, const float size_y)
{
@@ -169,14 +144,43 @@ Mesh *create_grid_mesh(const int verts_x,
return mesh;
}
-static void geo_node_mesh_primitive_grid_exec(GeoNodeExecParams params)
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_mesh_primitive_grid_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Float>(N_("Size X"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .subtype(PROP_DISTANCE)
+ .description(N_("Side length of the plane in the X direction"));
+ b.add_input<decl::Float>(N_("Size Y"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .subtype(PROP_DISTANCE)
+ .description(N_("Side length of the plane in the Y direction"));
+ b.add_input<decl::Int>(N_("Vertices X"))
+ .default_value(3)
+ .min(2)
+ .max(1000)
+ .description(N_("Number of vertices in the X direction"));
+ b.add_input<decl::Int>(N_("Vertices Y"))
+ .default_value(3)
+ .min(2)
+ .max(1000)
+ .description(N_("Number of vertices in the Y direction"));
+ b.add_output<decl::Geometry>(N_("Mesh"));
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
{
const float size_x = params.extract_input<float>("Size X");
const float size_y = params.extract_input<float>("Size Y");
const int verts_x = params.extract_input<int>("Vertices X");
const int verts_y = params.extract_input<int>("Vertices Y");
if (verts_x < 1 || verts_y < 1) {
- params.set_output("Mesh", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -187,14 +191,16 @@ static void geo_node_mesh_primitive_grid_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_grid_cc
void register_node_type_geo_mesh_primitive_grid()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_grid_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_GRID, "Grid", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_primitive_grid_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_grid_exec;
+ 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/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
index e4bf5e31dbf..5f483a95063 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
@@ -24,9 +24,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_primitive_ico_sphere_cc {
-static void geo_node_mesh_primitive_ico_sphere_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>(N_("Radius"))
.default_value(1.0f)
@@ -69,7 +69,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius)
return mesh;
}
-static void geo_node_mesh_primitive_ico_sphere_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const int subdivisions = std::min(params.extract_input<int>("Subdivisions"), 10);
const float radius = params.extract_input<float>("Radius");
@@ -78,15 +78,17 @@ static void geo_node_mesh_primitive_ico_sphere_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_ico_sphere_cc
void register_node_type_geo_mesh_primitive_ico_sphere()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_ico_sphere_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, "Ico Sphere", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_primitive_ico_sphere_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_ico_sphere_exec;
+ 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/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
index 1a92be1c05d..9a87c040bdf 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc
@@ -23,11 +23,15 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_primitive_line_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometryMeshLine)
-static void geo_node_mesh_primitive_line_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Count"))
.default_value(10)
@@ -51,9 +55,7 @@ static void geo_node_mesh_primitive_line_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void geo_node_mesh_primitive_line_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -63,7 +65,7 @@ static void geo_node_mesh_primitive_line_layout(uiLayout *layout,
}
}
-static void geo_node_mesh_primitive_line_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryMeshLine *node_storage = (NodeGeometryMeshLine *)MEM_callocN(
sizeof(NodeGeometryMeshLine), __func__);
@@ -74,16 +76,16 @@ static void geo_node_mesh_primitive_line_init(bNodeTree *UNUSED(ntree), bNode *n
node->storage = node_storage;
}
-static void geo_node_mesh_primitive_line_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *count_socket = (bNodeSocket *)node->inputs.first;
bNodeSocket *resolution_socket = count_socket->next;
bNodeSocket *start_socket = resolution_socket->next;
bNodeSocket *end_and_offset_socket = start_socket->next;
- const NodeGeometryMeshLine &storage = *(const NodeGeometryMeshLine *)node->storage;
- const GeometryNodeMeshLineMode mode = (const GeometryNodeMeshLineMode)storage.mode;
- const GeometryNodeMeshLineCountMode count_mode = (const GeometryNodeMeshLineCountMode)
+ const NodeGeometryMeshLine &storage = node_storage(*node);
+ const GeometryNodeMeshLineMode mode = (GeometryNodeMeshLineMode)storage.mode;
+ const GeometryNodeMeshLineCountMode count_mode = (GeometryNodeMeshLineCountMode)
storage.count_mode;
node_sock_label(end_and_offset_socket,
@@ -100,44 +102,48 @@ static void geo_node_mesh_primitive_line_update(bNodeTree *ntree, bNode *node)
count_mode == GEO_NODE_MESH_LINE_COUNT_TOTAL);
}
-static void fill_edge_data(MutableSpan<MEdge> edges)
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
{
- for (const int i : edges.index_range()) {
- edges[i].v1 = i;
- edges[i].v2 = i + 1;
- edges[i].flag |= ME_LOOSEEDGE;
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ if (params.in_out() == SOCK_OUT) {
+ search_link_ops_for_declarations(params, declaration.outputs());
+ return;
}
-}
-
-Mesh *create_line_mesh(const float3 start, const float3 delta, const int count)
-{
- if (count < 1) {
- return nullptr;
- }
-
- Mesh *mesh = BKE_mesh_new_nomain(count, count - 1, 0, 0, 0);
- BKE_id_material_eval_ensure_default_slot(&mesh->id);
- MutableSpan<MVert> verts{mesh->mvert, mesh->totvert};
- MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
-
- short normal[3];
- normal_float_to_short_v3(normal, delta.normalized());
-
- for (const int i : verts.index_range()) {
- copy_v3_v3(verts[i].co, start + delta * i);
- copy_v3_v3_short(verts[i].no, normal);
+ else if (params.node_tree().typeinfo->validate_link(
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ params.add_item(IFACE_("Count"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeMeshLine");
+ node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
+ params.connect_available_socket(node, "Count");
+ });
+ params.add_item(IFACE_("Resolution"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeMeshLine");
+ node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_OFFSET;
+ node_storage(node).count_mode = GEO_NODE_MESH_LINE_COUNT_RESOLUTION;
+ params.connect_available_socket(node, "Resolution");
+ });
+ params.add_item(IFACE_("Start Location"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeMeshLine");
+ params.connect_available_socket(node, "Start Location");
+ });
+ params.add_item(IFACE_("Offset"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeMeshLine");
+ params.connect_available_socket(node, "Offset");
+ });
+ /* The last socket is reused in end points mode. */
+ params.add_item(IFACE_("End Location"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeMeshLine");
+ node_storage(node).mode = GEO_NODE_MESH_LINE_MODE_END_POINTS;
+ params.connect_available_socket(node, "Offset");
+ });
}
-
- fill_edge_data(edges);
-
- return mesh;
}
-static void geo_node_mesh_primitive_line_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometryMeshLine &storage = *(const NodeGeometryMeshLine *)params.node().storage;
- const GeometryNodeMeshLineMode mode = (const GeometryNodeMeshLineMode)storage.mode;
- const GeometryNodeMeshLineCountMode count_mode = (const GeometryNodeMeshLineCountMode)
+ const NodeGeometryMeshLine &storage = node_storage(params.node());
+ const GeometryNodeMeshLineMode mode = (GeometryNodeMeshLineMode)storage.mode;
+ const GeometryNodeMeshLineCountMode count_mode = (GeometryNodeMeshLineCountMode)
storage.count_mode;
Mesh *mesh = nullptr;
@@ -174,19 +180,59 @@ static void geo_node_mesh_primitive_line_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
+} // namespace blender::nodes::node_geo_mesh_primitive_line_cc
+
+namespace blender::nodes {
+
+static void fill_edge_data(MutableSpan<MEdge> edges)
+{
+ for (const int i : edges.index_range()) {
+ edges[i].v1 = i;
+ edges[i].v2 = i + 1;
+ edges[i].flag |= ME_LOOSEEDGE;
+ }
+}
+
+Mesh *create_line_mesh(const float3 start, const float3 delta, const int count)
+{
+ if (count < 1) {
+ return nullptr;
+ }
+
+ Mesh *mesh = BKE_mesh_new_nomain(count, count - 1, 0, 0, 0);
+ BKE_id_material_eval_ensure_default_slot(&mesh->id);
+ MutableSpan<MVert> verts{mesh->mvert, mesh->totvert};
+ MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
+
+ short normal[3];
+ normal_float_to_short_v3(normal, delta.normalized());
+
+ for (const int i : verts.index_range()) {
+ copy_v3_v3(verts[i].co, start + delta * i);
+ copy_v3_v3_short(verts[i].no, normal);
+ }
+
+ fill_edge_data(edges);
+
+ return mesh;
+}
+
} // namespace blender::nodes
void register_node_type_geo_mesh_primitive_line()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_line_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_PRIMITIVE_LINE, "Mesh Line", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_primitive_line_declare;
- node_type_init(&ntype, blender::nodes::geo_node_mesh_primitive_line_init);
- node_type_update(&ntype, blender::nodes::geo_node_mesh_primitive_line_update);
+ 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, "NodeGeometryMeshLine", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_line_exec;
- ntype.draw_buttons = blender::nodes::geo_node_mesh_primitive_line_layout;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
index 3197a94c27b..ce2e0923a30 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc
@@ -25,9 +25,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_primitive_uv_sphere_cc {
-static void geo_node_mesh_primitive_uv_shpere_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Int>(N_("Segments"))
.default_value(32)
@@ -292,7 +292,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const
return mesh;
}
-static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
const int segments_num = params.extract_input<int>("Segments");
const int rings_num = params.extract_input<int>("Rings");
@@ -303,7 +303,7 @@ static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
if (rings_num < 3) {
params.error_message_add(NodeWarningType::Info, TIP_("Rings must be at least 3"));
}
- params.set_output("Mesh", GeometrySet());
+ params.set_default_remaining_outputs();
return;
}
@@ -313,15 +313,17 @@ static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_primitive_uv_sphere_cc
void register_node_type_geo_mesh_primitive_uv_sphere()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_primitive_uv_sphere_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_MESH_PRIMITIVE_UV_SPHERE, "UV Sphere", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_primitive_uv_shpere_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_primitive_uv_sphere_exec;
+ 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/node_geo_mesh_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc
index d99c0c851a8..1ec9808044f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc
@@ -23,9 +23,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_subdivide_cc {
-static void geo_node_mesh_subdivide_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Int>(N_("Level")).default_value(1).min(0).max(6);
@@ -72,14 +72,14 @@ static void geometry_set_mesh_subdivide(GeometrySet &geometry_set, const int lev
BKE_subdiv_free(subdiv);
}
-static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
#ifndef WITH_OPENSUBDIV
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenSubdiv"));
- params.set_output("Mesh", std::move(geometry_set));
+ params.set_default_remaining_outputs();
return;
#endif
@@ -97,14 +97,16 @@ static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_subdivide_cc
void register_node_type_geo_mesh_subdivide()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_subdivide_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SUBDIVIDE_MESH, "Subdivide Mesh", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_subdivide_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_subdivide_exec;
+ 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/node_geo_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
index 11865c635b8..90f0af75788 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
@@ -18,16 +18,16 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_to_curve_cc {
-static void geo_node_legacy_mesh_to_curve_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_legacy_mesh_to_curve_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
@@ -56,14 +56,16 @@ static void geo_node_legacy_mesh_to_curve_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_to_curve_cc
void register_node_type_geo_mesh_to_curve()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_to_curve_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_TO_CURVE, "Mesh to Curve", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_legacy_mesh_to_curve_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_legacy_mesh_to_curve_exec;
+ 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/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
index a37e3e34777..77314341fec 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
@@ -26,9 +26,11 @@
using blender::Array;
-namespace blender::nodes {
+namespace blender::nodes::node_geo_mesh_to_points_cc {
-static void geo_node_mesh_to_points_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryMeshToPoints)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
@@ -41,12 +43,12 @@ static void geo_node_mesh_to_points_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Points"));
}
-static void geo_node_mesh_to_points_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
-static void geo_node_mesh_to_points_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryMeshToPoints *data = (NodeGeometryMeshToPoints *)MEM_callocN(
sizeof(NodeGeometryMeshToPoints), __func__);
@@ -81,10 +83,15 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ /* Evaluating directly into the point cloud doesn't work because we are not using the full
+ * "min_array_size" array but compressing the selected elements into the final array with no
+ * gaps. */
+ evaluator.add(position_field);
+ evaluator.add(radius_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
uninitialized_fill_n(pointcloud->radius, pointcloud->totpoint, 0.05f);
@@ -92,13 +99,6 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
PointCloudComponent &point_component =
geometry_set.get_component_for_write<PointCloudComponent>();
- /* Evaluating directly into the point cloud doesn't work because we are not using the full
- * "min_array_size" array but compressing the selected elements into the final array with no
- * gaps. */
- fn::FieldEvaluator evaluator{field_context, &selection};
- evaluator.add(position_field);
- evaluator.add(radius_field);
- evaluator.evaluate();
copy_attribute_to_points(evaluator.get_evaluated<float3>(0),
selection,
{(float3 *)pointcloud->co, pointcloud->totpoint});
@@ -129,7 +129,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_INSTANCES});
}
-static void geo_node_mesh_to_points_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
Field<float3> position = params.extract_input<Field<float3>>("Position");
@@ -144,8 +144,7 @@ static void geo_node_mesh_to_points_exec(GeoNodeExecParams params)
FieldOperation(max_zero_fn, {std::move(radius)}));
Field<float> positive_radius(std::move(max_zero_op), 0);
- const NodeGeometryMeshToPoints &storage =
- *(const NodeGeometryMeshToPoints *)params.node().storage;
+ const NodeGeometryMeshToPoints &storage = node_storage(params.node());
const GeometryNodeMeshToPointsMode mode = (GeometryNodeMeshToPointsMode)storage.mode;
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
@@ -172,17 +171,19 @@ static void geo_node_mesh_to_points_exec(GeoNodeExecParams params)
params.set_output("Points", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_mesh_to_points_cc
void register_node_type_geo_mesh_to_points()
{
+ namespace file_ns = blender::nodes::node_geo_mesh_to_points_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_MESH_TO_POINTS, "Mesh to Points", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_mesh_to_points_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_mesh_to_points_exec;
- node_type_init(&ntype, blender::nodes::geo_node_mesh_to_points_init);
- ntype.draw_buttons = blender::nodes::geo_node_mesh_to_points_layout;
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ node_type_init(&ntype, file_ns::node_init);
+ ntype.draw_buttons = file_ns::node_layout;
node_type_storage(
&ntype, "NodeGeometryMeshToPoints", node_free_standard_storage, node_copy_standard_storage);
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
index bb8e5f7e29b..38c3b9cbcd9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -21,9 +21,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_object_info_cc {
-static void geo_node_object_info_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryObjectInfo)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Object>(N_("Object")).hide_label();
b.add_input<decl::Bool>(N_("As Instance"))
@@ -35,31 +37,22 @@ static void geo_node_object_info_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_object_info_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_object_info_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const bNode &bnode = params.node();
- NodeGeometryObjectInfo *node_storage = (NodeGeometryObjectInfo *)bnode.storage;
- const bool transform_space_relative = (node_storage->transform_space ==
+ const NodeGeometryObjectInfo &storage = node_storage(params.node());
+ const bool transform_space_relative = (storage.transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
- auto default_transform = [&]() {
- params.set_output("Location", float3(0));
- params.set_output("Rotation", float3(0));
- params.set_output("Scale", float3(0));
- };
- auto default_geometry = [&]() { params.set_output("Geometry", GeometrySet()); };
-
Object *object = params.get_input<Object *>("Object");
const Object *self_object = params.self_object();
if (object == nullptr) {
- default_transform();
- default_geometry();
+ params.set_default_remaining_outputs();
return;
}
@@ -81,7 +74,7 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
if (object == self_object) {
params.error_message_add(NodeWarningType::Error,
TIP_("Geometry cannot be retrieved from the modifier object"));
- default_geometry();
+ params.set_default_remaining_outputs();
return;
}
@@ -107,7 +100,7 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
}
}
-static void geo_node_object_info_node_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryObjectInfo *data = (NodeGeometryObjectInfo *)MEM_callocN(
sizeof(NodeGeometryObjectInfo), __func__);
@@ -115,18 +108,20 @@ static void geo_node_object_info_node_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_object_info_cc
void register_node_type_geo_object_info()
{
+ namespace file_ns = blender::nodes::node_geo_object_info_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_OBJECT_INFO, "Object Info", NODE_CLASS_INPUT, 0);
- node_type_init(&ntype, blender::nodes::geo_node_object_info_node_init);
+ node_type_init(&ntype, file_ns::node_node_init);
node_type_storage(
&ntype, "NodeGeometryObjectInfo", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = blender::nodes::geo_node_object_info_exec;
- ntype.draw_buttons = blender::nodes::geo_node_object_info_layout;
- ntype.declare = blender::nodes::geo_node_object_info_declare;
+ 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/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
index 5a6a3b25a45..5510773eabd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
@@ -21,11 +21,11 @@
#include "node_geometry_util.hh"
-using blender::Array;
+namespace blender::nodes::node_geo_points_to_vertices_cc {
-namespace blender::nodes {
+using blender::Array;
-static void geo_node_points_to_vertices_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Points")).supported_type(GEO_COMPONENT_TYPE_POINT_CLOUD);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
@@ -92,7 +92,7 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
}
-static void geo_node_points_to_vertices_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -104,15 +104,17 @@ static void geo_node_points_to_vertices_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_points_to_vertices_cc
void register_node_type_geo_points_to_vertices()
{
+ namespace file_ns = blender::nodes::node_geo_points_to_vertices_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_POINTS_TO_VERTICES, "Points to Vertices", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_points_to_vertices_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_points_to_vertices_exec;
+ 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/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
index 31c16cb95e0..744cce6d445 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
@@ -28,14 +28,27 @@
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_points_to_volume_cc {
-static void geo_node_points_to_volume_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryPointsToVolume)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Points"));
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::Float>(N_("Voxel Size"))
+ .default_value(0.3f)
+ .min(0.01f)
+ .subtype(PROP_DISTANCE)
+ .make_available([](bNode &node) {
+ node_storage(node).resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE;
+ });
+ b.add_input<decl::Float>(N_("Voxel Amount"))
+ .default_value(64.0f)
+ .min(0.0f)
+ .make_available([](bNode &node) {
+ node_storage(node).resolution_mode = GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT;
+ });
b.add_input<decl::Float>(N_("Radius"))
.default_value(0.5f)
.min(0.0f)
@@ -44,16 +57,14 @@ static void geo_node_points_to_volume_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Volume"));
}
-static void geo_node_points_to_volume_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+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 geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)MEM_callocN(
sizeof(NodeGeometryPointsToVolume), __func__);
@@ -61,18 +72,18 @@ static void geo_node_points_to_volume_init(bNodeTree *UNUSED(ntree), bNode *node
node->storage = data;
}
-static void geo_node_points_to_volume_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryPointsToVolume *data = (NodeGeometryPointsToVolume *)node->storage;
+ const NodeGeometryPointsToVolume &storage = node_storage(*node);
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 ==
+ storage.resolution_mode ==
GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_AMOUNT);
nodeSetSocketAvailability(ntree,
voxel_size_socket,
- data->resolution_mode ==
+ storage.resolution_mode ==
GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE);
}
@@ -136,8 +147,7 @@ static float compute_voxel_size(const GeoNodeExecParams &params,
Span<float3> positions,
const float radius)
{
- const NodeGeometryPointsToVolume &storage =
- *(const NodeGeometryPointsToVolume *)params.node().storage;
+ const NodeGeometryPointsToVolume &storage = node_storage(params.node());
if (storage.resolution_mode == GEO_NODE_POINTS_TO_VOLUME_RESOLUTION_MODE_SIZE) {
return params.get_input<float>("Voxel Size");
@@ -236,7 +246,7 @@ static void initialize_volume_component_from_points(GeoNodeExecParams &params,
}
#endif
-static void geo_node_points_to_volume_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
@@ -248,14 +258,16 @@ static void geo_node_points_to_volume_exec(GeoNodeExecParams params)
#else
params.error_message_add(NodeWarningType::Error,
TIP_("Disabled, Blender was compiled without OpenVDB"));
- params.set_output("Volume", GeometrySet());
+ params.set_default_remaining_outputs();
#endif
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_points_to_volume_cc
void register_node_type_geo_points_to_volume()
{
+ namespace file_ns = blender::nodes::node_geo_points_to_volume_cc;
+
static bNodeType ntype;
geo_node_type_base(
@@ -265,10 +277,10 @@ void register_node_type_geo_points_to_volume()
node_free_standard_storage,
node_copy_standard_storage);
node_type_size(&ntype, 170, 120, 700);
- node_type_init(&ntype, blender::nodes::geo_node_points_to_volume_init);
- node_type_update(&ntype, blender::nodes::geo_node_points_to_volume_update);
- ntype.declare = blender::nodes::geo_node_points_to_volume_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_points_to_volume_exec;
- ntype.draw_buttons = blender::nodes::geo_node_points_to_volume_layout;
+ 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/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc
index c05476b982b..aa3383e68be 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc
@@ -27,9 +27,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_proximity_cc {
-static void geo_node_proximity_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryProximity)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Target"))
.only_realized_data()
@@ -39,7 +41,7 @@ static void geo_node_proximity_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Float>(N_("Distance")).dependent_field();
}
-static void geo_node_proximity_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "target_element", 0, "", ICON_NONE);
}
@@ -206,21 +208,17 @@ class ProximityFunction : public fn::MultiFunction {
}
};
-static void geo_node_proximity_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set_target = params.extract_input<GeometrySet>("Target");
geometry_set_target.ensure_owns_direct_data();
- auto return_default = [&]() {
- params.set_output("Position", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
- params.set_output("Distance", fn::make_constant_field<float>(0.0f));
- };
-
if (!geometry_set_target.has_mesh() && !geometry_set_target.has_pointcloud()) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
- const NodeGeometryProximity &storage = *(const NodeGeometryProximity *)params.node().storage;
+ const NodeGeometryProximity &storage = node_storage(params.node());
Field<float3> position_field = params.extract_input<Field<float3>>("Source Position");
auto proximity_fn = std::make_unique<ProximityFunction>(
@@ -233,18 +231,20 @@ static void geo_node_proximity_exec(GeoNodeExecParams params)
params.set_output("Distance", Field<float>(proximity_op, 1));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_proximity_cc
void register_node_type_geo_proximity()
{
+ namespace file_ns = blender::nodes::node_geo_proximity_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_PROXIMITY, "Geometry Proximity", NODE_CLASS_GEOMETRY, 0);
- node_type_init(&ntype, blender::nodes::geo_proximity_init);
+ node_type_init(&ntype, file_ns::geo_proximity_init);
node_type_storage(
&ntype, "NodeGeometryProximity", node_free_standard_storage, node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_proximity_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_proximity_exec;
- ntype.draw_buttons = blender::nodes::geo_node_proximity_layout;
+ 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/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
index d422bf5a00a..d255fe482f6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc
@@ -23,13 +23,17 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
+namespace blender::nodes::node_geo_raycast_cc {
+
using namespace blender::bke::mesh_surface_sample;
-namespace blender::nodes {
+NODE_STORAGE_FUNCS(NodeGeometryRaycast)
-static void geo_node_raycast_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Target Geometry"))
.only_realized_data()
@@ -63,13 +67,13 @@ static void geo_node_raycast_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").dependent_field({1, 2, 3, 4, 5, 6});
}
-static void geo_node_raycast_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "mapping", 0, "", ICON_NONE);
}
-static void geo_node_raycast_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryRaycast *data = (NodeGeometryRaycast *)MEM_callocN(sizeof(NodeGeometryRaycast),
__func__);
@@ -78,10 +82,10 @@ static void geo_node_raycast_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_raycast_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryRaycast &data = *(const NodeGeometryRaycast *)node->storage;
- const CustomDataType data_type = static_cast<CustomDataType>(data.data_type);
+ const NodeGeometryRaycast &storage = node_storage(*node);
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
bNodeSocket *socket_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
bNodeSocket *socket_float = socket_vector->next;
@@ -108,6 +112,25 @@ static void geo_node_raycast_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
}
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+ search_link_ops_for_declarations(params, declaration.inputs().take_back(3));
+ search_link_ops_for_declarations(params, declaration.outputs().take_front(4));
+
+ const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ (eNodeSocketDatatype)params.other_socket().type);
+ if (type && *type != CD_PROP_STRING) {
+ /* The input and output sockets have the same name. */
+ params.add_item(IFACE_("Attribute"), [type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeRaycast");
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Attribute");
+ });
+ }
+}
+
static eAttributeMapMode get_map_mode(GeometryNodeRaycastMapMode map_mode)
{
switch (map_mode) {
@@ -205,10 +228,10 @@ class RaycastFunction : public fn::MultiFunction {
std::unique_ptr<FieldEvaluator> target_evaluator_;
const GVArray *target_data_ = nullptr;
- /* Always evaluate the target domain data on the point domain. Eventually this could be
- * exposed as an option or determined automatically from the field inputs in order to avoid
- * losing information if the target field is on a different domain. */
- const AttributeDomain domain_ = ATTR_DOMAIN_POINT;
+ /* Always evaluate the target domain data on the face corner domain because it contains the most
+ * information. Eventually this could be exposed as an option or determined automatically from
+ * the field inputs for better performance. */
+ const AttributeDomain domain_ = ATTR_DOMAIN_CORNER;
fn::MFSignature signature_;
@@ -375,35 +398,27 @@ static void output_attribute_field(GeoNodeExecParams &params, GField field)
}
}
-static void geo_node_raycast_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet target = params.extract_input<GeometrySet>("Target Geometry");
- const NodeGeometryRaycast &data = *(const NodeGeometryRaycast *)params.node().storage;
- const GeometryNodeRaycastMapMode mapping = static_cast<GeometryNodeRaycastMapMode>(data.mapping);
- const CustomDataType data_type = static_cast<CustomDataType>(data.data_type);
-
- auto return_default = [&]() {
- params.set_output("Is Hit", fn::make_constant_field<bool>(false));
- params.set_output("Hit Position", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
- params.set_output("Hit Normal", fn::make_constant_field<float3>({0.0f, 0.0f, 0.0f}));
- params.set_output("Hit Distance", fn::make_constant_field<float>(0.0f));
- attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
- using T = decltype(dummy);
- output_attribute_field(params, fn::make_constant_field<T>(T()));
- });
- };
+ const NodeGeometryRaycast &storage = node_storage(params.node());
+ const GeometryNodeRaycastMapMode mapping = (GeometryNodeRaycastMapMode)storage.mapping;
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
if (target.is_empty()) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
if (!target.has_mesh()) {
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
if (target.get_mesh_for_read()->totpoly == 0) {
params.error_message_add(NodeWarningType::Error, TIP_("The target mesh must have faces"));
- return return_default();
+ params.set_default_remaining_outputs();
+ return;
}
GField field = get_input_attribute_field(params, data_type);
@@ -426,20 +441,23 @@ static void geo_node_raycast_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_raycast_cc
void register_node_type_geo_raycast()
{
+ namespace file_ns = blender::nodes::node_geo_raycast_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_RAYCAST, "Raycast", NODE_CLASS_GEOMETRY, 0);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, blender::nodes::geo_node_raycast_init);
- node_type_update(&ntype, blender::nodes::geo_node_raycast_update);
+ 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 = blender::nodes::geo_node_raycast_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_raycast_exec;
- ntype.draw_buttons = blender::nodes::geo_node_raycast_layout;
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc
index 6c51c1f738f..fad35389823 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc
@@ -16,33 +16,48 @@
#include "node_geometry_util.hh"
+#include "GEO_realize_instances.hh"
+
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_realize_instances_cc {
-static void geo_node_realize_instances_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Geometry>(N_("Geometry"));
}
-static void geo_node_realize_instances_exec(GeoNodeExecParams params)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "legacy_behavior", 0, nullptr, ICON_NONE);
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
{
+ const bool legacy_behavior = params.node().custom1 & GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR;
+
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
- geometry_set = bke::geometry_set_realize_instances(geometry_set);
+ geometry::RealizeInstancesOptions options;
+ options.keep_original_ids = legacy_behavior;
+ options.realize_instance_attributes = !legacy_behavior;
+ geometry_set = geometry::realize_instances(geometry_set, options);
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_realize_instances_cc
void register_node_type_geo_realize_instances()
{
+ namespace file_ns = blender::nodes::node_geo_realize_instances_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_REALIZE_INSTANCES, "Realize Instances", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_realize_instances_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_realize_instances_exec;
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons_ex = file_ns::node_layout;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
index c53eaa2ded9..335484c62b0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc
@@ -18,9 +18,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_rotate_instances_cc {
-static void geo_node_rotate_instances_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Instances")).only_instances();
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -35,19 +35,17 @@ static void rotate_instances(GeoNodeExecParams &params, InstancesComponent &inst
GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE};
const int domain_size = instances_component.instances_amount();
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(params.extract_input<Field<bool>>("Selection"));
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
+ evaluator.add(params.extract_input<Field<float3>>("Rotation"));
+ evaluator.add(params.extract_input<Field<float3>>("Pivot Point"));
+ evaluator.add(params.extract_input<Field<bool>>("Local Space"));
+ evaluator.evaluate();
- fn::FieldEvaluator transforms_evaluator{field_context, &selection};
- transforms_evaluator.add(params.extract_input<Field<float3>>("Rotation"));
- transforms_evaluator.add(params.extract_input<Field<float3>>("Pivot Point"));
- transforms_evaluator.add(params.extract_input<Field<bool>>("Local Space"));
- transforms_evaluator.evaluate();
- const VArray<float3> &rotations = transforms_evaluator.get_evaluated<float3>(0);
- const VArray<float3> &pivots = transforms_evaluator.get_evaluated<float3>(1);
- const VArray<bool> &local_spaces = transforms_evaluator.get_evaluated<bool>(2);
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ const VArray<float3> &rotations = evaluator.get_evaluated<float3>(0);
+ const VArray<float3> &pivots = evaluator.get_evaluated<float3>(1);
+ const VArray<bool> &local_spaces = evaluator.get_evaluated<bool>(2);
MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
@@ -96,7 +94,7 @@ static void rotate_instances(GeoNodeExecParams &params, InstancesComponent &inst
});
}
-static void geo_node_rotate_instances_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
if (geometry_set.has_instances()) {
@@ -106,15 +104,17 @@ static void geo_node_rotate_instances_exec(GeoNodeExecParams params)
params.set_output("Instances", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_rotate_instances_cc
void register_node_type_geo_rotate_instances()
{
+ namespace file_ns = blender::nodes::node_geo_rotate_instances_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_ROTATE_INSTANCES, "Rotate Instances", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_rotate_instances_exec;
- ntype.declare = blender::nodes::geo_node_rotate_instances_declare;
+ 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/node_geo_scale_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
index fa2501515a9..1779ac8bff7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
@@ -18,9 +18,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_scale_instances_cc {
-static void geo_node_scale_instances_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Instances")).only_instances();
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -37,19 +37,17 @@ static void scale_instances(GeoNodeExecParams &params, InstancesComponent &insta
{
GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE};
- fn::FieldEvaluator selection_evaluator{field_context, instances_component.instances_amount()};
- selection_evaluator.add(params.extract_input<Field<bool>>("Selection"));
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, instances_component.instances_amount()};
+ evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
+ evaluator.add(params.extract_input<Field<float3>>("Scale"));
+ evaluator.add(params.extract_input<Field<float3>>("Center"));
+ evaluator.add(params.extract_input<Field<bool>>("Local Space"));
+ evaluator.evaluate();
- fn::FieldEvaluator transforms_evaluator{field_context, &selection};
- transforms_evaluator.add(params.extract_input<Field<float3>>("Scale"));
- transforms_evaluator.add(params.extract_input<Field<float3>>("Center"));
- transforms_evaluator.add(params.extract_input<Field<bool>>("Local Space"));
- transforms_evaluator.evaluate();
- const VArray<float3> &scales = transforms_evaluator.get_evaluated<float3>(0);
- const VArray<float3> &pivots = transforms_evaluator.get_evaluated<float3>(1);
- const VArray<bool> &local_spaces = transforms_evaluator.get_evaluated<bool>(2);
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ const VArray<float3> &scales = evaluator.get_evaluated<float3>(0);
+ const VArray<float3> &pivots = evaluator.get_evaluated<float3>(1);
+ const VArray<bool> &local_spaces = evaluator.get_evaluated<bool>(2);
MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
@@ -75,7 +73,7 @@ static void scale_instances(GeoNodeExecParams &params, InstancesComponent &insta
});
}
-static void geo_node_scale_instances_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
if (geometry_set.has_instances()) {
@@ -85,14 +83,16 @@ static void geo_node_scale_instances_exec(GeoNodeExecParams params)
params.set_output("Instances", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_scale_instances_cc
void register_node_type_geo_scale_instances()
{
+ namespace file_ns = blender::nodes::node_geo_scale_instances_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SCALE_INSTANCES, "Scale Instances", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_scale_instances_exec;
- ntype.declare = blender::nodes::geo_node_scale_instances_declare;
+ 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/node_geo_separate_components.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc
index a16fb712b13..e4adfe6587d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_separate_components_cc {
-static void geo_node_join_geometry_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_output<decl::Geometry>(N_("Mesh"));
@@ -28,7 +28,7 @@ static void geo_node_join_geometry_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Instances"));
}
-static void geo_node_separate_components_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -61,15 +61,17 @@ static void geo_node_separate_components_exec(GeoNodeExecParams params)
params.set_output("Instances", instances);
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_separate_components_cc
void register_node_type_geo_separate_components()
{
+ namespace file_ns = blender::nodes::node_geo_separate_components_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SEPARATE_COMPONENTS, "Separate Components", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_join_geometry_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_separate_components_exec;
+ 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/node_geo_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
index 28e214c0ccc..7f1cc1be421 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc
@@ -19,9 +19,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_separate_geometry_cc {
-static void geo_node_separate_geometry_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometrySeparateGeometry)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Bool>(N_("Selection"))
@@ -35,14 +37,12 @@ static void geo_node_separate_geometry_declare(NodeDeclarationBuilder &b)
.description(N_("The parts of the geometry not in the selection"));
}
-static void geo_node_separate_geometry_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
}
-static void geo_node_separate_geometry_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometrySeparateGeometry *data = (NodeGeometrySeparateGeometry *)MEM_callocN(
sizeof(NodeGeometrySeparateGeometry), __func__);
@@ -51,14 +51,13 @@ static void geo_node_separate_geometry_init(bNodeTree *UNUSED(tree), bNode *node
node->storage = data;
}
-static void geo_node_separate_geometry_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
- const bNode &node = params.node();
- const NodeGeometryDeleteGeometry &storage = *(const NodeGeometryDeleteGeometry *)node.storage;
+ const NodeGeometrySeparateGeometry &storage = node_storage(params.node());
const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
bool all_is_error = false;
@@ -95,10 +94,12 @@ static void geo_node_separate_geometry_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_separate_geometry_cc
void register_node_type_geo_separate_geometry()
{
+ namespace file_ns = blender::nodes::node_geo_separate_geometry_cc;
+
static bNodeType ntype;
geo_node_type_base(
@@ -109,10 +110,10 @@ void register_node_type_geo_separate_geometry()
node_free_standard_storage,
node_copy_standard_storage);
- node_type_init(&ntype, blender::nodes::geo_node_separate_geometry_init);
+ node_type_init(&ntype, file_ns::node_init);
- ntype.declare = blender::nodes::geo_node_separate_geometry_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_separate_geometry_exec;
- ntype.draw_buttons = blender::nodes::geo_node_separate_geometry_layout;
+ 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/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
index 30b445da58c..f98b4116526 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
@@ -21,9 +21,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_curve_handles_cc {
-static void geo_node_set_curve_handles_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometrySetCurveHandlePositions)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -32,14 +34,12 @@ static void geo_node_set_curve_handles_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curve"));
}
-static void geo_node_set_curve_handles_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
}
-static void geo_node_set_curve_handles_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometrySetCurveHandlePositions *data = (NodeGeometrySetCurveHandlePositions *)MEM_callocN(
sizeof(NodeGeometrySetCurveHandlePositions), __func__);
@@ -60,10 +60,12 @@ static void set_position_in_component(const GeometryNodeCurveHandleMode mode,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add(position_field);
+ evaluator.add(offset_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
CurveComponent *curve_component = static_cast<CurveComponent *>(&component);
CurveEval *curve = curve_component->get_for_write();
@@ -77,7 +79,7 @@ static void set_position_in_component(const GeometryNodeCurveHandleMode mode,
if (spline->type() == Spline::Type::Bezier) {
BezierSpline &bezier = static_cast<BezierSpline &>(*spline);
for (int i : bezier.positions().index_range()) {
- if (selection[current_mask] == current_point) {
+ if (current_mask < selection.size() && selection[current_mask] == current_point) {
if (mode & GEO_NODE_CURVE_HANDLE_LEFT) {
if (bezier.handle_types_left()[i] == BezierSpline::HandleType::Vector) {
bezier.ensure_auto_handles();
@@ -105,7 +107,7 @@ static void set_position_in_component(const GeometryNodeCurveHandleMode mode,
}
else {
for (int UNUSED(i) : spline->positions().index_range()) {
- if (selection[current_mask] == current_point) {
+ if (current_mask < selection.size() && selection[current_mask] == current_point) {
current_mask++;
}
current_point++;
@@ -113,13 +115,8 @@ static void set_position_in_component(const GeometryNodeCurveHandleMode mode,
}
}
- fn::FieldEvaluator position_evaluator{field_context, &selection};
- position_evaluator.add(position_field);
- position_evaluator.add(offset_field);
- position_evaluator.evaluate();
-
- const VArray<float3> &positions_input = position_evaluator.get_evaluated<float3>(0);
- const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1);
+ const VArray<float3> &positions_input = evaluator.get_evaluated<float3>(0);
+ const VArray<float3> &offsets_input = evaluator.get_evaluated<float3>(1);
OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
side, ATTR_DOMAIN_POINT, {0, 0, 0});
@@ -132,11 +129,10 @@ static void set_position_in_component(const GeometryNodeCurveHandleMode mode,
positions.save();
}
-static void geo_node_set_curve_handles_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeGeometrySetCurveHandlePositions *node_storage =
- (NodeGeometrySetCurveHandlePositions *)params.node().storage;
- const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)node_storage->mode;
+ const NodeGeometrySetCurveHandlePositions &storage = node_storage(params.node());
+ const GeometryNodeCurveHandleMode mode = (GeometryNodeCurveHandleMode)storage.mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -162,22 +158,24 @@ static void geo_node_set_curve_handles_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_curve_handles_cc
void register_node_type_geo_set_curve_handles()
{
+ namespace file_ns = blender::nodes::node_geo_set_curve_handles_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_CURVE_HANDLES, "Set Handle Positions", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_curve_handles_exec;
- ntype.declare = blender::nodes::geo_node_set_curve_handles_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.declare = file_ns::node_declare;
ntype.minwidth = 100.0f;
- node_type_init(&ntype, blender::nodes::geo_node_set_curve_handles_init);
+ node_type_init(&ntype, file_ns::node_init);
node_type_storage(&ntype,
"NodeGeometrySetCurveHandlePositions",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.draw_buttons = blender::nodes::geo_node_set_curve_handles_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
index e47ce7dea30..7d99f42c487 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_curve_radius_cc {
-static void geo_node_set_curve_radius_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -40,20 +40,18 @@ static void set_radius_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
"radius", ATTR_DOMAIN_POINT);
- fn::FieldEvaluator radii_evaluator{field_context, &selection};
- radii_evaluator.add_with_destination(radius_field, radii.varray());
- radii_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(radius_field, radii.varray());
+ evaluator.evaluate();
+
radii.save();
}
-static void geo_node_set_curve_radius_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -69,15 +67,17 @@ static void geo_node_set_curve_radius_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_curve_radius_cc
void register_node_type_geo_set_curve_radius()
{
+ namespace file_ns = blender::nodes::node_geo_set_curve_radius_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_CURVE_RADIUS, "Set Curve Radius", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_curve_radius_exec;
- ntype.declare = blender::nodes::geo_node_set_curve_radius_declare;
+ 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/node_geo_set_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
index a861c35f738..447310e1ad7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_curve_tilt_cc {
-static void geo_node_set_curve_tilt_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -36,20 +36,18 @@ static void set_tilt_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<float> tilts = component.attribute_try_get_for_output_only<float>(
"tilt", ATTR_DOMAIN_POINT);
- fn::FieldEvaluator tilt_evaluator{field_context, &selection};
- tilt_evaluator.add_with_destination(tilt_field, tilts.varray());
- tilt_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(tilt_field, tilts.varray());
+ evaluator.evaluate();
+
tilts.save();
}
-static void geo_node_set_curve_tilt_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -65,14 +63,16 @@ static void geo_node_set_curve_tilt_exec(GeoNodeExecParams params)
params.set_output("Curve", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_curve_tilt_cc
void register_node_type_geo_set_curve_tilt()
{
+ namespace file_ns = blender::nodes::node_geo_set_curve_tilt_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SET_CURVE_TILT, "Set Curve Tilt", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_curve_tilt_exec;
- ntype.declare = blender::nodes::geo_node_set_curve_tilt_declare;
+ 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/node_geo_set_id.cc b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
index 77d8e786501..db4083acd4b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_id_cc {
-static void geo_node_set_id_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -36,26 +36,24 @@ static void set_id_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
/* Since adding the ID attribute can change the result of the field evaluation (the random value
* node uses the index if the ID is unavailable), make sure that it isn't added before evaluating
* the field. However, as an optimization, use a faster code path when it already exists. */
- fn::FieldEvaluator id_evaluator{field_context, &selection};
if (component.attribute_exists("id")) {
OutputAttribute_Typed<int> id_attribute = component.attribute_try_get_for_output_only<int>(
"id", ATTR_DOMAIN_POINT);
- id_evaluator.add_with_destination(id_field, id_attribute.varray());
- id_evaluator.evaluate();
+ evaluator.add_with_destination(id_field, id_attribute.varray());
+ evaluator.evaluate();
id_attribute.save();
}
else {
- id_evaluator.add(id_field);
- id_evaluator.evaluate();
- const VArray<int> &result_ids = id_evaluator.get_evaluated<int>(0);
+ evaluator.add(id_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ const VArray<int> &result_ids = evaluator.get_evaluated<int>(0);
OutputAttribute_Typed<int> id_attribute = component.attribute_try_get_for_output_only<int>(
"id", ATTR_DOMAIN_POINT);
result_ids.materialize(selection, id_attribute.as_span());
@@ -63,7 +61,7 @@ static void set_id_in_component(GeometryComponent &component,
}
}
-static void geo_node_set_id_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -81,14 +79,16 @@ static void geo_node_set_id_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_id_cc
void register_node_type_geo_set_id()
{
+ namespace file_ns = blender::nodes::node_geo_set_id_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SET_ID, "Set ID", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_id_exec;
- ntype.declare = blender::nodes::geo_node_set_id_declare;
+ 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/node_geo_set_material.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc
index 3817de02a38..30510c3570c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc
@@ -21,16 +21,18 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_pointcloud_types.h"
#include "DNA_volume_types.h"
#include "BKE_material.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_material_cc {
-static void geo_node_set_material_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"))
- .supported_type({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_VOLUME});
+ .supported_type(
+ {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_POINT_CLOUD});
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
b.add_input<decl::Material>(N_("Material")).hide_label();
b.add_output<decl::Geometry>(N_("Geometry"));
@@ -59,58 +61,68 @@ static void assign_material_to_faces(Mesh &mesh, const IndexMask selection, Mate
}
}
-static void geo_node_set_material_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ /* Only add the warnings once, even if there are many unique instances. */
+ bool point_selection_warning = false;
bool volume_selection_warning = false;
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
- if (geometry_set.has<MeshComponent>()) {
+ if (geometry_set.has_mesh()) {
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
- Mesh *mesh = mesh_component.get_for_write();
- if (mesh != nullptr) {
- GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE};
+ Mesh &mesh = *mesh_component.get_for_write();
+ GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE};
- fn::FieldEvaluator selection_evaluator{field_context, mesh->totpoly};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator selection_evaluator{field_context, mesh.totpoly};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
- assign_material_to_faces(*mesh, selection, material);
- }
+ assign_material_to_faces(mesh, selection, material);
}
- if (geometry_set.has_volume()) {
- Volume &volume = *geometry_set.get_volume_for_write();
-
+ if (Volume *volume = geometry_set.get_volume_for_write()) {
+ BKE_id_material_eval_assign(&volume->id, 1, material);
if (selection_field.node().depends_on_input()) {
volume_selection_warning = true;
}
-
- BKE_id_material_eval_assign(&volume.id, 1, material);
+ }
+ if (PointCloud *pointcloud = geometry_set.get_pointcloud_for_write()) {
+ BKE_id_material_eval_assign(&pointcloud->id, 1, material);
+ if (selection_field.node().depends_on_input()) {
+ point_selection_warning = true;
+ }
}
});
if (volume_selection_warning) {
- /* Only add the warning once, even if there are many unique volume instances. */
params.error_message_add(
NodeWarningType::Info,
TIP_("Volumes only support a single material; selection input can not be a field"));
}
+ if (point_selection_warning) {
+ params.error_message_add(
+ NodeWarningType::Info,
+ TIP_("Point clouds only support a single material; selection input can not be a field"));
+ }
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_material_cc
void register_node_type_geo_set_material()
{
+ namespace file_ns = blender::nodes::node_geo_set_material_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SET_MATERIAL, "Set Material", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_set_material_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_set_material_exec;
+ 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/node_geo_set_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
index a8bb1bd8644..4451907132a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_material_index_cc {
-static void geo_node_set_material_index_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -36,20 +36,17 @@ static void set_material_index_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<int> indices = component.attribute_try_get_for_output_only<int>(
"material_index", ATTR_DOMAIN_FACE);
- fn::FieldEvaluator material_evaluator{field_context, &selection};
- material_evaluator.add_with_destination(index_field, indices.varray());
- material_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(index_field, indices.varray());
+ evaluator.evaluate();
indices.save();
}
-static void geo_node_set_material_index_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -64,15 +61,17 @@ static void geo_node_set_material_index_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_material_index_cc
void register_node_type_geo_set_material_index()
{
+ namespace file_ns = blender::nodes::node_geo_set_material_index_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_MATERIAL_INDEX, "Set Material Index", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_material_index_exec;
- ntype.declare = blender::nodes::geo_node_set_material_index_declare;
+ 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/node_geo_set_point_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
index 9ff299542b4..98adff7c939 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_point_radius_cc {
-static void geo_node_set_point_radius_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Points")).supported_type(GEO_COMPONENT_TYPE_POINT_CLOUD);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -40,20 +40,18 @@ static void set_radius_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<float> radii = component.attribute_try_get_for_output_only<float>(
"radius", ATTR_DOMAIN_POINT);
- fn::FieldEvaluator radii_evaluator{field_context, &selection};
- radii_evaluator.add_with_destination(radius_field, radii.varray());
- radii_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(radius_field, radii.varray());
+ evaluator.evaluate();
+
radii.save();
}
-static void geo_node_set_point_radius_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -70,15 +68,17 @@ static void geo_node_set_point_radius_exec(GeoNodeExecParams params)
params.set_output("Points", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_point_radius_cc
void register_node_type_geo_set_point_radius()
{
+ namespace file_ns = blender::nodes::node_geo_set_point_radius_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_POINT_RADIUS, "Set Point Radius", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_point_radius_exec;
- ntype.declare = blender::nodes::geo_node_set_point_radius_declare;
+ 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/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
index 5fe9fb1b3d4..93073c2436d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -16,11 +16,16 @@
#include "DEG_depsgraph_query.h"
+#include "BLI_task.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_position_cc {
-static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -29,6 +34,77 @@ static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
+static void set_computed_position_and_offset(GeometryComponent &component,
+ const VArray<float3> &in_positions,
+ const VArray<float3> &in_offsets,
+ const AttributeDomain domain,
+ const IndexMask selection)
+{
+
+ OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
+ "position", domain, {0, 0, 0});
+
+ const int grain_size = 10000;
+
+ switch (component.type()) {
+ case GEO_COMPONENT_TYPE_MESH: {
+ Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write();
+ MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert};
+ if (in_positions.is_same(positions.varray())) {
+ devirtualize_varray(in_offsets, [&](const auto in_offsets) {
+ threading::parallel_for(
+ selection.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int i : selection.slice(range)) {
+ const float3 offset = in_offsets[i];
+ add_v3_v3(mverts[i].co, offset);
+ }
+ });
+ });
+ }
+ else {
+ devirtualize_varray2(
+ in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
+ threading::parallel_for(
+ selection.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int i : selection.slice(range)) {
+ const float3 new_position = in_positions[i] + in_offsets[i];
+ copy_v3_v3(mverts[i].co, new_position);
+ }
+ });
+ });
+ }
+ break;
+ }
+ default: {
+ MutableSpan<float3> out_positions_span = positions.as_span();
+ if (in_positions.is_same(positions.varray())) {
+ devirtualize_varray(in_offsets, [&](const auto in_offsets) {
+ threading::parallel_for(
+ selection.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int i : selection.slice(range)) {
+ out_positions_span[i] += in_offsets[i];
+ }
+ });
+ });
+ }
+ else {
+ devirtualize_varray2(
+ in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) {
+ threading::parallel_for(
+ selection.index_range(), grain_size, [&](const IndexRange range) {
+ for (const int i : selection.slice(range)) {
+ out_positions_span[i] = in_positions[i] + in_offsets[i];
+ }
+ });
+ });
+ }
+ break;
+ }
+ }
+
+ positions.save();
+}
+
static void set_position_in_component(GeometryComponent &component,
const Field<bool> &selection_field,
const Field<float3> &position_field,
@@ -43,33 +119,19 @@ static void set_position_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
- fn::FieldEvaluator position_evaluator{field_context, &selection};
- position_evaluator.add(position_field);
- position_evaluator.add(offset_field);
- position_evaluator.evaluate();
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add(position_field);
+ evaluator.add(offset_field);
+ evaluator.evaluate();
- /* TODO: We could have different code paths depending on whether the offset input is a single
- * value or not */
-
- const VArray<float3> &positions_input = position_evaluator.get_evaluated<float3>(0);
- const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1);
-
- OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
- "position", domain, {0, 0, 0});
- MutableSpan<float3> position_mutable = positions.as_span();
-
- for (int i : selection) {
- position_mutable[i] = positions_input[i] + offsets_input[i];
- }
- positions.save();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ const VArray<float3> &positions_input = evaluator.get_evaluated<float3>(0);
+ const VArray<float3> &offsets_input = evaluator.get_evaluated<float3>(1);
+ set_computed_position_and_offset(component, positions_input, offsets_input, domain, selection);
}
-static void geo_node_set_position_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -89,14 +151,16 @@ static void geo_node_set_position_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_position_cc
void register_node_type_geo_set_position()
{
+ namespace file_ns = blender::nodes::node_geo_set_position_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SET_POSITION, "Set Position", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_position_exec;
- ntype.declare = blender::nodes::geo_node_set_position_declare;
+ 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/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
index 06e25c2ed55..879a868cc0e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_shade_smooth_cc {
-static void geo_node_set_shade_smooth_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -36,20 +36,18 @@ static void set_smooth_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<bool> shades = component.attribute_try_get_for_output_only<bool>(
"shade_smooth", ATTR_DOMAIN_FACE);
- fn::FieldEvaluator shade_evaluator{field_context, &selection};
- shade_evaluator.add_with_destination(shade_field, shades.varray());
- shade_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(shade_field, shades.varray());
+ evaluator.evaluate();
+
shades.save();
}
-static void geo_node_set_shade_smooth_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -64,15 +62,17 @@ static void geo_node_set_shade_smooth_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_shade_smooth_cc
void register_node_type_geo_set_shade_smooth()
{
+ namespace file_ns = blender::nodes::node_geo_set_shade_smooth_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_SHADE_SMOOTH, "Set Shade Smooth", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_shade_smooth_exec;
- ntype.declare = blender::nodes::geo_node_set_shade_smooth_declare;
+ 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/node_geo_set_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
index ec751ae1d2b..694491d7e6d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
@@ -16,9 +16,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_spline_cyclic_cc {
-static void geo_node_set_spline_cyclic_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -36,20 +36,18 @@ static void set_cyclic_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<bool> cyclics = component.attribute_try_get_for_output_only<bool>(
"cyclic", ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator cyclic_evaluator{field_context, &selection};
- cyclic_evaluator.add_with_destination(cyclic_field, cyclics.varray());
- cyclic_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(cyclic_field, cyclics.varray());
+ evaluator.evaluate();
+
cyclics.save();
}
-static void geo_node_set_spline_cyclic_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -65,15 +63,17 @@ static void geo_node_set_spline_cyclic_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_spline_cyclic_cc
void register_node_type_geo_set_spline_cyclic()
{
+ namespace file_ns = blender::nodes::node_geo_set_spline_cyclic_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_SPLINE_CYCLIC, "Set Spline Cyclic", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_spline_cyclic_exec;
- ntype.declare = blender::nodes::geo_node_set_spline_cyclic_declare;
+ 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/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
index ccf419975ca..0f93db5e6f6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
@@ -18,13 +18,13 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_set_spline_resolution_cc {
-static void geo_node_set_spline_resolution_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_CURVE);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Int>(N_("Resolution")).default_value(12).supports_field();
+ b.add_input<decl::Int>(N_("Resolution")).min(1).default_value(12).supports_field();
b.add_output<decl::Geometry>(N_("Geometry"));
}
@@ -38,20 +38,18 @@ static void set_resolution_in_component(GeometryComponent &component,
return;
}
- fn::FieldEvaluator selection_evaluator{field_context, domain_size};
- selection_evaluator.add(selection_field);
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
-
OutputAttribute_Typed<int> resolutions = component.attribute_try_get_for_output_only<int>(
"resolution", ATTR_DOMAIN_CURVE);
- fn::FieldEvaluator resolution_evaluator{field_context, &selection};
- resolution_evaluator.add_with_destination(resolution_field, resolutions.varray());
- resolution_evaluator.evaluate();
+
+ fn::FieldEvaluator evaluator{field_context, domain_size};
+ evaluator.set_selection(selection_field);
+ evaluator.add_with_destination(resolution_field, resolutions.varray());
+ evaluator.evaluate();
+
resolutions.save();
}
-static void geo_node_set_spline_resolution_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -81,15 +79,17 @@ static void geo_node_set_spline_resolution_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_set_spline_resolution_cc
void register_node_type_geo_set_spline_resolution()
{
+ namespace file_ns = blender::nodes::node_geo_set_spline_resolution_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SET_SPLINE_RESOLUTION, "Set Spline Resolution", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_set_spline_resolution_exec;
- ntype.declare = blender::nodes::geo_node_set_spline_resolution_declare;
+ 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/node_geo_string_join.cc b/source/blender/nodes/geometry/nodes/node_geo_string_join.cc
index 98d0aca084a..5308b43afb2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_string_join.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_string_join.cc
@@ -16,16 +16,16 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_string_join_cc {
-static void geo_node_string_join_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::String>(N_("Delimiter"));
b.add_input<decl::String>(N_("Strings")).multi_input().hide_value();
b.add_output<decl::String>(N_("String"));
};
-static void geo_node_string_join_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
Vector<std::string> strings = params.extract_multi_input<std::string>("Strings");
const std::string delim = params.extract_input<std::string>("Delimiter");
@@ -40,14 +40,16 @@ static void geo_node_string_join_exec(GeoNodeExecParams params)
params.set_output("String", std::move(output));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_string_join_cc
void register_node_type_geo_string_join()
{
+ namespace file_ns = blender::nodes::node_geo_string_join_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_STRING_JOIN, "Join Strings", NODE_CLASS_CONVERTER, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_string_join_exec;
- ntype.declare = blender::nodes::geo_node_string_join_declare;
+ 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/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
index 9e3ff10a3c5..33614eb3c46 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc
@@ -30,9 +30,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_string_to_curves_cc {
-static void geo_node_string_to_curves_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryStringToCurves)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::String>(N_("String"));
b.add_input<decl::Float>(N_("Size")).default_value(1.0f).min(0.0f).subtype(PROP_DISTANCE);
@@ -55,12 +57,17 @@ static void geo_node_string_to_curves_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Float>(N_("Text Box Height"))
.default_value(0.0f)
.min(0.0f)
- .subtype(PROP_DISTANCE);
+ .subtype(PROP_DISTANCE)
+ .make_available([](bNode &node) {
+ node_storage(node).overflow = GEO_NODE_STRING_TO_CURVES_MODE_SCALE_TO_FIT;
+ });
b.add_output<decl::Geometry>(N_("Curves"));
- b.add_output<decl::String>(N_("Remainder"));
+ b.add_output<decl::String>(N_("Remainder")).make_available([](bNode &node) {
+ node_storage(node).overflow = GEO_NODE_STRING_TO_CURVES_MODE_TRUNCATE;
+ });
}
-static void geo_node_string_to_curves_layout(uiLayout *layout, struct bContext *C, PointerRNA *ptr)
+static void node_layout(uiLayout *layout, struct bContext *C, PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -79,7 +86,7 @@ static void geo_node_string_to_curves_layout(uiLayout *layout, struct bContext *
uiItemR(layout, ptr, "align_y", 0, "", ICON_NONE);
}
-static void geo_node_string_to_curves_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryStringToCurves *data = (NodeGeometryStringToCurves *)MEM_callocN(
sizeof(NodeGeometryStringToCurves), __func__);
@@ -91,11 +98,11 @@ static void geo_node_string_to_curves_init(bNodeTree *UNUSED(ntree), bNode *node
node->id = (ID *)BKE_vfont_builtin_get();
}
-static void geo_node_string_to_curves_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryStringToCurves *storage = (const NodeGeometryStringToCurves *)node->storage;
+ const NodeGeometryStringToCurves &storage = node_storage(*node);
const GeometryNodeStringToCurvesOverflowMode overflow = (GeometryNodeStringToCurvesOverflowMode)
- storage->overflow;
+ storage.overflow;
bNodeSocket *socket_remainder = ((bNodeSocket *)node->outputs.first)->next;
nodeSetSocketAvailability(
ntree, socket_remainder, overflow == GEO_NODE_STRING_TO_CURVES_MODE_TRUNCATE);
@@ -131,8 +138,7 @@ static TextLayout get_text_layout(GeoNodeExecParams &params)
return {};
}
- const NodeGeometryStringToCurves &storage =
- *(const NodeGeometryStringToCurves *)params.node().storage;
+ const NodeGeometryStringToCurves &storage = node_storage(params.node());
const GeometryNodeStringToCurvesOverflowMode overflow = (GeometryNodeStringToCurvesOverflowMode)
storage.overflow;
const GeometryNodeStringToCurvesAlignXMode align_x = (GeometryNodeStringToCurvesAlignXMode)
@@ -265,7 +271,7 @@ static void add_instances_from_handles(InstancesComponent &instances,
});
}
-static void geo_node_string_to_curves_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
TextLayout layout = get_text_layout(params);
@@ -297,23 +303,25 @@ static void geo_node_string_to_curves_exec(GeoNodeExecParams params)
params.set_output("Curves", std::move(geometry_set_out));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_string_to_curves_cc
void register_node_type_geo_string_to_curves()
{
+ namespace file_ns = blender::nodes::node_geo_string_to_curves_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_STRING_TO_CURVES, "String to Curves", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_string_to_curves_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_string_to_curves_exec;
- node_type_init(&ntype, blender::nodes::geo_node_string_to_curves_init);
- node_type_update(&ntype, blender::nodes::geo_node_string_to_curves_update);
+ 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_update(&ntype, file_ns::node_update);
node_type_size(&ntype, 190, 120, 700);
node_type_storage(&ntype,
"NodeGeometryStringToCurves",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.draw_buttons = blender::nodes::geo_node_string_to_curves_layout;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
index 2b3430a5ed0..74e0560b32f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -27,9 +27,11 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_subdivision_surface_cc {
-static void geo_node_subdivision_surface_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometrySubdivisionSurface)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Int>(N_("Level")).default_value(1).min(0).max(6);
@@ -42,15 +44,13 @@ static void geo_node_subdivision_surface_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void geo_node_subdivision_surface_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "uv_smooth", 0, "", ICON_NONE);
uiItemR(layout, ptr, "boundary_smooth", 0, "", ICON_NONE);
}
-static void geo_node_subdivision_surface_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometrySubdivisionSurface *data = (NodeGeometrySubdivisionSurface *)MEM_callocN(
sizeof(NodeGeometrySubdivisionSurface), __func__);
@@ -59,7 +59,7 @@ static void geo_node_subdivision_surface_init(bNodeTree *UNUSED(ntree), bNode *n
node->storage = data;
}
-static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
#ifndef WITH_OPENSUBDIV
@@ -68,8 +68,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
#else
Field<float> crease_field = params.extract_input<Field<float>>("Crease");
- const NodeGeometrySubdivisionSurface &storage =
- *(const NodeGeometrySubdivisionSurface *)params.node().storage;
+ const NodeGeometrySubdivisionSurface &storage = node_storage(params.node());
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);
@@ -145,18 +144,20 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_subdivision_surface_cc
void register_node_type_geo_subdivision_surface()
{
+ namespace file_ns = blender::nodes::node_geo_subdivision_surface_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_SUBDIVISION_SURFACE, "Subdivision Surface", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_subdivision_surface_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_subdivision_surface_exec;
- ntype.draw_buttons = blender::nodes::geo_node_subdivision_surface_layout;
- node_type_init(&ntype, blender::nodes::geo_node_subdivision_surface_init);
+ 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",
diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
index 8d6f53ae375..d22522fe087 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
@@ -24,11 +24,15 @@
#include "BKE_material.h"
+#include "NOD_socket_search_link.hh"
+
#include "FN_multi_function_signature.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_switch_cc {
+
+NODE_STORAGE_FUNCS(NodeSwitch)
-static void geo_node_switch_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Bool>(N_("Switch")).default_value(false).supports_field();
b.add_input<decl::Bool>(N_("Switch"), "Switch_001").default_value(false);
@@ -83,32 +87,27 @@ static void geo_node_switch_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Image>(N_("Output"), "Output_011");
}
-static void geo_node_switch_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "input_type", 0, "", ICON_NONE);
}
-static void geo_node_switch_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeSwitch *data = (NodeSwitch *)MEM_callocN(sizeof(NodeSwitch), __func__);
data->input_type = SOCK_GEOMETRY;
node->storage = data;
}
-static void geo_node_switch_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeSwitch *node_storage = (NodeSwitch *)node->storage;
+ const NodeSwitch &storage = node_storage(*node);
int index = 0;
bNodeSocket *field_switch = (bNodeSocket *)node->inputs.first;
bNodeSocket *non_field_switch = (bNodeSocket *)field_switch->next;
- const bool fields_type = ELEM((eNodeSocketDatatype)node_storage->input_type,
- SOCK_FLOAT,
- SOCK_INT,
- SOCK_BOOLEAN,
- SOCK_VECTOR,
- SOCK_RGBA,
- SOCK_STRING);
+ const bool fields_type = ELEM(
+ storage.input_type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA, SOCK_STRING);
nodeSetSocketAvailability(ntree, field_switch, fields_type);
nodeSetSocketAvailability(ntree, non_field_switch, !fields_type);
@@ -117,13 +116,40 @@ static void geo_node_switch_update(bNodeTree *ntree, bNode *node)
if (index <= 1) {
continue;
}
- nodeSetSocketAvailability(
- ntree, socket, socket->type == (eNodeSocketDatatype)node_storage->input_type);
+ nodeSetSocketAvailability(ntree, socket, socket->type == storage.input_type);
}
LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
- nodeSetSocketAvailability(
- ntree, socket, socket->type == (eNodeSocketDatatype)node_storage->input_type);
+ nodeSetSocketAvailability(ntree, socket, socket->type == storage.input_type);
+ }
+}
+
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ if (params.in_out() == SOCK_OUT) {
+ params.add_item(IFACE_("Output"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSwitch");
+ node_storage(node).input_type = params.socket.type;
+ params.update_and_connect_available_socket(node, "Output");
+ });
+ }
+ else {
+ if (params.other_socket().type == SOCK_BOOLEAN) {
+ params.add_item(IFACE_("Switch"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSwitch");
+ params.connect_available_socket(node, "Start");
+ });
+ }
+ params.add_item(IFACE_("False"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSwitch");
+ node_storage(node).input_type = params.socket.type;
+ params.update_and_connect_available_socket(node, "False");
+ });
+ params.add_item(IFACE_("True"), [](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeSwitch");
+ node_storage(node).input_type = params.socket.type;
+ params.update_and_connect_available_socket(node, "True");
+ });
}
}
@@ -232,9 +258,9 @@ template<typename T> void switch_no_fields(GeoNodeExecParams &params, const Stri
}
}
-static void geo_node_switch_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- const NodeSwitch &storage = *(const NodeSwitch *)params.node().storage;
+ const NodeSwitch &storage = node_storage(params.node());
const eNodeSocketDatatype data_type = static_cast<eNodeSocketDatatype>(storage.input_type);
switch (data_type) {
@@ -293,19 +319,22 @@ static void geo_node_switch_exec(GeoNodeExecParams params)
}
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_switch_cc
void register_node_type_geo_switch()
{
+ namespace file_ns = blender::nodes::node_geo_switch_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_SWITCH, "Switch", NODE_CLASS_CONVERTER, 0);
- ntype.declare = blender::nodes::geo_node_switch_declare;
- node_type_init(&ntype, blender::nodes::geo_node_switch_init);
- node_type_update(&ntype, blender::nodes::geo_node_switch_update);
+ 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, "NodeSwitch", node_free_standard_storage, node_copy_standard_storage);
- ntype.geometry_node_execute = blender::nodes::geo_node_switch_exec;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.geometry_node_execute_supports_laziness = true;
- ntype.draw_buttons = blender::nodes::geo_node_switch_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
+ ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
index 3b30806d8ae..1f099dcd04d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc
@@ -31,19 +31,24 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
+namespace blender::nodes::node_geo_transfer_attribute_cc {
+
using namespace blender::bke::mesh_surface_sample;
using blender::fn::GArray;
-namespace blender::nodes {
+NODE_STORAGE_FUNCS(NodeGeometryTransferAttribute)
-static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Target"))
- .only_realized_data()
- .supported_type(
- {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE});
+ .supported_type({GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_INSTANCES});
b.add_input<decl::Vector>(N_("Attribute")).hide_value().supports_field();
b.add_input<decl::Float>(N_("Attribute"), "Attribute_001").hide_value().supports_field();
@@ -51,8 +56,14 @@ static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Bool>(N_("Attribute"), "Attribute_003").hide_value().supports_field();
b.add_input<decl::Int>(N_("Attribute"), "Attribute_004").hide_value().supports_field();
- b.add_input<decl::Vector>(N_("Source Position")).implicit_field();
- b.add_input<decl::Int>(N_("Index")).implicit_field();
+ b.add_input<decl::Vector>(N_("Source Position"))
+ .implicit_field()
+ .make_available([](bNode &node) {
+ node_storage(node).mode = GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED;
+ });
+ b.add_input<decl::Int>(N_("Index")).implicit_field().make_available([](bNode &node) {
+ node_storage(node).mode = GEO_NODE_ATTRIBUTE_TRANSFER_INDEX;
+ });
b.add_output<decl::Vector>(N_("Attribute")).dependent_field({6, 7});
b.add_output<decl::Float>(N_("Attribute"), "Attribute_001").dependent_field({6, 7});
@@ -61,14 +72,12 @@ static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").dependent_field({6, 7});
}
-static void geo_node_transfer_attribute_layout(uiLayout *layout,
- bContext *UNUSED(C),
- PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
const bNode &node = *static_cast<const bNode *>(ptr->data);
- const NodeGeometryTransferAttribute &data = *static_cast<const NodeGeometryTransferAttribute *>(
- node.storage);
- const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)data.mode;
+ const NodeGeometryTransferAttribute &storage = node_storage(node);
+ const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
+ storage.mode;
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "mapping", 0, "", ICON_NONE);
@@ -77,7 +86,7 @@ static void geo_node_transfer_attribute_layout(uiLayout *layout,
}
}
-static void geo_node_transfer_attribute_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryTransferAttribute *data = (NodeGeometryTransferAttribute *)MEM_callocN(
sizeof(NodeGeometryTransferAttribute), __func__);
@@ -86,12 +95,12 @@ static void geo_node_transfer_attribute_init(bNodeTree *UNUSED(tree), bNode *nod
node->storage = data;
}
-static void geo_node_transfer_attribute_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryTransferAttribute &data = *(const NodeGeometryTransferAttribute *)
- node->storage;
- const CustomDataType data_type = static_cast<CustomDataType>(data.data_type);
- const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)data.mode;
+ const NodeGeometryTransferAttribute &storage = node_storage(*node);
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
+ storage.mode;
bNodeSocket *socket_geometry = (bNodeSocket *)node->inputs.first;
bNodeSocket *socket_vector = socket_geometry->next;
@@ -125,6 +134,24 @@ static void geo_node_transfer_attribute_update(bNodeTree *ntree, bNode *node)
nodeSetSocketAvailability(ntree, out_socket_int32, data_type == CD_PROP_INT32);
}
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ const NodeDeclaration &declaration = *params.node_type().fixed_declaration;
+ search_link_ops_for_declarations(params, declaration.inputs().take_back(2));
+ search_link_ops_for_declarations(params, declaration.inputs().take_front(1));
+
+ const std::optional<CustomDataType> type = node_data_type_to_custom_data_type(
+ (eNodeSocketDatatype)params.other_socket().type);
+ if (type && *type != CD_PROP_STRING) {
+ /* The input and output sockets have the same name. */
+ params.add_item(IFACE_("Attribute"), [type](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeAttributeTransfer");
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Attribute");
+ });
+ }
+}
+
static void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
const VArray<float3> &positions,
const IndexMask mask,
@@ -132,9 +159,9 @@ static void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
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());
+ BLI_assert(positions.size() >= r_indices.size());
+ BLI_assert(positions.size() >= r_distances_sq.size());
+ BLI_assert(positions.size() >= r_positions.size());
for (const int i : mask) {
BVHTreeNearest nearest;
@@ -160,7 +187,7 @@ static void get_closest_pointcloud_points(const PointCloud &pointcloud,
const MutableSpan<int> r_indices,
const MutableSpan<float> r_distances_sq)
{
- BLI_assert(positions.size() == r_indices.size());
+ BLI_assert(positions.size() >= r_indices.size());
BLI_assert(pointcloud.totpoint > 0);
BVHTreeFromPointCloud tree_data;
@@ -500,7 +527,7 @@ class NearestTransferFunction : public fn::MultiFunction {
Array<int> mesh_indices;
Array<float> mesh_distances;
- /* If there is a point-cloud, find the closest points. */
+ /* If there is a point cloud, find the closest points. */
if (use_points_) {
point_indices.reinitialize(tot_samples);
if (use_mesh_) {
@@ -593,8 +620,10 @@ static const GeometryComponent *find_target_component(const GeometrySet &geometr
{
/* Choose the other component based on a consistent order, rather than some more complicated
* heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */
- static const Array<GeometryComponentType> supported_types = {
- GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE};
+ static const Array<GeometryComponentType> supported_types = {GEO_COMPONENT_TYPE_MESH,
+ GEO_COMPONENT_TYPE_POINT_CLOUD,
+ GEO_COMPONENT_TYPE_CURVE,
+ GEO_COMPONENT_TYPE_INSTANCES};
for (const GeometryComponentType src_type : supported_types) {
if (component_is_available(geometry, src_type, domain)) {
return geometry.get_component_for_read(src_type);
@@ -719,14 +748,14 @@ static void output_attribute_field(GeoNodeExecParams &params, GField field)
}
}
-static void geo_node_transfer_attribute_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry = params.extract_input<GeometrySet>("Target");
- const bNode &node = params.node();
- const NodeGeometryTransferAttribute &data = *(const NodeGeometryTransferAttribute *)node.storage;
- const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)data.mode;
- const CustomDataType data_type = static_cast<CustomDataType>(data.data_type);
- const AttributeDomain domain = static_cast<AttributeDomain>(data.domain);
+ const NodeGeometryTransferAttribute &storage = node_storage(params.node());
+ const GeometryNodeAttributeTransferMode mapping = (GeometryNodeAttributeTransferMode)
+ storage.mode;
+ const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
+ const AttributeDomain domain = static_cast<AttributeDomain>(storage.domain);
GField field = get_input_attribute_field(params, data_type);
@@ -737,10 +766,6 @@ static void geo_node_transfer_attribute_exec(GeoNodeExecParams params)
});
};
- /* Since the instances are not used, there is no point in keeping
- * a reference to them while the field is passed around. */
- geometry.remove(GEO_COMPONENT_TYPE_INSTANCES);
-
GField output_field;
switch (mapping) {
case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {
@@ -794,22 +819,25 @@ static void geo_node_transfer_attribute_exec(GeoNodeExecParams params)
output_attribute_field(params, std::move(output_field));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_transfer_attribute_cc
void register_node_type_geo_transfer_attribute()
{
+ namespace file_ns = blender::nodes::node_geo_transfer_attribute_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_TRANSFER_ATTRIBUTE, "Transfer Attribute", NODE_CLASS_ATTRIBUTE, 0);
- node_type_init(&ntype, blender::nodes::geo_node_transfer_attribute_init);
- node_type_update(&ntype, blender::nodes::geo_node_transfer_attribute_update);
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
node_type_storage(&ntype,
"NodeGeometryTransferAttribute",
node_free_standard_storage,
node_copy_standard_storage);
- ntype.declare = blender::nodes::geo_node_transfer_attribute_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_transfer_attribute_exec;
- ntype.draw_buttons = blender::nodes::geo_node_transfer_attribute_layout;
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index 2c55a255b5d..8322de20d20 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -35,15 +35,6 @@
namespace blender::nodes {
-static void geo_node_transform_declare(NodeDeclarationBuilder &b)
-{
- b.add_input<decl::Geometry>(N_("Geometry"));
- b.add_input<decl::Vector>(N_("Translation")).subtype(PROP_TRANSLATION);
- b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER);
- b.add_input<decl::Vector>(N_("Scale")).default_value({1, 1, 1}).subtype(PROP_XYZ);
- b.add_output<decl::Geometry>(N_("Geometry"));
-}
-
static bool use_translate(const float3 rotation, const float3 scale)
{
if (compare_ff(rotation.length_squared(), 0.0f, 1e-9f) != 1) {
@@ -69,15 +60,6 @@ static void transform_mesh(Mesh &mesh, const float4x4 &transform)
BKE_mesh_normals_tag_dirty(&mesh);
}
-void transform_mesh(Mesh &mesh,
- const float3 translation,
- const float3 rotation,
- const float3 scale)
-{
- const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rotation, scale);
- transform_mesh(mesh, matrix);
-}
-
static void translate_pointcloud(PointCloud &pointcloud, const float3 translation)
{
CustomData_duplicate_referenced_layer(&pointcloud.pdata, CD_PROP_FLOAT3, pointcloud.totpoint);
@@ -153,49 +135,71 @@ static void translate_volume(Volume &volume, const float3 translation, const Dep
transform_volume(volume, float4x4::from_location(translation), depsgraph);
}
-void transform_geometry_set(GeometrySet &geometry,
- const float4x4 &transform,
- const Depsgraph &depsgraph)
+static void translate_geometry_set(GeometrySet &geometry,
+ const float3 translation,
+ const Depsgraph &depsgraph)
{
if (CurveEval *curve = geometry.get_curve_for_write()) {
- curve->transform(transform);
+ curve->translate(translation);
}
if (Mesh *mesh = geometry.get_mesh_for_write()) {
- transform_mesh(*mesh, transform);
+ translate_mesh(*mesh, translation);
}
if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) {
- transform_pointcloud(*pointcloud, transform);
+ translate_pointcloud(*pointcloud, translation);
}
if (Volume *volume = geometry.get_volume_for_write()) {
- transform_volume(*volume, transform, depsgraph);
+ translate_volume(*volume, translation, depsgraph);
}
if (geometry.has_instances()) {
- transform_instances(geometry.get_component_for_write<InstancesComponent>(), transform);
+ translate_instances(geometry.get_component_for_write<InstancesComponent>(), translation);
}
}
-static void translate_geometry_set(GeometrySet &geometry,
- const float3 translation,
- const Depsgraph &depsgraph)
+void transform_geometry_set(GeometrySet &geometry,
+ const float4x4 &transform,
+ const Depsgraph &depsgraph)
{
if (CurveEval *curve = geometry.get_curve_for_write()) {
- curve->translate(translation);
+ curve->transform(transform);
}
if (Mesh *mesh = geometry.get_mesh_for_write()) {
- translate_mesh(*mesh, translation);
+ transform_mesh(*mesh, transform);
}
if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) {
- translate_pointcloud(*pointcloud, translation);
+ transform_pointcloud(*pointcloud, transform);
}
if (Volume *volume = geometry.get_volume_for_write()) {
- translate_volume(*volume, translation, depsgraph);
+ transform_volume(*volume, transform, depsgraph);
}
if (geometry.has_instances()) {
- translate_instances(geometry.get_component_for_write<InstancesComponent>(), translation);
+ transform_instances(geometry.get_component_for_write<InstancesComponent>(), transform);
}
}
-static void geo_node_transform_exec(GeoNodeExecParams params)
+void transform_mesh(Mesh &mesh,
+ const float3 translation,
+ const float3 rotation,
+ const float3 scale)
+{
+ const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rotation, scale);
+ transform_mesh(mesh, matrix);
+}
+
+} // namespace blender::nodes
+
+namespace blender::nodes::node_geo_transform_cc {
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Geometry"));
+ b.add_input<decl::Vector>(N_("Translation")).subtype(PROP_TRANSLATION);
+ b.add_input<decl::Vector>(N_("Rotation")).subtype(PROP_EULER);
+ b.add_input<decl::Vector>(N_("Scale")).default_value({1, 1, 1}).subtype(PROP_XYZ);
+ b.add_output<decl::Geometry>(N_("Geometry"));
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
const float3 translation = params.extract_input<float3>("Translation");
@@ -214,14 +218,16 @@ static void geo_node_transform_exec(GeoNodeExecParams params)
params.set_output("Geometry", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_transform_cc
void register_node_type_geo_transform()
{
+ namespace file_ns = blender::nodes::node_geo_transform_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_TRANSFORM, "Transform", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_transform_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_transform_exec;
+ 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/node_geo_translate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
index 1a5a60fb1b0..59049ecf0ed 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc
@@ -18,9 +18,9 @@
#include "node_geometry_util.hh"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_translate_instances_cc {
-static void geo_node_translate_instances_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Instances")).only_instances();
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
@@ -33,17 +33,15 @@ static void translate_instances(GeoNodeExecParams &params, InstancesComponent &i
{
GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_INSTANCE};
- fn::FieldEvaluator selection_evaluator{field_context, instances_component.instances_amount()};
- selection_evaluator.add(params.extract_input<Field<bool>>("Selection"));
- selection_evaluator.evaluate();
- const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+ fn::FieldEvaluator evaluator{field_context, instances_component.instances_amount()};
+ evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
+ evaluator.add(params.extract_input<Field<float3>>("Translation"));
+ evaluator.add(params.extract_input<Field<bool>>("Local Space"));
+ evaluator.evaluate();
- fn::FieldEvaluator transforms_evaluator{field_context, &selection};
- transforms_evaluator.add(params.extract_input<Field<float3>>("Translation"));
- transforms_evaluator.add(params.extract_input<Field<bool>>("Local Space"));
- transforms_evaluator.evaluate();
- const VArray<float3> &translations = transforms_evaluator.get_evaluated<float3>(0);
- const VArray<bool> &local_spaces = transforms_evaluator.get_evaluated<bool>(1);
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ const VArray<float3> &translations = evaluator.get_evaluated<float3>(0);
+ const VArray<bool> &local_spaces = evaluator.get_evaluated<bool>(1);
MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
@@ -60,7 +58,7 @@ static void translate_instances(GeoNodeExecParams &params, InstancesComponent &i
});
}
-static void geo_node_translate_instances_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances");
if (geometry_set.has_instances()) {
@@ -70,15 +68,17 @@ static void geo_node_translate_instances_exec(GeoNodeExecParams params)
params.set_output("Instances", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_translate_instances_cc
void register_node_type_geo_translate_instances()
{
+ namespace file_ns = blender::nodes::node_geo_translate_instances_cc;
+
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_TRANSLATE_INSTANCES, "Translate Instances", NODE_CLASS_GEOMETRY, 0);
- ntype.geometry_node_execute = blender::nodes::geo_node_translate_instances_exec;
- ntype.declare = blender::nodes::geo_node_translate_instances_declare;
+ 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/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
index c869846e1f8..f8deaaa4a14 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc
@@ -27,16 +27,16 @@ Mesh *triangulate_mesh(Mesh *mesh,
const int flag);
}
-namespace blender::nodes {
+namespace blender::nodes::node_geo_triangulate_cc {
-static void geo_node_triangulate_declare(NodeDeclarationBuilder &b)
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Int>(N_("Minimum Vertices")).default_value(4).min(4).max(10000);
b.add_output<decl::Geometry>(N_("Mesh"));
}
-static void geo_node_triangulate_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "quad_method", 0, "", ICON_NONE);
uiItemR(layout, ptr, "ngon_method", 0, "", ICON_NONE);
@@ -48,7 +48,7 @@ static void geo_triangulate_init(bNodeTree *UNUSED(ntree), bNode *node)
node->custom2 = GEO_NODE_TRIANGULATE_NGON_BEAUTY;
}
-static void geo_node_triangulate_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
const int min_vertices = std::max(params.extract_input<int>("Minimum Vertices"), 4);
@@ -69,16 +69,18 @@ static void geo_node_triangulate_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_triangulate_cc
void register_node_type_geo_triangulate()
{
+ namespace file_ns = blender::nodes::node_geo_triangulate_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_TRIANGULATE, "Triangulate", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_triangulate_declare;
- node_type_init(&ntype, blender::nodes::geo_triangulate_init);
- ntype.geometry_node_execute = blender::nodes::geo_node_triangulate_exec;
- ntype.draw_buttons = blender::nodes::geo_node_triangulate_layout;
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::geo_triangulate_init);
+ 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_viewer.cc b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
index a46d7529124..18f2fa4cd36 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc
@@ -14,13 +14,23 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "BKE_context.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
+#include "ED_node.h"
+#include "ED_spreadsheet.h"
+
+#include "NOD_socket_search_link.hh"
+
#include "node_geometry_util.hh"
-namespace blender::nodes {
-static void geo_node_viewer_declare(NodeDeclarationBuilder &b)
+namespace blender::nodes::node_geo_viewer_cc {
+
+NODE_STORAGE_FUNCS(NodeGeometryViewer)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry"));
b.add_input<decl::Float>(N_("Value")).supports_field().hide_value();
@@ -30,7 +40,7 @@ static void geo_node_viewer_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Bool>(N_("Value"), "Value_004").supports_field().hide_value();
}
-static void geo_node_viewer_init(bNodeTree *UNUSED(tree), bNode *node)
+static void node_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeGeometryViewer *data = (NodeGeometryViewer *)MEM_callocN(sizeof(NodeGeometryViewer),
__func__);
@@ -39,7 +49,7 @@ static void geo_node_viewer_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void geo_node_viewer_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
}
@@ -63,9 +73,9 @@ static eNodeSocketDatatype custom_data_type_to_socket_type(const CustomDataType
}
}
-static void geo_node_viewer_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- const NodeGeometryViewer &storage = *(const NodeGeometryViewer *)node->storage;
+ const NodeGeometryViewer &storage = node_storage(*node);
const CustomDataType data_type = static_cast<CustomDataType>(storage.data_type);
const eNodeSocketDatatype socket_type = custom_data_type_to_socket_type(data_type);
@@ -77,18 +87,67 @@ static void geo_node_viewer_update(bNodeTree *ntree, bNode *node)
}
}
-} // namespace blender::nodes
+static void node_gather_link_searches(GatherLinkSearchOpParams &params)
+{
+ auto set_active_fn = [](LinkSearchOpParams &params, bNode &viewer_node) {
+ /* Set this new viewer node active in spreadsheet editors. */
+ SpaceNode *snode = CTX_wm_space_node(&params.C);
+ Main *bmain = CTX_data_main(&params.C);
+ ED_node_set_active(bmain, snode, &params.node_tree, &viewer_node, nullptr);
+ ED_spreadsheet_context_paths_set_geometry_node(bmain, snode, &viewer_node);
+ };
+
+ const std::optional<CustomDataType> type = node_socket_to_custom_data_type(
+ params.other_socket());
+ if (params.in_out() == SOCK_OUT) {
+ /* The viewer node only has inputs. */
+ return;
+ }
+ if (params.other_socket().type == SOCK_GEOMETRY) {
+ params.add_item(IFACE_("Geometry"), [set_active_fn](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeViewer");
+ params.connect_available_socket(node, "Geometry");
+ set_active_fn(params, node);
+ });
+ }
+ if (type &&
+ ELEM(type, CD_PROP_FLOAT, CD_PROP_BOOL, CD_PROP_INT32, CD_PROP_FLOAT3, CD_PROP_COLOR)) {
+ params.add_item(IFACE_("Value"), [type, set_active_fn](LinkSearchOpParams &params) {
+ bNode &node = params.add_node("GeometryNodeViewer");
+ node_storage(node).data_type = *type;
+ params.update_and_connect_available_socket(node, "Value");
+
+ /* If the source node has a geometry socket, connect it to the new viewer node as well. */
+ LISTBASE_FOREACH (bNodeSocket *, socket, &params.node.outputs) {
+ if (socket->type == SOCK_GEOMETRY && !(socket->flag & (SOCK_UNAVAIL | SOCK_HIDDEN))) {
+ nodeAddLink(&params.node_tree,
+ &params.node,
+ socket,
+ &node,
+ static_cast<bNodeSocket *>(node.inputs.first));
+ }
+ }
+
+ set_active_fn(params, node);
+ });
+ }
+}
+
+} // namespace blender::nodes::node_geo_viewer_cc
void register_node_type_geo_viewer()
{
+ namespace file_ns = blender::nodes::node_geo_viewer_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_VIEWER, "Viewer", NODE_CLASS_OUTPUT, 0);
node_type_storage(
&ntype, "NodeGeometryViewer", node_free_standard_storage, node_copy_standard_storage);
- node_type_update(&ntype, blender::nodes::geo_node_viewer_update);
- node_type_init(&ntype, blender::nodes::geo_node_viewer_init);
- ntype.declare = blender::nodes::geo_node_viewer_declare;
- ntype.draw_buttons_ex = blender::nodes::geo_node_viewer_layout;
+ node_type_update(&ntype, file_ns::node_update);
+ node_type_init(&ntype, file_ns::node_init);
+ ntype.declare = file_ns::node_declare;
+ ntype.draw_buttons_ex = file_ns::node_layout;
+ ntype.gather_link_search_ops = file_ns::node_gather_link_searches;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
index 99eeae370fe..0819b401941 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
@@ -35,26 +35,39 @@
#include "UI_interface.h"
#include "UI_resources.h"
-namespace blender::nodes {
+namespace blender::nodes::node_geo_volume_to_mesh_cc {
-static void geo_node_volume_to_mesh_declare(NodeDeclarationBuilder &b)
+NODE_STORAGE_FUNCS(NodeGeometryVolumeToMesh)
+
+static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Volume")).supported_type(GEO_COMPONENT_TYPE_VOLUME);
- 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_("Voxel Size"))
+ .default_value(0.3f)
+ .min(0.01f)
+ .subtype(PROP_DISTANCE)
+ .make_available([](bNode &node) {
+ node_storage(node).resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE;
+ });
+ b.add_input<decl::Float>(N_("Voxel Amount"))
+ .default_value(64.0f)
+ .min(0.0f)
+ .make_available([](bNode &node) {
+ node_storage(node).resolution_mode = VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT;
+ });
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_("Mesh"));
}
-static void geo_node_volume_to_mesh_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+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 geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
+static void node_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)MEM_callocN(
sizeof(NodeGeometryVolumeToMesh), __func__);
@@ -62,26 +75,26 @@ static void geo_node_volume_to_mesh_init(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = data;
}
-static void geo_node_volume_to_mesh_update(bNodeTree *ntree, bNode *node)
+static void node_update(bNodeTree *ntree, bNode *node)
{
- NodeGeometryVolumeToMesh *data = (NodeGeometryVolumeToMesh *)node->storage;
+ const NodeGeometryVolumeToMesh &storage = node_storage(*node);
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);
+ storage.resolution_mode ==
+ VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_AMOUNT);
nodeSetSocketAvailability(ntree,
voxel_size_socket,
- data->resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE);
+ storage.resolution_mode == VOLUME_TO_MESH_RESOLUTION_MODE_VOXEL_SIZE);
}
#ifdef WITH_OPENVDB
static bke::VolumeToMeshResolution get_resolution_param(const GeoNodeExecParams &params)
{
- const NodeGeometryVolumeToMesh &storage =
- *(const NodeGeometryVolumeToMesh *)params.node().storage;
+ const NodeGeometryVolumeToMesh &storage = node_storage(params.node());
bke::VolumeToMeshResolution resolution;
resolution.mode = (VolumeToMeshResolutionMode)storage.resolution_mode;
@@ -176,7 +189,7 @@ static Mesh *create_mesh_from_volume(GeometrySet &geometry_set, GeoNodeExecParam
#endif /* WITH_OPENVDB */
-static void geo_node_volume_to_mesh_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Volume");
@@ -194,20 +207,22 @@ static void geo_node_volume_to_mesh_exec(GeoNodeExecParams params)
params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_volume_to_mesh_cc
void register_node_type_geo_volume_to_mesh()
{
+ namespace file_ns = blender::nodes::node_geo_volume_to_mesh_cc;
+
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_VOLUME_TO_MESH, "Volume to Mesh", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_volume_to_mesh_declare;
+ 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, blender::nodes::geo_node_volume_to_mesh_init);
- node_type_update(&ntype, blender::nodes::geo_node_volume_to_mesh_update);
- ntype.geometry_node_execute = blender::nodes::geo_node_volume_to_mesh_exec;
- ntype.draw_buttons = blender::nodes::geo_node_volume_to_mesh_layout;
+ 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);
}