[Bf-blender-cvs] [2a78b7acb0a] temp-geometry-nodes-extrude-mesh: Fix problem with inner edges also connected to unselected faces

Hans Goudey noreply at git.blender.org
Fri Jan 21 06:40:43 CET 2022


Commit: 2a78b7acb0ac6414b11c618b0cd9acd740fafca1
Author: Hans Goudey
Date:   Thu Jan 20 23:40:35 2022 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rB2a78b7acb0ac6414b11c618b0cd9acd740fafca1

Fix problem with inner edges also connected to unselected faces

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

M	source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc

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

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 ddcfcca244f..62f7b2a1c20 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -74,10 +74,6 @@ static MutableSpan<MVert> mesh_verts(Mesh &mesh)
 {
   return {mesh.mvert, mesh.totvert};
 }
-static Span<MEdge> mesh_edges(const Mesh &mesh)
-{
-  return {mesh.medge, mesh.totedge};
-}
 static MutableSpan<MEdge> mesh_edges(Mesh &mesh)
 {
   return {mesh.medge, mesh.totedge};
@@ -123,11 +119,11 @@ static void save_selection_as_attribute(MeshComponent &component,
   attribute.save();
 }
 
-static void expand_mesh_size(Mesh &mesh,
-                             const int vert_expand,
-                             const int edge_expand,
-                             const int poly_expand,
-                             const int loop_expand)
+static void expand_mesh(Mesh &mesh,
+                        const int vert_expand,
+                        const int edge_expand,
+                        const int poly_expand,
+                        const int loop_expand)
 {
   if (vert_expand != 0) {
     CustomData_duplicate_referenced_layers(&mesh.vdata, mesh.totvert);
@@ -255,7 +251,7 @@ static void extrude_mesh_vertices(MeshComponent &component,
   /* This allows parallelizing attribute mixing for new edges. */
   Array<Vector<int>> vert_to_edge_map = create_vert_to_edge_map(orig_vert_size, mesh_edges(mesh));
 
-  expand_mesh_size(mesh, selection.size(), selection.size(), 0, 0);
+  expand_mesh(mesh, selection.size(), selection.size(), 0, 0);
 
   const IndexRange new_vert_range{orig_vert_size, selection.size()};
   const IndexRange new_edge_range{orig_edge_size, selection.size()};
@@ -284,10 +280,9 @@ static void extrude_mesh_vertices(MeshComponent &component,
         }
         case ATTR_DOMAIN_EDGE: {
           /* New edge values are mixed from of all the edges connected to the source vertex. */
-          copy_with_mixing(
-              data.slice(new_edge_range), data.as_span(), [&](const int i) -> Span<int> {
-                return vert_to_edge_map[selection[i]];
-              });
+          copy_with_mixing(data.slice(new_edge_range), data.as_span(), [&](const int i) {
+            return vert_to_edge_map[selection[i]].as_span();
+          });
           break;
         }
         default:
@@ -438,11 +433,11 @@ static void extrude_mesh_edges(MeshComponent &component,
 
   Array<Vector<int, 2>> edge_to_poly_map = mesh_calculate_polys_of_edge(mesh);
 
-  expand_mesh_size(mesh,
-                   new_vert_range.size(),
-                   connect_edge_range.size() + boundary_edge_range.size(),
-                   new_poly_range.size(),
-                   new_loop_range.size());
+  expand_mesh(mesh,
+              new_vert_range.size(),
+              connect_edge_range.size() + boundary_edge_range.size(),
+              new_poly_range.size(),
+              new_loop_range.size());
 
   MutableSpan<MVert> new_verts = mesh_verts(mesh).slice(new_vert_range);
   MutableSpan<MEdge> connect_edges = mesh_edges(mesh).slice(connect_edge_range);
@@ -653,7 +648,7 @@ static void extrude_mesh_edges(MeshComponent &component,
 
 /**
  * Edges connected to one selected face are on the boundary of a region and will be duplicated into
- * a "side face".
+ * a "side face". Edges inside a region will be duplicated to leave any original faces unchanged.
  */
 static void extrude_mesh_face_regions(MeshComponent &component,
                                       const Field<bool> &selection_field,
@@ -713,10 +708,11 @@ static void extrude_mesh_face_regions(MeshComponent &component,
     }
   }
 
-  /* TODO: Some edges are "in between" but also duplicated. */
-  // Vector<int> duplicate_inner_edge_indices;
-  /* These edges are on top of an extruded region. Their vertices should be translated with the
-   * offset, but the edges themselves should not be duplicated. */
+  /* Edges inside of an extruded region that are also attached to deselected edges. They must be
+   * duplicated in order to leave the old edge attached to the unchanged deselected faces. */
+  VectorSet<int> new_inner_edge_indices;
+  /* Edges inside of an extruded region. Their vertices should be translated
+   * with the offset, but the edges themselves should not be duplicated. */
   Vector<int> inner_edge_indices;
   /* The extruded face corresponding to each boundary edge (and each boundary face). */
   Vector<int> edge_extruded_face_indices;
@@ -740,36 +736,62 @@ static void extrude_mesh_face_regions(MeshComponent &component,
     }
 
     if (selected_poly_count == 1) {
+      /* If there is only one selected polygon connected to the edge,
+       * the edge should be extruded to form a "side face". */
       boundary_edge_indices.add_new(i_edge);
       edge_extruded_face_indices.append(i_selected_poly);
     }
     else if (selected_poly_count > 1) {
-      inner_edge_indices.append(i_edge);
+      /* The edge is inside an extruded region of faces. */
+      if (deselected_poly_count > 0) {
+        /* Add edges that are also connected to deselected edges to a separate list. */
+        new_inner_edge_indices.add_new(i_edge);
+      }
+      else {
+        /* Otherwise, just keep track of edges inside the region so that
+         * we can reattach them to duplicated vertices if necessary. */
+        inner_edge_indices.append(i_edge);
+      }
     }
   }
 
-  const VectorSet<int> new_vert_indices = vert_indices_from_edges(mesh,
-                                                                  boundary_edge_indices.as_span());
+  VectorSet<int> new_vert_indices = vert_indices_from_edges(mesh, boundary_edge_indices.as_span());
+  /* Before adding the rest of the new vertices from the new inner edges, store the number
+   * of new vertices from the boundary edges, since this is the number of connecting edges. */
+  const int extruded_vert_size = new_vert_indices.size();
 
+  /* The vertices attached to duplicate inner edges also have to be duplicated. */
+  for (const int i_edge : new_inner_edge_indices) {
+    const MEdge &edge = mesh.medge[i_edge];
+    new_vert_indices.add(edge.v1);
+    new_vert_indices.add(edge.v2);
+  }
+
+  /* New vertices forming the duplicated boundary edges and the ends of the new inner edges. */
   const IndexRange new_vert_range{orig_vert_size, new_vert_indices.size()};
   /* One edge connects each selected vertex to a new vertex on the extruded polygons. */
-  const IndexRange connect_edge_range{orig_edges.size(), new_vert_range.size()};
+  const IndexRange connect_edge_range{orig_edges.size(), extruded_vert_size};
   /* Each selected edge is duplicated to form a single edge on the extrusion. */
   const IndexRange boundary_edge_range{connect_edge_range.one_after_last(),
                                        boundary_edge_indices.size()};
+  /* Duplicated edges inside regions that were connected to deselected faces. */
+  const IndexRange new_inner_edge_range{boundary_edge_range.one_after_last(),
+                                        new_inner_edge_indices.size()};
   /* Each edge selected for extrusion is extruded into a single face. */
   const IndexRange side_poly_range{orig_polys.size(), boundary_edge_indices.size()};
+  /* The loops that form the new side faces. */
   const IndexRange side_loop_range{orig_loops.size(), side_poly_range.size() * 4};
 
-  expand_mesh_size(mesh,
-                   new_vert_range.size(),
-                   connect_edge_range.size() + boundary_edge_range.size(),
-                   side_poly_range.size(),
-                   side_loop_range.size());
+  expand_mesh(mesh,
+              new_vert_range.size(),
+              connect_edge_range.size() + boundary_edge_range.size() + new_inner_edge_range.size(),
+              side_poly_range.size(),
+              side_loop_range.size());
 
   MutableSpan<MEdge> edges = mesh_edges(mesh);
   MutableSpan<MEdge> connect_edges = edges.slice(connect_edge_range);
   MutableSpan<MEdge> boundary_edges = edges.slice(boundary_edge_range);
+  MutableSpan<MEdge> new_inner_edges = edges.slice(new_inner_edge_range);
   MutableSpan<MPoly> polys = mesh_polys(mesh);
   MutableSpan<MPoly> new_polys = polys.slice(side_poly_range);
   MutableSpan<MLoop> loops = mesh_loops(mesh);
@@ -788,12 +810,20 @@ static void extrude_mesh_face_regions(MeshComponent &component,
     boundary_edges[i] = new_edge(new_vert_range[i_new_vert_1], new_vert_range[i_new_vert_2]);
   }
 
+  /* Initialize the new edges inside of extrude regions. */
+  for (const int i : new_inner_edge_indices.index_range()) {
+    const MEdge &orig_edge = edges[new_inner_edge_indices[i]];
+    const int i_new_vert_1 = new_vert_indices.index_of(orig_edge.v1);
+    const int i_new_vert_2 = new_vert_indices.index_of(orig_edge.v2);
+    new_inner_edges[i] = new_edge(new_vert_range[i_new_vert_1], new_vert_range[i_new_vert_2]);
+  }
+
   /* Initialize the new side polygons. */
   for (const int i : new_polys.index_range()) {
     new_polys[i] = new_poly(side_loop_range[i * 4], 4);
   }
 
-  /* Connect original edges that are in between two selected faces to the new vertices. */
+  /* Connect original edges inside face regions to any new vertices, if necessary. */
   for (const int i : inner_edge_indices) {
     MEdge &edge = edges[i];
     const int i_new_vert_1 = new_vert_indices.index_of_try(edge.v1);
@@ -817,6 +847,11 @@ static void extrude_mesh_face_regions(MeshComponent &component,
       const int i_boundary_edge = boundary_edge_indices.index_of_try(loop.e);
       if (i_boundary_edge != -1) {
         loop.e = boundary_edge_range[i_boundary_edge];
+        continue;
+      }
+      const int i_new_inner_edge = new_inner_edge_indices.index_of_try(loop.e);
+      if (i_new_inner_edge != -1) {
+        loop.e = new_inner_edge_range[i_new_inner_edge];
       }
     }
   }
@@ -869,6 +904,10 @@ static void extrude_mesh_face_regions(MeshComponent &component,
           MutableSpan<T> boundary_data = data.slice(boundary_edge_range);
           copy_with_indices(boundary_data, data.as_span(), boundary_edge_indices);
 
+  

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list