[Bf-blender-cvs] [754e7b4f958] temp-geometry-nodes-extrude-mesh: Add attribute interpolations for non-individual face mode
Hans Goudey
noreply at git.blender.org
Wed Jan 5 01:30:50 CET 2022
Commit: 754e7b4f95820d106fb3894b5013d37002298f93
Author: Hans Goudey
Date: Tue Jan 4 18:30:41 2022 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rB754e7b4f95820d106fb3894b5013d37002298f93
Add attribute interpolations for non-individual face 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 6dd938ac16c..e862600cae7 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -392,7 +392,6 @@ static void extrude_mesh_edges(MeshComponent &component,
edge.flag = (ME_EDGEDRAW | ME_EDGERENDER);
}
- /* TODO: Combine with poly loop? */
for (const int i : duplicate_edges.index_range()) {
const MEdge &orig_edge = mesh.medge[edge_selection[i]];
MEdge &edge = duplicate_edges[i];
@@ -597,6 +596,9 @@ static void extrude_mesh_edges(MeshComponent &component,
static IndexMask index_mask_from_selection(const VArray<bool> &selection,
Vector<int64_t> &r_indices)
{
+ if (!selection) {
+ return IndexMask(0);
+ }
if (selection.is_single()) {
if (selection.get_internal_single()) {
return IndexMask(selection.size());
@@ -668,7 +670,7 @@ static void extrude_mesh_faces(MeshComponent &component,
}
Vector<int> in_between_edges;
- /* The extruded face corresponding to each extruded edge. */
+ /* 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;
for (const int i_edge : IndexRange(orig_edges.size())) {
@@ -787,6 +789,12 @@ static void extrude_mesh_faces(MeshComponent &component,
connect_edge_range[extrude_index_2]);
}
+ /* Create a map of all of an index in the extruded vertices array to all of the indices of edges
+ * in the duplicate edges array that connect to that vertex. This can be used to simplify the
+ * mixing of attribute data for the connecting edges. */
+ Array<Vector<int>> new_vert_to_duplicate_edge_map = create_vert_to_edge_map(
+ new_vert_range.size(), duplicate_edges, orig_vert_size);
+
component.attribute_foreach([&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
OutputAttribute attribute = component.attribute_try_get_for_output(
id, meta_data.domain, meta_data.data_type);
@@ -808,10 +816,24 @@ static void extrude_mesh_faces(MeshComponent &component,
case ATTR_DOMAIN_EDGE: {
MutableSpan<T> duplicate_data = data.slice(duplicate_edge_range);
MutableSpan<T> connect_data = data.slice(connect_edge_range);
- connect_data.fill(T());
for (const int i : edge_selection.index_range()) {
duplicate_data[i] = data[edge_selection[i]];
}
+ threading::parallel_for(connect_data.index_range(), 512, [&](const IndexRange range) {
+ for (const int i : range) {
+ /* Create a separate mixer for every point to avoid allocating temporary
+ * buffers in the mixer the size of the result and to allow multi-threading. */
+ attribute_math::DefaultMixer<T> mixer{connect_data.slice(i, 1)};
+
+ for (const int i_connected_duplicate_edge : new_vert_to_duplicate_edge_map[i]) {
+ /* Use the duplicate data because it's slightly simpler to access and was just
+ * filled in the previous loop. */
+ mixer.mix_in(0, duplicate_data[i_connected_duplicate_edge]);
+ }
+
+ mixer.finalize();
+ }
+ });
break;
}
case ATTR_DOMAIN_FACE: {
@@ -823,7 +845,43 @@ static void extrude_mesh_faces(MeshComponent &component,
}
case ATTR_DOMAIN_CORNER: {
MutableSpan<T> new_data = data.slice(side_loop_range);
- new_data.fill(T());
+ threading::parallel_for(edge_selection.index_range(), 256, [&](const IndexRange range) {
+ for (const int i_edge_selection : range) {
+ const MPoly &poly = polys[edge_orig_face_indices[i_edge_selection]];
+
+ const MEdge &duplicate_edge = duplicate_edges[i_edge_selection];
+ const int new_vert_1 = duplicate_edge.v1;
+ const int new_vert_2 = duplicate_edge.v2;
+ const int orig_vert_1 = new_vert_orig_indices[new_vert_1 - orig_vert_size];
+ const int orig_vert_2 = new_vert_orig_indices[new_vert_2 - orig_vert_size];
+
+ /* Retrieve the data for the first two sides of the quad from the extruded polygon,
+ * which we generally expect to have just a small amount of sides. This loop could be
+ * eliminated by adding a cache of connected loops. */
+ T data_1;
+ T data_2;
+ for (const int i_loop : IndexRange(poly.loopstart, poly.totloop)) {
+ if (loops[i_loop].v == new_vert_1) {
+ data_1 = data[i_loop];
+ }
+ if (loops[i_loop].v == new_vert_2) {
+ data_2 = data[i_loop];
+ }
+ }
+
+ /* Instead of replicating the order in #fill_quad_consistent_direction here, it's
+ * simpler (though probably not faster) to just match the corner data based on the
+ * vertex indices. */
+ for (const int i : IndexRange(4 * i_edge_selection, 4)) {
+ if (ELEM(new_loops[i].v, new_vert_1, orig_vert_1)) {
+ new_data[i] = data_1;
+ }
+ else if (ELEM(new_loops[i].v, new_vert_2, orig_vert_2)) {
+ new_data[i] = data_2;
+ }
+ }
+ }
+ });
break;
}
default:
@@ -1010,9 +1068,9 @@ static void extrude_individual_mesh_faces(MeshComponent &component,
MutableSpan<T> side_loop_data = new_data.slice(i_extrude * 4, 4);
/* The two corners on each side of the side polygon get the data from the matching
- * corners of the extruded polygon. (All the corners that would be in the same
- * location if the extrude offset is 0). This order depends on the following loop
- * filling the loop indices. */
+ * corners of the extruded polygon. (Matching values for the corners that would be
+ * in the same location if the extrude offset is 0). This order depends on the
+ * following loop filling the loop indices. */
side_loop_data[0] = poly_loop_data[i_next];
side_loop_data[1] = poly_loop_data[i];
side_loop_data[2] = poly_loop_data[i];
More information about the Bf-blender-cvs
mailing list