[Bf-blender-cvs] [a9846ee5121] temp-geometry-nodes-extrude-mesh: Progress on face extrude mode
Hans Goudey
noreply at git.blender.org
Mon Dec 27 06:46:23 CET 2021
Commit: a9846ee51219ce50ef0e013f702f536bb3b3b7ba
Author: Hans Goudey
Date: Sun Dec 26 23:46:15 2021 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rBa9846ee51219ce50ef0e013f702f536bb3b3b7ba
Progress on face extrude 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 f81eb3da179..d5948c2b649 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -32,6 +32,9 @@ namespace blender::nodes::node_geo_extrude_mesh_cc {
NODE_STORAGE_FUNCS(NodeGeometryExtrudeMesh)
+/* TODO: Decide whether to transfer attributes by topology proximity to new faces, corners, and
+ * edges. */
+
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Mesh").supported_type(GEO_COMPONENT_TYPE_MESH);
@@ -153,7 +156,9 @@ static void extrude_mesh_edges(MeshComponent &component,
edge_evaluator.evaluate();
const IndexMask selection = edge_evaluator.get_evaluated_as_mask(0);
+ /* Maps vertex indices in the original mesh to the corresponding extruded vertices. */
Array<int> extrude_vert_indices(mesh.totvert, -1);
+ /* Maps from the index in the added vertices to the original vertex they were extruded from. */
Vector<int> extrude_vert_orig_indices;
extrude_vert_orig_indices.reserve(selection.size());
for (const int i_edge : selection) {
@@ -177,9 +182,13 @@ static void extrude_mesh_edges(MeshComponent &component,
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 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. */
@@ -190,20 +199,23 @@ static void extrude_mesh_edges(MeshComponent &component,
mesh.totvert += extrude_vert_size;
mesh.totedge += new_edge_size;
- // mesh.totpoly += selection.size();
- // mesh.totloop += selection.size() * 4;
+ 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);
+ 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);
- MutableSpan<MEdge> duplicate_edges = new_edges.take_back(duplicate_edge_size);
+ MutableSpan<MEdge> extrude_edges = edges.slice(extrude_edge_offset, extrude_edge_size);
+ MutableSpan<MEdge> duplicate_edges = edges.slice(duplicate_edge_offset, duplicate_edge_size);
+ MutableSpan<MPoly> polys{mesh.mpoly, mesh.totpoly};
+ MutableSpan<MPoly> new_polys = polys.take_back(selection.size());
+ MutableSpan<MLoop> loops{mesh.mloop, mesh.totloop};
+ MutableSpan<MLoop> new_loops = loops.take_back(new_loop_size);
for (const int i : extrude_edges.index_range()) {
MEdge &edge = extrude_edges[i];
@@ -220,6 +232,48 @@ static void extrude_mesh_edges(MeshComponent &component,
edge.flag |= (ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE);
}
+ for (const int i : new_polys.index_range()) {
+ MPoly &poly = new_polys[i];
+ poly.loopstart = orig_loop_size + i * 4;
+ poly.totloop = 4;
+ poly.mat_nr = 0;
+ }
+
+ /* 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);
+ 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);
+ const int vert_index = extrude_edge.v1 > orig_vert_size ? extrude_edge.v1 : extrude_edge.v2;
+ new_vert_to_extrude_edge[vert_index - orig_vert_size] = i;
+ }
+
+ /* TODO: Figure out winding order for new faces. */
+ for (const int i : selection.index_range()) {
+ MutableSpan<MLoop> poly_loops = new_loops.slice(4 * i, 4);
+ const int orig_edge_index = selection[i];
+ const MEdge &orig_edge = edges[orig_edge_index];
+ const MEdge &duplicate_edge = duplicate_edges[i];
+ const int new_vert_index_1 = duplicate_edge.v1 - orig_vert_size;
+ const int new_vert_index_2 = duplicate_edge.v2 - orig_vert_size;
+ const int extrude_edge_index_1 = new_vert_to_extrude_edge[new_vert_index_1];
+ const int extrude_edge_index_2 = new_vert_to_extrude_edge[new_vert_index_2];
+ const MEdge &extrude_edge_1 = extrude_edges[new_vert_to_extrude_edge[new_vert_index_1]];
+ const MEdge &extrude_edge_2 = extrude_edges[new_vert_to_extrude_edge[new_vert_index_2]];
+ poly_loops[0].v = orig_edge.v1;
+ poly_loops[0].e = orig_edge_index;
+ poly_loops[1].v = orig_edge.v2;
+ poly_loops[1].e = extrude_edge_offset + extrude_edge_index_1;
+ /* The first vertex of the duplicate edge is the extrude edge that isn't used yet. */
+ poly_loops[2].v = extrude_edge_1.v1 == orig_edge.v2 ? extrude_edge_1.v1 : extrude_edge_1.v2;
+ poly_loops[2].e = duplicate_edge_offset + i;
+
+ poly_loops[3].v = extrude_edge_2.v1 == orig_edge.v1 ? extrude_edge_2.v2 : extrude_edge_2.v1;
+ poly_loops[3].e = extrude_edge_offset + extrude_edge_index_2;
+ }
+
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(
@@ -244,9 +298,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(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);
+ MutableSpan<T> duplicate_data = data.slice(duplicate_edge_offset, duplicate_edge_size);
for (const int i : selection.index_range()) {
duplicate_data[i] = data[selection[i]];
More information about the Bf-blender-cvs
mailing list