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:
-rw-r--r--release/scripts/startup/nodeitems_builtins.py1
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc89
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);
+}