[Bf-blender-cvs] [0989a02c68a] temp-geometry-nodes-extrude-mesh: Fix face orientation for one connected face in edge mode

Hans Goudey noreply at git.blender.org
Tue Jan 4 22:36:25 CET 2022


Commit: 0989a02c68a9095a14750e5cbec3473c45567efb
Author: Hans Goudey
Date:   Tue Jan 4 15:32:59 2022 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rB0989a02c68a9095a14750e5cbec3473c45567efb

Fix face orientation for one connected face in edge mode

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

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 694ce075ffc..e637dae33b7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -128,9 +128,10 @@ static void expand_mesh_size(Mesh &mesh,
   }
 }
 
-static Array<Vector<int>> create_vert_to_edge_map(const int vert_size, Span<MEdge> edges)
+static Array<Vector<int>> create_vert_to_edge_map(const Mesh &mesh)
 {
-  Array<Vector<int>> vert_to_edge_map(vert_size);
+  Span<MEdge> edges = bke::mesh_edges(mesh);
+  Array<Vector<int>> vert_to_edge_map(mesh.totvert);
   for (const int i : edges.index_range()) {
     vert_to_edge_map[edges[i].v1].append(i);
     vert_to_edge_map[edges[i].v2].append(i);
@@ -155,6 +156,8 @@ static void extrude_mesh_vertices(MeshComponent &component,
   const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
   const VArray<float3> offsets = evaluator.get_evaluated<float3>(0);
 
+  Array<Vector<int>> vert_to_edge_map = create_vert_to_edge_map(mesh);
+
   expand_mesh_size(mesh, selection.size(), selection.size(), 0, 0);
 
   const IndexRange new_vert_range{orig_vert_size, selection.size()};
@@ -170,9 +173,6 @@ static void extrude_mesh_vertices(MeshComponent &component,
     edge.flag = ME_LOOSEEDGE;
   }
 
-  Array<Vector<int>> vert_to_edge_map = create_vert_to_edge_map(
-      orig_vert_size, bke::mesh_edges(mesh).take_front(orig_edge_size));
-
   component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
     if (!ELEM(meta_data.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE)) {
       return true;
@@ -246,6 +246,63 @@ static void extrude_mesh_vertices(MeshComponent &component,
   BLI_assert(BKE_mesh_is_valid(component.get_for_write()));
 }
 
+static Array<Vector<int, 2>> mesh_calculate_polys_of_edge(const Mesh &mesh)
+{
+  Span<MPoly> polys = bke::mesh_polys(mesh);
+  Span<MLoop> loops = bke::mesh_loops(mesh);
+  Array<Vector<int, 2>> polys_of_edge(mesh.totedge);
+
+  for (const int poly_index : polys.index_range()) {
+    const MPoly &poly = polys[poly_index];
+    for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
+      polys_of_edge[loop.e].append(poly_index);
+    }
+  }
+
+  return polys_of_edge;
+}
+
+static void fill_quad_consistent_direction(Span<MLoop> other_poly_loops,
+                                           MutableSpan<MLoop> new_loops,
+                                           const int vert_connected_to_poly_1,
+                                           const int vert_connected_to_poly_2,
+                                           const int vert_across_from_poly_1,
+                                           const int vert_across_from_poly_2,
+                                           const int edge_connected_to_poly,
+                                           const int connecting_edge_1,
+                                           const int edge_across_from_poly,
+                                           const int connecting_edge_2)
+{
+  /* Find the loop on the polygon connected to the new quad that uses the duplicate edge. */
+  bool start_with_connecting_edge = true;
+  for (const MLoop &loop : other_poly_loops) {
+    if (loop.e == edge_connected_to_poly) {
+      start_with_connecting_edge = loop.v == vert_connected_to_poly_1;
+      break;
+    }
+  }
+  if (start_with_connecting_edge) {
+    new_loops[0].v = vert_connected_to_poly_1;
+    new_loops[0].e = connecting_edge_1;
+    new_loops[1].v = vert_across_from_poly_1;
+    new_loops[1].e = edge_across_from_poly;
+    new_loops[2].v = vert_across_from_poly_2;
+    new_loops[2].e = connecting_edge_2;
+    new_loops[3].v = vert_connected_to_poly_2;
+    new_loops[3].e = edge_connected_to_poly;
+  }
+  else {
+    new_loops[0].v = vert_connected_to_poly_1;
+    new_loops[0].e = edge_connected_to_poly;
+    new_loops[1].v = vert_connected_to_poly_2;
+    new_loops[1].e = connecting_edge_2;
+    new_loops[2].v = vert_across_from_poly_2;
+    new_loops[2].e = edge_across_from_poly;
+    new_loops[3].v = vert_across_from_poly_1;
+    new_loops[3].e = connecting_edge_1;
+  }
+}
+
 /**
  * The resulting vector maps from the index in the added vertices to the original vertex they were
  * extruded from.
@@ -310,6 +367,8 @@ static void extrude_mesh_edges(MeshComponent &component,
   /* Every new polygon is a quad with four corners. */
   const IndexRange new_loop_range{orig_loop_size, new_poly_range.size() * 4};
 
+  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() + duplicate_edge_range.size(),
@@ -319,8 +378,10 @@ static void extrude_mesh_edges(MeshComponent &component,
   MutableSpan<MVert> new_verts = bke::mesh_verts(mesh).slice(new_vert_range);
   MutableSpan<MEdge> connect_edges = bke::mesh_edges(mesh).slice(connect_edge_range);
   MutableSpan<MEdge> duplicate_edges = bke::mesh_edges(mesh).slice(duplicate_edge_range);
-  MutableSpan<MPoly> new_polys = bke::mesh_polys(mesh).slice(new_poly_range);
-  MutableSpan<MLoop> new_loops = bke::mesh_loops(mesh).slice(new_loop_range);
+  MutableSpan<MPoly> polys = bke::mesh_polys(mesh);
+  MutableSpan<MPoly> new_polys = polys.slice(new_poly_range);
+  MutableSpan<MLoop> loops = bke::mesh_loops(mesh);
+  MutableSpan<MLoop> new_loops = loops.slice(new_loop_range);
 
   for (const int i : connect_edges.index_range()) {
     MEdge &edge = connect_edges[i];
@@ -345,31 +406,35 @@ static void extrude_mesh_edges(MeshComponent &component,
     poly.flag = 0;
   }
 
-  /* TODO: Figure out winding order for new faces. */
   for (const int i : edge_selection.index_range()) {
-    MutableSpan<MLoop> poly_loops = new_loops.slice(4 * i, 4);
     const int orig_edge_index = edge_selection[i];
-    const MEdge &duplicate_edge = duplicate_edges[i];
 
+    const MEdge &duplicate_edge = duplicate_edges[i];
     const int new_vert_1 = duplicate_edge.v1;
     const int new_vert_2 = duplicate_edge.v2;
     const int extrude_index_1 = new_vert_1 - orig_vert_size;
     const int extrude_index_2 = new_vert_2 - orig_vert_size;
-    const int orig_vert_index_1 = new_vert_orig_indices[extrude_index_1];
-    const int orig_vert_index_2 = new_vert_orig_indices[extrude_index_2];
-
-    /* Add the start vertex and edge along the original edge. */
-    poly_loops[0].v = orig_vert_index_1;
-    poly_loops[0].e = orig_edge_index;
-    /* Add the other vertex of the original edge and the first extrusion edge. */
-    poly_loops[1].v = orig_vert_index_2;
-    poly_loops[1].e = connect_edge_range[extrude_index_2];
-    /* Add the first new vertex and the duplicated edge. */
-    poly_loops[2].v = new_vert_2;
-    poly_loops[2].e = duplicate_edge_range[i];
-    /* Add the second duplicate edge vertex, and the second extruded edge to complete the face. */
-    poly_loops[3].v = new_vert_1;
-    poly_loops[3].e = connect_edge_range[extrude_index_1];
+
+    Span<int> connected_polys = edge_to_poly_map[orig_edge_index];
+
+    /* When there was a single polygon connected to the new polygon, we can use the old one to keep
+     * the face direction consistent. When there is more than one connected edge, the new face
+     * direction is totally arbitrary and the only goal for the behavior is to be deterministic. */
+    Span<MLoop> connected_poly_loops = {};
+    if (connected_polys.size() == 1) {
+      const MPoly &connected_poly = polys[connected_polys.first()];
+      connected_poly_loops = loops.slice(connected_poly.loopstart, connected_poly.totloop);
+    }
+    fill_quad_consistent_direction(connected_poly_loops,
+                                   new_loops.slice(4 * i, 4),
+                                   new_vert_orig_indices[extrude_index_1],
+                                   new_vert_orig_indices[extrude_index_2],
+                                   new_vert_1,
+                                   new_vert_2,
+                                   orig_edge_index,
+                                   connect_edge_range[extrude_index_1],
+                                   duplicate_edge_range[i],
+                                   connect_edge_range[extrude_index_2]);
   }
 
   component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
@@ -614,49 +679,24 @@ static void extrude_mesh_faces(MeshComponent &component,
   }
 
   for (const int i : edge_selection.index_range()) {
-    MutableSpan<MLoop> poly_loops = new_loops.slice(4 * i, 4);
-    const int orig_edge_index = edge_selection[i];
-    const int duplicate_edge_index = duplicate_edge_range[i];
     const MEdge &duplicate_edge = duplicate_edges[i];
-
     const int new_vert_1 = duplicate_edge.v1;
     const int new_vert_2 = duplicate_edge.v2;
     const int extrude_index_1 = new_vert_1 - orig_vert_size;
     const int extrude_index_2 = new_vert_2 - orig_vert_size;
-    const int orig_vert_index_1 = new_vert_orig_indices[extrude_index_1];
-    const int orig_vert_index_2 = new_vert_orig_indices[extrude_index_2];
 
-    /* Find the loop on the extruded polygon that uses the duplicate edge. */
-    bool direction = true;
     const MPoly &extrude_poly = polys[edge_orig_face_indices[i]];
-    for (const MLoop &loop : loops.slice(extrude_poly.loopstart, extrude_poly.totloop)) {
-      if (loop.e == duplicate_edge_index) {
-        direction = loop.v == new_vert_1;
-        break;
-      }
-    }
 
-    /* The side faces of this extruded polygon must have the same winding order. */
-    if (direction) {
-      poly_loops[0].v = new_vert_1;
-      poly_loops[0].e = connect_edge_range[extrude_index_1];
-      poly_loops[1].v = orig_vert_index_1;
-      poly_loops[1].e = orig_edge_index;
-      poly_loops[2].v = orig_vert_index_2;
-      poly_loops[2].e = connect_edge_range[extrude_index_2];
-      poly_loops[3].v = new_vert_2;
-      poly_loops[3].e = duplicate_edge_index;
-    }
-    else {
-      poly_loops[0].v = new_vert_1;
-      poly_loops[0].e = duplicate_edge_index;
-      poly_loops[1].v = new_vert_2;
-     

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list