[Bf-blender-cvs] [d2b9cc41e79] soc-2021-porting-modifiers-to-nodes-decimate: Added attribute delimiter for dissolve node

Fabian Schempp noreply at git.blender.org
Thu Jul 8 12:12:51 CEST 2021


Commit: d2b9cc41e790b0003e7355f6535a05fa62f984a3
Author: Fabian Schempp
Date:   Thu Jul 8 12:08:29 2021 +0200
Branches: soc-2021-porting-modifiers-to-nodes-decimate
https://developer.blender.org/rBd2b9cc41e790b0003e7355f6535a05fa62f984a3

Added attribute delimiter for dissolve node

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

M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/bmesh/intern/bmesh_mesh.h
M	source/blender/bmesh/intern/bmesh_operator_api.h
M	source/blender/bmesh/tools/bmesh_decimate_dissolve.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/geometry/nodes/node_geo_dissolve.cc

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

diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 3feab285a09..d3b472f9975 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1447,7 +1447,7 @@ void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
 }
 
 /**
- * Use to temporary tag bmesh mesh data based on an array of bool.
+ * Use to temporary tag bmesh vertex data based on an array of bool.
  */
 void BM_temporary_tag_vertices(BMesh *bm, const bool *mask)
 {
@@ -1462,4 +1462,38 @@ void BM_temporary_tag_vertices(BMesh *bm, const bool *mask)
   }
 }
 
+/**
+ * Use to temporary tag bmesh edge data based on an array of bool.
+ */
+void BM_temporary_tag_edges(BMesh *bm, const bool *mask)
+{
+  BMIter iter;
+  BMEdge *e;
+  int i = 0;
+  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+    if (mask[i]) {
+      /* BM_ELEM_SELECT is used here instead of BM_ELEM_TAG because BM_ELEM_TAG does not work for
+       * some reason. */
+      BM_elem_flag_enable(e, BM_ELEM_SELECT);
+    }
+    i++;
+  }
+}
+
+/**
+ * Use to temporary tag bmesh face data based on an array of bool.
+ */
+void BM_temporary_tag_faces(BMesh *bm, const bool *mask)
+{
+  BMIter iter;
+  BMFace *f;
+  int i = 0;
+  BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+    if (mask[i]) {
+      BM_elem_flag_enable(f, BM_ELEM_TAG);
+    }
+    i++;
+  }
+}
+
 /** \} */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index cb9a481af83..3d1f4f7e40a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -135,3 +135,5 @@ void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
                                          const float (*vert_coords)[3],
                                          const float mat[4][4]);
 void BM_temporary_tag_vertices(BMesh *bm, const bool *mask);
+void BM_temporary_tag_edges(BMesh *bm, const bool *mask);
+void BM_temporary_tag_faces(BMesh *bm, const bool *mask);
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 0f9488bd091..4a92c2221f6 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -428,6 +428,8 @@ typedef enum {
   BMO_DELIM_SEAM = 1 << 2,
   BMO_DELIM_SHARP = 1 << 3,
   BMO_DELIM_UV = 1 << 4,
+  BMO_DELIM_EDGE_TAG = 1 << 5,
+  BMO_DELIM_FACE_TAG = 1 << 6,
 } BMO_Delimit;
 
 void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index d8a586acee5..c9eaab4a26f 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -104,6 +104,19 @@ static bool bm_edge_is_delimiter(const BMEdge *e,
   BLI_assert(BM_edge_is_manifold(e));
 
   if (delimit != 0) {
+    if (delimit & BMO_DELIM_EDGE_TAG) {
+      /* BM_ELEM_SELECT is used here instead of BM_ELEM_TAG because BM_ELEM_TAG does not work for
+       * some reason. */
+      if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+        return true;
+      }
+    }
+    if (delimit & BMO_DELIM_FACE_TAG) {
+      if (BM_elem_flag_test(e->l->f, BM_ELEM_TAG) !=
+          BM_elem_flag_test(e->l->radial_next->f, BM_ELEM_TAG)) {
+        return true;
+      }
+    }
     if (delimit & BMO_DELIM_SEAM) {
       if (BM_elem_flag_test(e, BM_ELEM_SEAM)) {
         return true;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 44ef75295d2..fa34f0000fc 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1962,11 +1962,12 @@ typedef enum GeometryNodeCollapseSymmetryAxis {
 } GeometryNodeCollapseSymmetryAxis;
 
 typedef enum GeometryNodeDissolveDelimiter {
-  GEO_NODE_DISSOLVE_DELIMITTER_NORMAL = 1 << 0,
-  GEO_NODE_DISSOLVE_DELIMITTER_MATERIAL = 1 << 1,
-  GEO_NODE_DISSOLVE_DELIMITTER_SEAM = 1 << 2,
-  GEO_NODE_DISSOLVE_DELIMITTER_SHARP = 1 << 3,
-  GEO_NODE_DISSOLVE_DELIMITTER_UV = 1 << 4,
+  /* Keep in sync with BMO_Delimit*/
+  GEO_NODE_DISSOLVE_DELIMITTER_EDGE = 1 << 5,
+  GEO_NODE_DISSOLVE_DELIMITTER_FACE = 1 << 6,
+  // GEO_NODE_DISSOLVE_DELIMITTER_SEAM = 1 << 2,
+  // GEO_NODE_DISSOLVE_DELIMITTER_SHARP = 1 << 3,
+  // GEO_NODE_DISSOLVE_DELIMITTER_UV = 1 << 4,
 } GeometryNodeDissolveDelimiter;
 
 #ifdef __cplusplus
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 7579e158fbc..1bec6b3db3d 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -10000,15 +10000,16 @@ static void def_geo_dissolve(StructRNA *srna)
   PropertyRNA *prop;
 
   static EnumPropertyItem delimiter_items[] = {
-      {GEO_NODE_DISSOLVE_DELIMITTER_NORMAL, "normal", 0, "Normal", "No Symmetry is applied"},
-      {GEO_NODE_DISSOLVE_DELIMITTER_MATERIAL,
-       "material",
+      {GEO_NODE_DISSOLVE_DELIMITTER_EDGE,
+       "edge",
        0,
-       "Material",
-       "Symmetry is applied on X axis"},
-      {GEO_NODE_DISSOLVE_DELIMITTER_SEAM, "seam", 0, "Seam", "Symmetry is applied on Y axis"},
-      {GEO_NODE_DISSOLVE_DELIMITTER_SHARP, "sharp", 0, "Sharp", "Symmetry is applied on Z axis"},
-      {GEO_NODE_DISSOLVE_DELIMITTER_UV, "uv", 0, "UV", "Symmetry is applied on Z axis"},
+       "Edge",
+       "Use edge attribute domain as delimiter"},
+      {GEO_NODE_DISSOLVE_DELIMITTER_FACE,
+       "face",
+       0,
+       "Face",
+       "Use face attribute domain as delimiter"},
       {0, NULL, 0, NULL, NULL},
   };
 
diff --git a/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc b/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc
index 79a6debfafc..c0980d43c5f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc
@@ -30,6 +30,7 @@
 static bNodeSocketTemplate geo_node_dissolve_in[] = {
     {SOCK_GEOMETRY, N_("Geometry")},
     {SOCK_FLOAT, N_("Angle"), M_PI * 0.25, 0.0f, 0.0f, 1.0f, 0.0f, M_PI, PROP_ANGLE},
+    {SOCK_STRING, N_("Delimiter")},
     {SOCK_BOOLEAN, N_("All Boundaries"), false},
     {-1, ""},
 };
@@ -52,21 +53,27 @@ static void geo_node_dissolve_init(bNodeTree *UNUSED(tree), bNode *node)
       sizeof(NodeGeometryDissolve), __func__);
 
   node->storage = node_storage;
-  node_storage->delimiter = GEO_NODE_DISSOLVE_DELIMITTER_NORMAL;
+  node_storage->delimiter = GEO_NODE_DISSOLVE_DELIMITTER_FACE;
 }
 
 namespace blender::nodes {
 static Mesh *dissolve_mesh(const float angle,
                            const bool all_boundaries,
-                           const int delimiter,
+                           const int delimiter_type,
+                           const Array<bool> &delimiter,
                            Mesh *mesh)
 {
-  BMeshCreateParams bmesh_create_params = {0};
-  BMeshFromMeshParams bmesh_from_mesh_params = {
+  const BMeshCreateParams bmesh_create_params = {0};
+  const BMeshFromMeshParams bmesh_from_mesh_params = {
       true, 0, 0, 0, {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX}};
   BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
-
-  BM_mesh_decimate_dissolve(bm, angle, all_boundaries, (BMO_Delimit)delimiter);
+  if (delimiter_type & GEO_NODE_DISSOLVE_DELIMITTER_FACE) {
+    BM_temporary_tag_faces(bm, delimiter.data());
+  }
+  else {
+    BM_temporary_tag_edges(bm, delimiter.data());
+  }
+  BM_mesh_decimate_dissolve(bm, angle, all_boundaries, (BMO_Delimit)delimiter_type);
 
   Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
   BM_mesh_free(bm);
@@ -92,7 +99,27 @@ static void geo_node_dissolve_exec(GeoNodeExecParams params)
     const bool all_boundaries = params.extract_input<bool>("All Boundaries");
     const bNode &node = params.node();
     const NodeGeometryDissolve &node_storage = *(NodeGeometryDissolve *)node.storage;
-    Mesh *result = dissolve_mesh(angle, all_boundaries, node_storage.delimiter, input_mesh);
+
+    const bool default_delimiter = true;
+    AttributeDomain delimiter_domain = ATTR_DOMAIN_FACE;
+    int delimiter_domain_size = input_mesh->totpoly;
+    if (node_storage.delimiter & GEO_NODE_DISSOLVE_DELIMITTER_EDGE) {
+      delimiter_domain = ATTR_DOMAIN_EDGE;
+      delimiter_domain_size = input_mesh->totedge;
+    };
+
+    const GVArrayPtr delimiter = params.get_input_attribute(
+        "Delimiter", mesh_component, delimiter_domain, CD_PROP_BOOL, &default_delimiter);
+    if (!delimiter) {
+      return;
+    }
+    const GVArray_Typed<bool> delimiter_as_typed = delimiter->typed<bool>();
+    Array<bool> mask(delimiter_domain_size);
+    for (const int i : delimiter_as_typed.index_range()) {
+      mask[i] = delimiter_as_typed[i];
+    }
+
+    Mesh *result = dissolve_mesh(angle, all_boundaries, node_storage.delimiter, mask, input_mesh);
     geometry_set.replace_mesh(result);
   }



More information about the Bf-blender-cvs mailing list