[Bf-blender-cvs] [a1c5fc42814] temp-geometry-nodes-extrude-mesh: Cleanup: Use edge to poly topology map
Hans Goudey
noreply at git.blender.org
Wed Jan 12 16:32:30 CET 2022
Commit: a1c5fc42814d8fa7928671f68b8fdd4743264af5
Author: Hans Goudey
Date: Tue Jan 11 19:14:08 2022 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rBa1c5fc42814d8fa7928671f68b8fdd4743264af5
Cleanup: Use edge to poly topology map
This probably trades some memory usage for code simplicity,
which is more valuable at the moment.
===================================================================
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 2e232944de9..f2df1486fd4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -300,22 +300,28 @@ 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)
+static Array<Vector<int, 2>> mesh_calculate_polys_of_edge(const Mesh &mesh,
+ const IndexMask poly_mask)
{
Span<MPoly> polys = mesh_polys(mesh);
Span<MLoop> loops = 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];
+ poly_mask.foreach_index([&](const int64_t i_poly) {
+ const MPoly &poly = polys[i_poly];
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
- polys_of_edge[loop.e].append(poly_index);
+ polys_of_edge[loop.e].append(i_poly);
}
- }
+ });
return polys_of_edge;
}
+static Array<Vector<int, 2>> mesh_calculate_polys_of_edge(const Mesh &mesh)
+{
+ return mesh_calculate_polys_of_edge(mesh, IndexMask(mesh.totpoly));
+}
+
static void fill_quad_consistent_direction(Span<MLoop> other_poly_loops,
MutableSpan<MLoop> new_loops,
const int vert_connected_to_poly_1,
@@ -401,6 +407,9 @@ static void extrude_mesh_edges(MeshComponent &component,
edge_evaluator.evaluate();
const IndexMask edge_selection = edge_evaluator.get_evaluated_selection_as_mask();
const VArray<float3> &edge_offsets = edge_evaluator.get_evaluated<float3>(0);
+ if (edge_selection.is_empty()) {
+ return;
+ }
Array<int> new_vert_indices(orig_vert_size, -1);
Vector<int> new_vert_orig_indices = extrude_vert_orig_indices_from_edges(
@@ -640,6 +649,10 @@ static void extrude_mesh_edges(MeshComponent &component,
BLI_assert(BKE_mesh_is_valid(component.get_for_write()));
}
+/**
+ * Edges connected to one selected face are on the boundary of a region and will be duplicated into
+ * a "side face".
+ */
static void extrude_mesh_face_regions(MeshComponent &component,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
@@ -658,8 +671,13 @@ static void extrude_mesh_face_regions(MeshComponent &component,
poly_evaluator.evaluate();
const IndexMask poly_selection = poly_evaluator.get_evaluated_selection_as_mask();
const VArray<float3> &poly_offsets = poly_evaluator.get_evaluated<float3>(0);
+ if (poly_selection.is_empty()) {
+ return;
+ }
- /* Mix the offsets from the face domain to the vertex domain. */
+ /* Mix the offsets from the face domain to the vertex domain. Evaluate on the face domain above
+ * in order to be consistent with the selection, and to use the face normals rather than vertex
+ * normals as an offset, for example. */
Array<float3> vert_offsets;
if (!poly_offsets.is_single()) {
vert_offsets.reinitialize(orig_vert_size);
@@ -674,23 +692,20 @@ static void extrude_mesh_face_regions(MeshComponent &component,
mixer.finalize();
}
- DisjointSet regions(poly_selection.size());
+ /* Build a map that contains all of the selected faces connected to each edge. */
+ Array<Vector<int, 2>> edge_to_selected_poly_map = mesh_calculate_polys_of_edge(mesh,
+ poly_selection);
+
+ /* All of the faces (selected and unselected) connected to each edge. */
+ // Array<Vector<int, 2>> edge_to_poly_map = mesh_calculate_polys_of_edge(mesh);
- /* All vertices that are connected to the selected polygons. */
+ /* All vertices that are connected to the selected polygons.
+ * Start the size at one vert per poly to reduce reallocations. */
VectorSet<int> all_selected_verts;
- /* Keep track of the selected face that each edge corresponds to. Only edges with one selected
- * face will have a single associated face. However, we need to keep track of a value for every
- * face in the mesh at this point, because we don't know how many edges will be selected for
- * extrusion in the end. Alternatively, #mesh_calculate_polys_of_edge could be used, possibly
- * simplifying the rest of this algorithm slightly, but at a higher up-front cost. */
- Array<int> edge_face_indices(orig_edges.size(), -1);
- /* The number of connected faces for every edge, just to tell which should be extruded. */
- Array<int> edge_neighbor_count(orig_edges.size(), 0);
+ all_selected_verts.reserve(orig_polys.size());
for (const int i_poly : poly_selection) {
const MPoly &poly = orig_polys[i_poly];
for (const MLoop &loop : orig_loops.slice(poly.loopstart, poly.totloop)) {
- edge_neighbor_count[loop.e]++;
- edge_face_indices[loop.e] = i_poly;
all_selected_verts.add(loop.v);
}
}
@@ -700,17 +715,18 @@ static void extrude_mesh_face_regions(MeshComponent &component,
Vector<int> in_between_edges;
/* The extruded face corresponding to each extruded edge (and each extruded face). */
Vector<int> edge_orig_face_indices;
- Vector<int64_t> selected_edges_orig_indices;
+ Vector<int64_t> selected_edge_orig_indices;
for (const int i_edge : orig_edges.index_range()) {
- if (edge_neighbor_count[i_edge] == 1) {
- selected_edges_orig_indices.append(i_edge);
- edge_orig_face_indices.append(edge_face_indices[i_edge]);
+ Span<int> selected_polys = edge_to_selected_poly_map[i_edge];
+ if (selected_polys.size() == 1) {
+ selected_edge_orig_indices.append(i_edge);
+ edge_orig_face_indices.append(selected_polys.first());
}
- else if (edge_neighbor_count[i_edge] > 1) {
+ else if (selected_polys.size() > 1) {
in_between_edges.append(i_edge);
}
}
- const IndexMask edge_selection{selected_edges_orig_indices};
+ const IndexMask edge_selection{selected_edge_orig_indices};
/* Indices into the `duplicate_edges` span for each original selected edge. */
Array<int> duplicate_edge_indices(orig_edges.size(), -1);
More information about the Bf-blender-cvs
mailing list