[Bf-blender-cvs] [0ec94d5359d] master: Geometry Nodes: Port weld modifier to the merge by distance node

Hans Goudey noreply at git.blender.org
Tue Jan 25 18:08:02 CET 2022


Commit: 0ec94d5359d732c5ed819379d601ab2124798079
Author: Hans Goudey
Date:   Tue Jan 25 11:07:12 2022 -0600
Branches: master
https://developer.blender.org/rB0ec94d5359d732c5ed819379d601ab2124798079

Geometry Nodes: Port weld modifier to the merge by distance node

This commit moves the weld modifier code to the geometry module
so that it can be used in the "Merge by Distance" geometry node
from ec1b0c2014a8b91c2. The "All" mode is exposed in the node
for now, though we could expose the "Connected" mode in the future.

The modifier itself is responsible for creating the selections from
the vertex group. The "All" mode takes an `IndexMask` for the
selection, and the "Connected" mode takes a boolean array,
since it actually iterates over all edges.

Some disabled code for a BVH mode has not been copied over,
it's still accessible through the patches and git history anyway,
and it made the port slightly simpler.

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

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

M	source/blender/geometry/CMakeLists.txt
A	source/blender/geometry/GEO_mesh_merge_by_distance.hh
A	source/blender/geometry/intern/mesh_merge_by_distance.cc
M	source/blender/modifiers/intern/MOD_weld.cc
M	source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc

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

diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt
index 9e0b53f4980..f7ddd393b4d 100644
--- a/source/blender/geometry/CMakeLists.txt
+++ b/source/blender/geometry/CMakeLists.txt
@@ -30,10 +30,12 @@ set(INC
 )
 
 set(SRC
+  intern/mesh_merge_by_distance.cc
   intern/mesh_to_curve_convert.cc
   intern/point_merge_by_distance.cc
   intern/realize_instances.cc
 
+  GEO_mesh_merge_by_distance.hh
   GEO_mesh_to_curve.hh
   GEO_point_merge_by_distance.hh
   GEO_realize_instances.hh
diff --git a/source/blender/geometry/GEO_mesh_merge_by_distance.hh b/source/blender/geometry/GEO_mesh_merge_by_distance.hh
new file mode 100644
index 00000000000..00ba45f9dd2
--- /dev/null
+++ b/source/blender/geometry/GEO_mesh_merge_by_distance.hh
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <optional>
+
+#include "BLI_index_mask.hh"
+#include "BLI_span.hh"
+
+struct Mesh;
+
+/** \file
+ * \ingroup geo
+ */
+
+namespace blender::geometry {
+
+/**
+ * Merge selected vertices into other selected vertices within the \a merge_distance. The merged
+ * indices favor speed over accuracy, since the results will depend on the order of the vertices.
+ *
+ * \returns std::nullopt if the mesh should not be changed (no vertices are merged), in order to
+ * avoid copying the input. Otherwise returns the new mesh with merged geoemetry.
+ */
+std::optional<Mesh *> mesh_merge_by_distance_all(const Mesh &mesh,
+                                                 IndexMask selection,
+                                                 float merge_distance);
+
+/**
+ * Merge selected vertices along edges to other selected vertices. Only vertices connected by edges
+ * are considered for merging.
+ *
+ * \returns std::nullopt if the mesh should not be changed (no vertices are merged), in order to
+ * avoid copying the input. Otherwise returns the new mesh with merged geoemetry.
+ */
+std::optional<Mesh *> mesh_merge_by_distance_connected(const Mesh &mesh,
+                                                       Span<bool> selection,
+                                                       float merge_distance,
+                                                       bool only_loose_edges);
+
+}  // namespace blender::geometry
diff --git a/source/blender/modifiers/intern/MOD_weld.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc
similarity index 79%
copy from source/blender/modifiers/intern/MOD_weld.cc
copy to source/blender/geometry/intern/mesh_merge_by_distance.cc
index 2d4710ca71a..e49848a030b 100644
--- a/source/blender/modifiers/intern/MOD_weld.cc
+++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc
@@ -12,73 +12,26 @@
  * 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.
- *
- * The Original Code is Copyright (C) 2005 by the Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup modifiers
- *
- * Weld modifier: Remove doubles.
  */
 
-/* TODOs:
- * - Review weight and vertex color interpolation.;
- */
-
-//#define USE_WELD_DEBUG
-//#define USE_WELD_NORMALS
-//#define USE_BVHTREEKDOP
-
-#include <algorithm>
-
-#include "MEM_guardedalloc.h"
-
-#include "BLI_utildefines.h"
-
 #include "BLI_array.hh"
-#include "BLI_bitmap.h"
-#include "BLI_index_range.hh"
+#include "BLI_index_mask.hh"
 #include "BLI_kdtree.h"
-#include "BLI_math.h"
-#include "BLI_span.hh"
+#include "BLI_math_vector.hh"
 #include "BLI_vector.hh"
 
-#include "BLT_translation.h"
-
-#include "DNA_defaults.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_screen_types.h"
 
-#ifdef USE_BVHTREEKDOP
-#  include "BKE_bvhutils.h"
-#endif
-
-#include "BKE_context.h"
-#include "BKE_deform.h"
+#include "BKE_customdata.h"
 #include "BKE_mesh.h"
-#include "BKE_modifier.h"
-#include "BKE_screen.h"
-
-#include "UI_interface.h"
-#include "UI_resources.h"
 
-#include "RNA_access.h"
+#include "GEO_mesh_merge_by_distance.hh"
 
-#include "DEG_depsgraph.h"
-
-#include "MOD_modifiertypes.h"
-#include "MOD_ui_common.h"
+//#define USE_WELD_DEBUG
+//#define USE_WELD_NORMALS
 
-using blender::Array;
-using blender::IndexRange;
-using blender::MutableSpan;
-using blender::Span;
-using blender::Vector;
+namespace blender::geometry {
 
 /* Indicates when the element was not computed. */
 #define OUT_OF_CONTEXT (int)(-1)
@@ -375,7 +328,7 @@ static void weld_assert_poly_len(const WeldPoly *wp, const Span<WeldLoop> wloop)
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Weld Vert API
+/** \name Vert API
  * \{ */
 
 static Vector<WeldVert> weld_vert_ctx_alloc_and_setup(Span<int> vert_dest_map,
@@ -451,9 +404,44 @@ static void weld_vert_groups_setup(Span<WeldVert> wvert,
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Weld Edge API
+/** \name Edge API
  * \{ */
 
+static Vector<WeldEdge> weld_edge_ctx_alloc(Span<MEdge> medge,
+                                            Span<int> vert_dest_map,
+                                            MutableSpan<int> r_edge_dest_map,
+                                            MutableSpan<int> r_edge_ctx_map)
+{
+  /* Edge Context. */
+  int wedge_len = 0;
+
+  Vector<WeldEdge> wedge;
+  wedge.reserve(medge.size());
+
+  for (const int i : medge.index_range()) {
+    int v1 = medge[i].v1;
+    int v2 = medge[i].v2;
+    int v_dest_1 = vert_dest_map[v1];
+    int v_dest_2 = vert_dest_map[v2];
+    if ((v_dest_1 != OUT_OF_CONTEXT) || (v_dest_2 != OUT_OF_CONTEXT)) {
+      WeldEdge we{};
+      we.vert_a = (v_dest_1 != OUT_OF_CONTEXT) ? v_dest_1 : v1;
+      we.vert_b = (v_dest_2 != OUT_OF_CONTEXT) ? v_dest_2 : v2;
+      we.edge_dest = OUT_OF_CONTEXT;
+      we.edge_orig = i;
+      wedge.append(we);
+      r_edge_dest_map[i] = i;
+      r_edge_ctx_map[i] = wedge_len++;
+    }
+    else {
+      r_edge_dest_map[i] = OUT_OF_CONTEXT;
+      r_edge_ctx_map[i] = OUT_OF_CONTEXT;
+    }
+  }
+
+  return wedge;
+}
+
 static void weld_edge_ctx_setup(MutableSpan<WeldGroup> r_vlinks,
                                 MutableSpan<int> r_edge_dest_map,
                                 MutableSpan<WeldEdge> r_wedge,
@@ -566,41 +554,6 @@ static void weld_edge_ctx_setup(MutableSpan<WeldGroup> r_vlinks,
   *r_edge_kiil_len = edge_kill_len;
 }
 
-static Vector<WeldEdge> weld_edge_ctx_alloc(Span<MEdge> medge,
-                                            Span<int> vert_dest_map,
-                                            MutableSpan<int> r_edge_dest_map,
-                                            MutableSpan<int> r_edge_ctx_map)
-{
-  /* Edge Context. */
-  int wedge_len = 0;
-
-  Vector<WeldEdge> wedge;
-  wedge.reserve(medge.size());
-
-  for (const int i : medge.index_range()) {
-    int v1 = medge[i].v1;
-    int v2 = medge[i].v2;
-    int v_dest_1 = vert_dest_map[v1];
-    int v_dest_2 = vert_dest_map[v2];
-    if ((v_dest_1 != OUT_OF_CONTEXT) || (v_dest_2 != OUT_OF_CONTEXT)) {
-      WeldEdge we{};
-      we.vert_a = (v_dest_1 != OUT_OF_CONTEXT) ? v_dest_1 : v1;
-      we.vert_b = (v_dest_2 != OUT_OF_CONTEXT) ? v_dest_2 : v2;
-      we.edge_dest = OUT_OF_CONTEXT;
-      we.edge_orig = i;
-      wedge.append(we);
-      r_edge_dest_map[i] = i;
-      r_edge_ctx_map[i] = wedge_len++;
-    }
-    else {
-      r_edge_dest_map[i] = OUT_OF_CONTEXT;
-      r_edge_ctx_map[i] = OUT_OF_CONTEXT;
-    }
-  }
-
-  return wedge;
-}
-
 static void weld_edge_groups_setup(const int medge_len,
                                    const int edge_kill_len,
                                    MutableSpan<WeldEdge> wedge,
@@ -676,7 +629,7 @@ static void weld_edge_groups_setup(const int medge_len,
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Weld Poly and Loop API
+/** \name Poly and Loop API
  * \{ */
 
 static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter &iter,
@@ -1248,7 +1201,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Weld Mesh API
+/** \name Mesh API
  * \{ */
 
 static void weld_mesh_context_create(const Mesh &mesh,
@@ -1304,7 +1257,7 @@ static void weld_mesh_context_create(const Mesh &mesh,
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Weld CustomData
+/** \name CustomData
  * \{ */
 
 static void customdata_weld(
@@ -1445,246 +1398,22 @@ static void customdata_weld(
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name Weld Modifier Main
+/** \name Mesh Vertex Merging
  * \{ */
 
-#ifdef USE_BVHTREEKDOP
-struct WeldOverlapData {
-  const MVert *mvert;
-  float merge_dist_sq;
-};
-static bool bvhtree_weld_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread))
-{
-  if (index_a < index_b) {
-    struct WeldOverlapData *data = userdata;
-    const MVert *mvert = data->mvert;
-    const float dist_sq = len_squared_v3v3(mvert[index_a].co, mvert[index_b].co);
-    BLI_assert(dist_sq <= ((data->merge_dist_sq + FLT_EPSILON) * 3));
-    return dist_sq <= data->merge_dist_sq;
-  }
-  return false;
-}
-#endif
-
-/** Use for #MOD_WELD_MODE_CONNECTED calculation. */
-struct WeldVertexCluster {
-  float co[3];
- 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list