[Bf-blender-cvs] [3ff15a9e23b] master: Geometry Nodes: New Face Set Boundaries node

Wannes Malfait noreply at git.blender.org
Sun Sep 18 05:19:06 CEST 2022


Commit: 3ff15a9e23bd8a20ee514944779a898f1fe5accb
Author: Wannes Malfait
Date:   Sat Sep 17 22:18:52 2022 -0500
Branches: master
https://developer.blender.org/rB3ff15a9e23bd8a20ee514944779a898f1fe5accb

Geometry Nodes: New Face Set Boundaries node

With the recent addition of the UV unwrapping node, there is a need to
be able to create seams easily. This node does that by outputting a
selection of the boundaries between different input face sets. In the
context of UV mapping, one inputs the "patches" you want, and the node
gives you the seams needed to make those patches.

Differential Revision: https://developer.blender.org/D15423

===================================================================

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
M	source/blender/nodes/geometry/CMakeLists.txt
A	source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc

===================================================================

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);
+}



More information about the Bf-blender-cvs mailing list