diff options
-rw-r--r-- | release/scripts/startup/nodeitems_builtins.py | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_node.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 1 | ||||
-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_mesh_face_set_boundaries.cc | 89 |
7 files changed, 95 insertions, 0 deletions
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index b7d09215676..89b729595db 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -128,6 +128,7 @@ def mesh_node_items(context): yield NodeItem("GeometryNodeInputMeshEdgeVertices") yield NodeItem("GeometryNodeInputMeshFaceArea") yield NodeItem("GeometryNodeInputMeshFaceNeighbors") + yield NodeItem("GeometryNodeMeshFaceSetBoundaries") yield NodeItem("GeometryNodeInputMeshFaceIsPlanar") yield NodeItem("GeometryNodeInputShadeSmooth") yield NodeItem("GeometryNodeInputMeshIsland") diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 55bf24f943e..75654a86409 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1525,6 +1525,7 @@ struct TexResult; #define GEO_NODE_INPUT_SHORTEST_EDGE_PATHS 1168 #define GEO_NODE_EDGE_PATHS_TO_CURVES 1169 #define GEO_NODE_EDGE_PATHS_TO_SELECTION 1170 +#define GEO_NODE_MESH_FACE_SET_BOUNDARIES 1171 /** \} */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index c462d03e3da..1af04d3034c 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4748,6 +4748,7 @@ static void registerGeometryNodes() register_node_type_geo_material_replace(); register_node_type_geo_material_selection(); register_node_type_geo_merge_by_distance(); + register_node_type_geo_mesh_face_set_boundaries(); register_node_type_geo_mesh_primitive_circle(); register_node_type_geo_mesh_primitive_cone(); register_node_type_geo_mesh_primitive_cube(); diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h index e16cd7a253f..63af2c71d45 100644 --- a/source/blender/nodes/NOD_geometry.h +++ b/source/blender/nodes/NOD_geometry.h @@ -95,6 +95,7 @@ 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_face_set_boundaries(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 d587da823f1..73fb2bf32c8 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -352,6 +352,7 @@ DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "Provide a selection of faces that use the specified material") DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance,"MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance") DefNode(GeometryNode, GEO_NODE_MESH_BOOLEAN, def_geo_boolean, "MESH_BOOLEAN", MeshBoolean, "Mesh Boolean", "Cut, subtract, or join multiple mesh inputs") +DefNode(GeometryNode, GEO_NODE_MESH_FACE_SET_BOUNDARIES, 0, "MESH_FACE_SET_BOUNDARIES", MeshFaceSetBoundaries, "Face Set Boundaries", "Find edges on the boundaries between face sets") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "Generate a circular ring of edges") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE",MeshCone, "Cone", "Generate a cone mesh") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CUBE, 0, "MESH_PRIMITIVE_CUBE",MeshCube, "Cube", "Generate a cuboid mesh with variable side lengths and subdivisions") diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index 31c00cc6b82..cc3d00ea21f 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -105,6 +105,7 @@ set(SRC nodes/node_geo_material_replace.cc nodes/node_geo_material_selection.cc nodes/node_geo_merge_by_distance.cc + nodes/node_geo_mesh_face_set_boundaries.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_mesh_face_set_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc new file mode 100644 index 00000000000..88cccfb2f94 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" + +#include "BKE_mesh.h" + +#include "node_geometry_util.hh" + +namespace blender::nodes::node_geo_mesh_face_set_boundaries_cc { + +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_input<decl::Int>(N_("Face Set")) + .default_value(0) + .hide_value() + .supports_field() + .description(N_("An identifier for the group of each face. All contiguous faces with the " + "same value are in the same region")); + b.add_output<decl::Bool>(N_("Boundary Edges")) + .field_source() + .description(N_("The edges that lie on the boundaries between the different face sets")); +} + +class BoundaryFieldInput final : public bke::MeshFieldInput { + private: + const Field<int> face_set; + + public: + BoundaryFieldInput(const Field<int> face_set) + : bke::MeshFieldInput(CPPType::get<bool>(), "Boundary Field"), face_set(face_set) + { + category_ = Category::Generated; + } + + GVArray get_varray_for_context(const Mesh &mesh, + const eAttrDomain domain, + const IndexMask /*mask*/) const final + { + const bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; + FieldEvaluator face_evaluator{face_context, mesh.totpoly}; + face_evaluator.add(face_set); + face_evaluator.evaluate(); + const VArray<int> face_set = face_evaluator.get_evaluated<int>(0); + + Array<bool> boundary(mesh.totedge, false); + Array<bool> edge_visited(mesh.totedge, false); + Array<int> edge_face_set(mesh.totedge, 0); + const Span<MPoly> polys = mesh.polys(); + const Span<MLoop> loops = mesh.loops(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + const int edge = loop.e; + if (edge_visited[edge]) { + if (edge_face_set[edge] != face_set[i]) { + /* This edge is connected to two faces on different face sets. */ + boundary[edge] = true; + } + } + edge_visited[edge] = true; + edge_face_set[edge] = face_set[i]; + } + } + return mesh.attributes().adapt_domain<bool>( + VArray<bool>::ForContainer(std::move(boundary)), ATTR_DOMAIN_EDGE, domain); + } +}; + +static void node_geo_exec(GeoNodeExecParams params) +{ + const Field<int> face_set_field = params.extract_input<Field<int>>("Face Set"); + Field<bool> face_set_boundaries{std::make_shared<BoundaryFieldInput>(face_set_field)}; + params.set_output("Boundary Edges", std::move(face_set_boundaries)); +} + +} // namespace blender::nodes::node_geo_mesh_face_set_boundaries_cc + +void register_node_type_geo_mesh_face_set_boundaries() +{ + namespace file_ns = blender::nodes::node_geo_mesh_face_set_boundaries_cc; + + static bNodeType ntype; + geo_node_type_base( + &ntype, GEO_NODE_MESH_FACE_SET_BOUNDARIES, "Face Set Boundaries", NODE_CLASS_INPUT); + ntype.declare = file_ns::node_declare; + ntype.geometry_node_execute = file_ns::node_geo_exec; + nodeRegisterType(&ntype); +} |