[Bf-blender-cvs] [60101b9923f] temp-geometry-nodes-extrude-mesh: Evaluate offsets on edge and face domains
Hans Goudey
noreply at git.blender.org
Wed Jan 5 05:21:44 CET 2022
Commit: 60101b9923fe01e3b6c66f8196309aa5a6a48da9
Author: Hans Goudey
Date: Tue Jan 4 22:21:31 2022 -0600
Branches: temp-geometry-nodes-extrude-mesh
https://developer.blender.org/rB60101b9923fe01e3b6c66f8196309aa5a6a48da9
Evaluate offsets on edge and face domains
===================================================================
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 e862600cae7..69ce553352b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc
@@ -344,20 +344,16 @@ static void extrude_mesh_edges(MeshComponent &component,
GeometryComponentFieldContext edge_context{component, ATTR_DOMAIN_EDGE};
FieldEvaluator edge_evaluator{edge_context, mesh.totedge};
- edge_evaluator.add(selection_field);
+ edge_evaluator.set_selection(selection_field);
+ edge_evaluator.add(offset_field);
edge_evaluator.evaluate();
- const IndexMask edge_selection = edge_evaluator.get_evaluated_as_mask(0);
+ const IndexMask edge_selection = edge_evaluator.get_evaluated_selection_as_mask();
+ const VArray<float3> &edge_offsets = edge_evaluator.get_evaluated<float3>(0);
Array<int> new_vert_indices(orig_vert_size, -1);
Vector<int> new_vert_orig_indices = extrude_vert_orig_indices_from_edges(
edge_selection, mesh, new_vert_indices);
- Array<float3> offsets(orig_vert_size);
- GeometryComponentFieldContext point_context{component, ATTR_DOMAIN_POINT};
- FieldEvaluator point_evaluator{point_context, orig_vert_size}; /* TODO: Better edge_selection. */
- point_evaluator.add_with_destination(offset_field, offsets.as_mutable_span());
- point_evaluator.evaluate();
-
const IndexRange new_vert_range{orig_vert_size, new_vert_orig_indices.size()};
/* The extruded edges connect the original and duplicate edges. */
const IndexRange connect_edge_range{orig_edges.size(), new_vert_range.size()};
@@ -570,12 +566,31 @@ static void extrude_mesh_edges(MeshComponent &component,
return true;
});
- threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) {
- for (const int i : range) {
- const float3 offset = offsets[new_vert_orig_indices[i]];
- add_v3_v3(new_verts[i].co, offset);
+ if (edge_offsets.is_single()) {
+ const float3 offset = edge_offsets.get_internal_single();
+ threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) {
+ for (const int i : range) {
+ add_v3_v3(new_verts[i].co, offset);
+ }
+ });
+ }
+ else {
+ Array<float3> vert_offsets(new_verts.size());
+ attribute_math::DefaultMixer<float3> mixer(vert_offsets);
+ for (const int i : edge_selection.index_range()) {
+ const MEdge &edge = duplicate_edges[i];
+ const float3 offset = edge_offsets[edge_selection[i]];
+ mixer.mix_in(edge.v1 - orig_vert_size, offset);
+ mixer.mix_in(edge.v2 - orig_vert_size, offset);
}
- });
+ mixer.finalize();
+
+ threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) {
+ for (const int i : range) {
+ add_v3_v3(new_verts[i].co, vert_offsets[i]);
+ }
+ });
+ }
if (attribute_outputs.top_id) {
save_selection_as_attribute(
@@ -593,38 +608,6 @@ static void extrude_mesh_edges(MeshComponent &component,
BLI_assert(BKE_mesh_is_valid(component.get_for_write()));
}
-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());
- }
- return IndexMask(0);
- }
-
- if (selection.is_span()) {
- Span<bool> span = selection.get_internal_span();
- for (const int i : span.index_range()) {
- if (span[i]) {
- r_indices.append(i);
- }
- }
- }
- else {
- for (const int i : selection.index_range()) {
- if (selection[i]) {
- r_indices.append(i);
- }
- }
- }
-
- return IndexMask(r_indices);
-}
-
static void extrude_mesh_faces(MeshComponent &component,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
@@ -638,22 +621,11 @@ static void extrude_mesh_faces(MeshComponent &component,
GeometryComponentFieldContext poly_context{component, ATTR_DOMAIN_FACE};
FieldEvaluator poly_evaluator{poly_context, mesh.totpoly};
- poly_evaluator.add(selection_field);
+ poly_evaluator.set_selection(selection_field);
+ poly_evaluator.add(offset_field);
poly_evaluator.evaluate();
- const VArray<bool> &poly_selection_varray = poly_evaluator.get_evaluated<bool>(0);
- const IndexMask poly_selection = poly_evaluator.get_evaluated_as_mask(0);
-
- Vector<int64_t> vert_selection_indices;
- const VArray<bool> vert_selection_varray = component.attribute_try_adapt_domain(
- poly_selection_varray, ATTR_DOMAIN_FACE, ATTR_DOMAIN_POINT);
- const IndexMask vert_selection = index_mask_from_selection(vert_selection_varray,
- vert_selection_indices);
-
- Array<float3> offsets(orig_vert_size);
- GeometryComponentFieldContext vert_context{component, ATTR_DOMAIN_POINT};
- FieldEvaluator vert_evaluator{vert_context, &vert_selection};
- vert_evaluator.add_with_destination(offset_field, offsets.as_mutable_span());
- vert_evaluator.evaluate();
+ const IndexMask poly_selection = poly_evaluator.get_evaluated_selection_as_mask();
+ const VArray<float3> &poly_offsets = poly_evaluator.get_evaluated<float3>(0);
/* 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
@@ -893,18 +865,43 @@ static void extrude_mesh_faces(MeshComponent &component,
return true;
});
- threading::parallel_for(vert_selection.index_range(), 1024, [&](const IndexRange range) {
- for (const int i : range) {
- const int i_orig = vert_selection[i];
- const int i_new = new_vert_indices[i_orig];
- const float3 offset = offsets[i_orig];
- /* If the vertex is used by a selected edge, it will have been duplicated and only the new
- * vertex should use the offset. Otherwise the vertex might still need an offset, but it was
- * reused on the inside of a group of extruded faces. */
- MVert &vert = bke::mesh_verts(mesh)[(i_new != -1) ? i_new : i_orig];
- add_v3_v3(vert.co, offset);
+ if (poly_offsets.is_single()) {
+ const float3 offset = poly_offsets.get_internal_single();
+ threading::parallel_for(IndexRange(orig_vert_size), 1024, [&](const IndexRange range) {
+ for (const int i_orig : range) {
+ const int i_new = new_vert_indices[i_orig];
+ /* If the vertex is used by a selected edge, it will have been duplicated and only the new
+ * vertex should use the offset. Otherwise the vertex might still need an offset, but it
+ * was reused on the inside of a group of extruded faces. */
+ MVert &vert = bke::mesh_verts(mesh)[(i_new != -1) ? i_new : i_orig];
+ add_v3_v3(vert.co, offset);
+ }
+ });
+ }
+ else {
+ Array<float3> vert_offsets(orig_vert_size);
+ attribute_math::DefaultMixer<float3> mixer(vert_offsets);
+ for (const int i_poly : poly_selection) {
+ const MPoly &poly = orig_polys[i_poly];
+ const float3 offset = poly_offsets[i_poly];
+ for (const MLoop &loop : orig_loops.slice(poly.loopstart, poly.totloop)) {
+ mixer.mix_in(loop.v, offset);
+ }
}
- });
+ mixer.finalize();
+
+ threading::parallel_for(IndexRange(orig_vert_size), 1024, [&](const IndexRange range) {
+ for (const int i_orig : range) {
+ const int i_new = new_vert_indices[i_orig];
+ const float3 offset = vert_offsets[i_orig];
+ /* If the vertex is used by a selected edge, it will have been duplicated and only the new
+ * vertex should use the offset. Otherwise the vertex might still need an offset, but it
+ * was reused on the inside of a group of extruded faces. */
+ MVert &vert = bke::mesh_verts(mesh)[(i_new != -1) ? i_new : i_orig];
+ add_v3_v3(vert.co, offset);
+ }
+ });
+ }
BKE_mesh_runtime_clear_cache(&mesh);
BKE_mesh_normals_tag_dirty(&mesh);
More information about the Bf-blender-cvs
mailing list