[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