[Bf-blender-cvs] [bd17f462058] temp-geometry-nodes-extrude-mesh: Working edge extrusion, no new faces

Hans Goudey noreply at git.blender.org
Mon Dec 27 06:46:23 CET 2021


Commit: bd17f4620587a1607c1d034a7cd087cae804f456
Author: Hans Goudey
Date:   Sun Dec 26 20:21:48 2021 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rBbd17f4620587a1607c1d034a7cd087cae804f456

Working edge extrusion, no new faces

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

M	source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
M	source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc

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

diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 337a6037c42..a6f9f26d09d 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -103,6 +103,20 @@ void GeometryDataSource::foreach_default_column_ids(
     fn({(char *)"Rotation"}, false);
     fn({(char *)"Scale"}, false);
   }
+  else if (component_->type() == GEO_COMPONENT_TYPE_MESH) {
+    if (domain_ == ATTR_DOMAIN_EDGE) {
+      fn({(char *)"v1"}, false);
+      fn({(char *)"v2"}, false);
+    }
+    else if (domain_ == ATTR_DOMAIN_FACE) {
+      fn({(char *)"loopstart"}, false);
+      fn({(char *)"totloop"}, false);
+    }
+    else if (domain_ == ATTR_DOMAIN_CORNER) {
+      fn({(char *)"v"}, false);
+      fn({(char *)"e"}, false);
+    }
+  }
 }
 
 std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
@@ -146,6 +160,53 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
           }));
     }
   }
+  else if (component_->type() == GEO_COMPONENT_TYPE_MESH) {
+    const MeshComponent &component = static_cast<const MeshComponent &>(*component_);
+    if (const Mesh *mesh = component.get_for_read()) {
+      if (domain_ == ATTR_DOMAIN_EDGE) {
+        if (STREQ(column_id.name, "v1")) {
+          return std::make_unique<ColumnValues>(
+              column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) {
+                return mesh->medge[index].v1;
+              }));
+        }
+        if (STREQ(column_id.name, "v2")) {
+          return std::make_unique<ColumnValues>(
+              column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) {
+                return mesh->medge[index].v2;
+              }));
+        }
+      }
+      else if (domain_ == ATTR_DOMAIN_FACE) {
+        if (STREQ(column_id.name, "loopstart")) {
+          return std::make_unique<ColumnValues>(
+              column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) {
+                return mesh->mpoly[index].loopstart;
+              }));
+        }
+        if (STREQ(column_id.name, "totloop")) {
+          return std::make_unique<ColumnValues>(
+              column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) {
+                return mesh->mpoly[index].totloop;
+              }));
+        }
+      }
+      else if (domain_ == ATTR_DOMAIN_CORNER) {
+        if (STREQ(column_id.name, "v")) {
+          return std::make_unique<ColumnValues>(
+              column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) {
+                return mesh->mloop[index].v;
+              }));
+        }
+        if (STREQ(column_id.name, "e")) {
+          return std::make_unique<ColumnValues>(
+              column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) {
+                return mesh->mloop[index].e;
+              }));
+        }
+      }
+    }
+  }
 
   bke::ReadAttributeLookup attribute = component_->attribute_try_get_for_read(column_id.name);
   if (!attribute) {
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 51095475769..f81eb3da179 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -147,36 +147,47 @@ static void extrude_mesh_edges(MeshComponent &component,
   const int orig_edge_size = mesh.totedge;
   const int orig_loop_size = mesh.totloop;
 
-  GeometryComponentFieldContext context{component, ATTR_DOMAIN_EDGE};
-  FieldEvaluator evaluator{context, mesh.totvert};
-  evaluator.add(offset_field);
-  evaluator.set_selection(selection_field);
-  evaluator.evaluate();
-  const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
-  const VArray<float3> offsets = evaluator.get_evaluated<float3>(0);
+  GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE};
+  FieldEvaluator edge_evaluator{edge_context, mesh.totedge};
+  edge_evaluator.add(selection_field);
+  edge_evaluator.evaluate();
+  const IndexMask selection = edge_evaluator.get_evaluated_as_mask(0);
 
   Array<int> extrude_vert_indices(mesh.totvert, -1);
-  Vector<CopiedVert> extrude_vert_orig_indices;
+  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];
 
     if (extrude_vert_indices[edge.v1] == -1) {
       extrude_vert_indices[edge.v1] = orig_vert_size + extrude_vert_orig_indices.size();
-      extrude_vert_orig_indices.append({int(edge.v1)});
+      extrude_vert_orig_indices.append(edge.v1);
     }
 
     if (extrude_vert_indices[edge.v2] == -1) {
       extrude_vert_indices[edge.v2] = orig_vert_size + extrude_vert_orig_indices.size();
-      extrude_vert_orig_indices.append({int(edge.v2)});
+      extrude_vert_orig_indices.append(edge.v2);
     }
   }
 
+  GeometryComponentFieldContext point_context{component, ATTR_DOMAIN_POINT};
+  FieldEvaluator point_evaluator{point_context, mesh.totvert}; /* TODO: Better selection. */
+  point_evaluator.add(offset_field);
+  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_size = extrude_vert_size;
   const int duplicate_edge_size = selection.size();
   const int new_edge_size = extrude_edge_size + duplicate_edge_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_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();
@@ -185,7 +196,10 @@ static void extrude_mesh_edges(MeshComponent &component,
   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);
 
+  MutableSpan<MVert> verts{mesh.mvert, mesh.totvert};
+  MutableSpan<MVert> new_verts = verts.take_back(extrude_vert_size);
   MutableSpan<MEdge> edges{mesh.medge, mesh.totedge};
   MutableSpan<MEdge> new_edges = edges.take_back(new_edge_size);
   MutableSpan<MEdge> extrude_edges = new_edges.take_front(extrude_edge_size);
@@ -193,19 +207,66 @@ static void extrude_mesh_edges(MeshComponent &component,
 
   for (const int i : extrude_edges.index_range()) {
     MEdge &edge = extrude_edges[i];
-    edge.v1 = extrude_vert_orig_indices[i].orig_index;
+    edge.v1 = extrude_vert_orig_indices[i];
     edge.v2 = orig_vert_size + i;
-    edge.flag |= (ME_EDGEDRAW | ME_EDGERENDER);
+    edge.flag |= (ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE);
   }
 
   for (const int i : duplicate_edges.index_range()) {
     const MEdge &orig_edge = mesh.medge[selection[i]];
-    MEdge &edge = extrude_edges[i];
+    MEdge &edge = duplicate_edges[i];
     edge.v1 = extrude_vert_indices[orig_edge.v1];
     edge.v2 = extrude_vert_indices[orig_edge.v2];
-    edge.flag |= (ME_EDGEDRAW | ME_EDGERENDER);
+    edge.flag |= (ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE);
   }
 
+  component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+    if (meta_data.domain == ATTR_DOMAIN_POINT) {
+      OutputAttribute attribute = component.attribute_try_get_for_output(
+          id, ATTR_DOMAIN_POINT, meta_data.data_type);
+
+      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);
+
+        for (const int i : extrude_vert_orig_indices.index_range()) {
+          new_data[i] = data[extrude_vert_orig_indices[i]];
+        }
+      });
+
+      attribute.save();
+    }
+    else if (meta_data.domain == ATTR_DOMAIN_EDGE) {
+      OutputAttribute attribute = component.attribute_try_get_for_output(
+          id, ATTR_DOMAIN_EDGE, meta_data.data_type);
+
+      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(new_edge_size);
+        MutableSpan<T> extrude_data = new_data.take_front(extrude_edge_size);
+        MutableSpan<T> duplicate_data = new_data.take_back(duplicate_edge_size);
+
+        for (const int i : selection.index_range()) {
+          duplicate_data[i] = data[selection[i]];
+        }
+      });
+
+      attribute.save();
+    }
+    return true;
+  });
+
+  devirtualize_varray(offsets, [&](const auto offsets) {
+    threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) {
+      for (const int i : range) {
+        const float3 offset = offsets[extrude_vert_orig_indices[i]];
+        add_v3_v3(new_verts[i].co, offset);
+      }
+    });
+  });
+
   BKE_mesh_runtime_clear_cache(&mesh);
   BKE_mesh_normals_tag_dirty(&mesh);
 }



More information about the Bf-blender-cvs mailing list