diff options
Diffstat (limited to 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/NOD_geometry.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_static_types.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/geometry/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc | 80 |
4 files changed, 83 insertions, 0 deletions
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index e5c005f8c95..609d92c09df 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -132,6 +132,7 @@ void register_node_type_geo_is_viewport(void); void register_node_type_geo_join_geometry(void); void register_node_type_geo_material_replace(void); void register_node_type_geo_material_selection(void); +void register_node_type_geo_merge_by_distance(void); void register_node_type_geo_mesh_primitive_circle(void); void register_node_type_geo_mesh_primitive_cone(void); void register_node_type_geo_mesh_primitive_cube(void); diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index df820bf6dcf..8cbde6adcad 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -387,6 +387,7 @@ DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS", In DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "") DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "") DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "") +DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, 0, "MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "") DefNode(GeometryNode, GEO_NODE_MESH_BOOLEAN, def_geo_boolean, "MESH_BOOLEAN", MeshBoolean, "Mesh Boolean", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE", MeshCone, "Cone", "") diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index 0e5f90b58bf..b4add633b0c 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -150,6 +150,7 @@ set(SRC nodes/node_geo_join_geometry.cc nodes/node_geo_material_replace.cc nodes/node_geo_material_selection.cc + nodes/node_geo_merge_by_distance.cc nodes/node_geo_mesh_primitive_circle.cc nodes/node_geo_mesh_primitive_cone.cc nodes/node_geo_mesh_primitive_cube.cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc new file mode 100644 index 00000000000..54006062374 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc @@ -0,0 +1,80 @@ +/* + * 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 "GEO_point_merge_by_distance.hh" + +#include "node_geometry_util.hh" + +namespace blender::nodes::node_geo_merge_by_distance_cc { + +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_input<decl::Geometry>(N_("Geometry")).supported_type({GEO_COMPONENT_TYPE_POINT_CLOUD}); + b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field(); + b.add_input<decl::Float>(N_("Distance")).default_value(0.1f).min(0.0f).subtype(PROP_DISTANCE); + b.add_output<decl::Geometry>(N_("Geometry")); +} + +static PointCloud *pointcloud_merge_by_distance(const PointCloudComponent &src_points, + const float merge_distance, + const Field<bool> &selection_field) +{ + const int src_size = src_points.attribute_domain_size(ATTR_DOMAIN_POINT); + GeometryComponentFieldContext context{src_points, ATTR_DOMAIN_POINT}; + FieldEvaluator evaluator{context, src_size}; + evaluator.add(selection_field); + evaluator.evaluate(); + + const IndexMask selection = evaluator.get_evaluated_as_mask(0); + if (selection.is_empty()) { + return nullptr; + } + + return geometry::point_merge_by_distance(src_points, merge_distance, selection); +} + +static void node_geo_exec(GeoNodeExecParams params) +{ + GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); + + const Field<bool> selection = params.extract_input<Field<bool>>("Selection"); + const float merge_distance = params.extract_input<float>("Distance"); + + geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { + if (geometry_set.has_pointcloud()) { + PointCloud *result = pointcloud_merge_by_distance( + *geometry_set.get_component_for_read<PointCloudComponent>(), merge_distance, selection); + geometry_set.replace_pointcloud(result); + } + }); + + params.set_output("Geometry", std::move(geometry_set)); +} + +} // namespace blender::nodes::node_geo_merge_by_distance_cc + +void register_node_type_geo_merge_by_distance() +{ + namespace file_ns = blender::nodes::node_geo_merge_by_distance_cc; + + static bNodeType ntype; + + geo_node_type_base(&ntype, GEO_NODE_MERGE_BY_DISTANCE, "Merge by Distance", NODE_CLASS_GEOMETRY); + + ntype.declare = file_ns::node_declare; + ntype.geometry_node_execute = file_ns::node_geo_exec; + nodeRegisterType(&ntype); +} |