[Bf-blender-cvs] [75b337a2935] temp-geometry-nodes-extrude-mesh: Working face extrusion except for middle vertex offset

Hans Goudey noreply at git.blender.org
Mon Dec 27 23:03:20 CET 2021


Commit: 75b337a2935c94f30a274cd25fdf34690cbdf7b0
Author: Hans Goudey
Date:   Mon Dec 27 16:03:13 2021 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rB75b337a2935c94f30a274cd25fdf34690cbdf7b0

Working face extrusion except for middle vertex offset

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenlib/BLI_span.hh
M	source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index c39583d234a..5c25fb336e5 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -25,6 +25,12 @@
 #include "BKE_mesh_types.h"
 #include "BLI_utildefines.h"
 
+#ifdef __cplusplus
+#  include "BLI_span.hh"
+#  include "DNA_mesh_types.h"
+#  include "DNA_meshdata_types.h"
+#endif
+
 struct BLI_Stack;
 struct BMesh;
 struct BMeshCreateParams;
@@ -984,3 +990,47 @@ BLI_INLINE int BKE_mesh_origindex_mface_mpoly(const int *index_mf_to_mpoly,
 #ifdef __cplusplus
 }
 #endif
+
+#ifdef __cplusplus
+
+namespace blender::bke {
+
+inline Span<MVert> mesh_verts(const Mesh &mesh)
+{
+  return {mesh.mvert, mesh.totvert};
+}
+inline MutableSpan<MVert> mesh_verts(Mesh &mesh)
+{
+  return {mesh.mvert, mesh.totvert};
+}
+
+inline Span<MEdge> mesh_edges(const Mesh &mesh)
+{
+  return {mesh.medge, mesh.totedge};
+}
+inline MutableSpan<MEdge> mesh_edges(Mesh &mesh)
+{
+  return {mesh.medge, mesh.totedge};
+}
+
+inline Span<MPoly> mesh_polys(const Mesh &mesh)
+{
+  return {mesh.mpoly, mesh.totpoly};
+}
+inline MutableSpan<MPoly> mesh_polys(Mesh &mesh)
+{
+  return {mesh.mpoly, mesh.totpoly};
+}
+
+inline Span<MLoop> mesh_loops(const Mesh &mesh)
+{
+  return {mesh.mloop, mesh.totloop};
+}
+inline MutableSpan<MLoop> mesh_loops(Mesh &mesh)
+{
+  return {mesh.mloop, mesh.totloop};
+}
+
+}  // namespace blender::bke
+
+#endif
\ No newline at end of file
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index 5b7981e0302..995dc70a84d 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -599,6 +599,11 @@ template<typename T> class MutableSpan {
     return MutableSpan(data_ + start, new_size);
   }
 
+  constexpr MutableSpan slice(IndexRange range) const
+  {
+    return this->slice(range.start(), range.size());
+  }
+
   /**
    * Returns a new MutableSpan with n elements removed from the beginning. This invokes
    * undefined behavior when n is negative.
diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
index 6589ad3ce04..589cd9e5fed 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -34,6 +34,7 @@ NODE_STORAGE_FUNCS(NodeGeometryExtrudeMesh)
 
 /* TODO: Decide whether to transfer attributes by topology proximity to new faces, corners, and
  * edges. */
+/* TODO: Deduplicate edge extrusion between edge and face modes. */
 
 static void node_declare(NodeDeclarationBuilder &b)
 {
@@ -57,6 +58,35 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
   node->storage = data;
 }
 
+static void expand_mesh_size(Mesh &mesh,
+                             const int vert_expand,
+                             const int edge_expand,
+                             const int poly_expand,
+                             const int loop_expand)
+{
+  if (vert_expand != 0) {
+    mesh.totvert += vert_expand;
+    CustomData_duplicate_referenced_layers(&mesh.vdata, mesh.totvert);
+    CustomData_realloc(&mesh.vdata, mesh.totvert);
+  }
+  if (edge_expand != 0) {
+    mesh.totedge += edge_expand;
+    CustomData_duplicate_referenced_layers(&mesh.edata, mesh.totedge);
+    CustomData_realloc(&mesh.edata, mesh.totedge);
+  }
+  if (poly_expand != 0) {
+    mesh.totpoly += poly_expand;
+    CustomData_duplicate_referenced_layers(&mesh.pdata, mesh.totpoly);
+    CustomData_realloc(&mesh.pdata, mesh.totpoly);
+  }
+  if (loop_expand != 0) {
+    mesh.totloop += loop_expand;
+    CustomData_duplicate_referenced_layers(&mesh.ldata, mesh.totloop);
+    CustomData_realloc(&mesh.ldata, mesh.totloop);
+  }
+  BKE_mesh_update_customdata_pointers(&mesh, false);
+}
+
 static void extrude_mesh_vertices(MeshComponent &component,
                                   const Field<bool> &selection_field,
                                   const Field<float3> &offset_field)
@@ -72,17 +102,7 @@ static void extrude_mesh_vertices(MeshComponent &component,
   const VArray<float3> offsets = evaluator.get_evaluated<float3>(0);
 
   const int orig_vert_size = mesh.totvert;
-  mesh.totvert += selection.size();
-  mesh.totedge += selection.size();
-
-  /* TODO: This is a stupid way to work around an issue with #CustomData_realloc,
-   * which doesn't reallocate a referenced layer apparently. */
-  CustomData_duplicate_referenced_layers(&mesh.vdata, mesh.totvert);
-  CustomData_duplicate_referenced_layers(&mesh.edata, mesh.totedge);
-
-  CustomData_realloc(&mesh.vdata, mesh.totvert);
-  CustomData_realloc(&mesh.edata, mesh.totedge);
-  BKE_mesh_update_customdata_pointers(&mesh, false);
+  expand_mesh_size(mesh, selection.size(), selection.size(), 0, 0);
 
   MutableSpan<MVert> verts{mesh.mvert, mesh.totvert};
   MutableSpan<MEdge> edges{mesh.medge, mesh.totedge};
@@ -136,18 +156,13 @@ static void extrude_mesh_vertices(MeshComponent &component,
 //   selected_edges_of_verts[edge.v2].append(i);
 // }
 
-struct CopiedVert {
-  int orig_index;
-  // int new_index;
-};
-
 static void extrude_mesh_edges(MeshComponent &component,
                                const Field<bool> &selection_field,
                                const Field<float3> &offset_field)
 {
   Mesh &mesh = *component.get_for_write();
   const int orig_vert_size = mesh.totvert;
-  const int orig_edge_size = mesh.totedge;
+  Span<MEdge> orig_edges{mesh.medge, mesh.totedge};
   const int orig_loop_size = mesh.totloop;
 
   GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE};
@@ -162,7 +177,7 @@ static void extrude_mesh_edges(MeshComponent &component,
   Vector<int> extrude_vert_orig_indices;
   extrude_vert_orig_indices.reserve(selection.size());
   for (const int i_edge : selection) {
-    const MEdge &edge = mesh.medge[i_edge];
+    const MEdge &edge = orig_edges[i_edge];
 
     if (extrude_vert_indices[edge.v1] == -1) {
       extrude_vert_indices[edge.v1] = orig_vert_size + extrude_vert_orig_indices.size();
@@ -175,40 +190,25 @@ static void extrude_mesh_edges(MeshComponent &component,
     }
   }
 
+  Array<float3> offsets(orig_vert_size);
   GeometryComponentFieldContext point_context{component, ATTR_DOMAIN_POINT};
-  FieldEvaluator point_evaluator{point_context, mesh.totvert}; /* TODO: Better selection. */
-  point_evaluator.add(offset_field);
+  FieldEvaluator point_evaluator{point_context, orig_vert_size}; /* TODO: Better selection. */
+  point_evaluator.add_with_destination(offset_field, offsets.as_mutable_span());
   point_evaluator.evaluate();
-  const VArray<float3> offsets = point_evaluator.get_evaluated<float3>(0);
 
-  const int extrude_vert_size = extrude_vert_orig_indices.size();
-  const int extrude_edge_offset = orig_edge_size;
-  const int extrude_edge_size = extrude_vert_size;
-  const int duplicate_edge_offset = orig_edge_size + extrude_vert_size;
+  const IndexRange extrude_vert_range{orig_vert_size, extrude_vert_orig_indices.size()};
+  const int extrude_edge_offset = orig_edges.size();
+  const int extrude_edge_size = extrude_vert_range.size();
+  const int duplicate_edge_offset = orig_edges.size() + extrude_vert_range.size();
   const int duplicate_edge_size = selection.size();
   const int new_edge_size = extrude_edge_size + duplicate_edge_size;
   const int new_poly_size = selection.size();
   const int new_loop_size = new_poly_size * 4;
 
-  /* TODO: This is a stupid way to work around an issue with #CustomData_realloc,
-   * which doesn't reallocate a referenced layer apparently. */
-  CustomData_duplicate_referenced_layers(&mesh.vdata, mesh.totvert);
-  CustomData_duplicate_referenced_layers(&mesh.edata, mesh.totedge);
-  CustomData_duplicate_referenced_layers(&mesh.pdata, mesh.totpoly);
-  CustomData_duplicate_referenced_layers(&mesh.ldata, mesh.totloop);
-
-  mesh.totvert += extrude_vert_size;
-  mesh.totedge += new_edge_size;
-  mesh.totpoly += selection.size();
-  mesh.totloop += selection.size() * 4;
-  CustomData_realloc(&mesh.vdata, mesh.totvert);
-  CustomData_realloc(&mesh.edata, mesh.totedge);
-  CustomData_realloc(&mesh.pdata, mesh.totpoly);
-  CustomData_realloc(&mesh.ldata, mesh.totloop);
-  BKE_mesh_update_customdata_pointers(&mesh, false);
+  expand_mesh_size(mesh, extrude_vert_range.size(), new_edge_size, new_poly_size, new_loop_size);
 
   MutableSpan<MVert> verts{mesh.mvert, mesh.totvert};
-  MutableSpan<MVert> new_verts = verts.take_back(extrude_vert_size);
+  MutableSpan<MVert> new_verts = verts.slice(extrude_vert_range);
   MutableSpan<MEdge> edges{mesh.medge, mesh.totedge};
   MutableSpan<MEdge> extrude_edges = edges.slice(extrude_edge_offset, extrude_edge_size);
   MutableSpan<MEdge> duplicate_edges = edges.slice(duplicate_edge_offset, duplicate_edge_size);
@@ -243,7 +243,7 @@ static void extrude_mesh_edges(MeshComponent &component,
   /* Maps new vertices to the extruded edges connecting them to the original edges. The values are
    * indices into the `extrude_edges` array, and the element index corresponds to the vert in
    * `new_verts` of the same index. */
-  Array<int> new_vert_to_extrude_edge(extrude_vert_size);
+  Array<int> new_vert_to_extrude_edge(extrude_vert_range.size());
   for (const int i : extrude_edges.index_range()) {
     const MEdge &extrude_edge = extrude_edges[i];
     BLI_assert(extrude_edge.v1 >= orig_vert_size || extrude_edge.v2 >= orig_vert_size);
@@ -283,7 +283,7 @@ static void extrude_mesh_edges(MeshComponent &component,
       attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
         using T = decltype(dummy);
         MutableSpan<T> data = attribute.as_span().typed<T>();
-        MutableSpan<T> new_data = data.take_back(extrude_vert_size);
+        MutableSpan<T> new_data = data.slice(extrude_vert_range);
 
         for (const int i : extrude_vert_orig_indices.index_range()) {
           new_data[i] = data[extrude_vert_orig_indices[i]];
@@ -311,13 +311,265 @@ static void extrude_mesh_edges(MeshComponent &component,
     return true;
   });
 
-  devirtualize_varray(offsets, [&](const auto offsets) {
-    threading::parallel_for(new_verts.inde

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list