Geometry Nodes: Parallelize flip faces node

I observed a 2x performance improvement for a large mesh.
This commit is contained in:
Hans Goudey 2023-01-19 14:14:12 -06:00
parent 76673e5fcf
commit 4cfa4f7551
1 changed files with 19 additions and 16 deletions

View File

@ -1,11 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_task.hh"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_attribute_math.hh"
#include "node_geometry_util.hh"
@ -33,16 +32,18 @@ static void mesh_flip_faces(Mesh &mesh, const Field<bool> &selection_field)
const Span<MPoly> polys = mesh.polys();
MutableSpan<MLoop> loops = mesh.loops_for_write();
for (const int i : selection.index_range()) {
const MPoly &poly = polys[selection[i]];
int start = poly.loopstart;
for (const int j : IndexRange(poly.totloop / 2)) {
const int index1 = start + j + 1;
const int index2 = start + poly.totloop - j - 1;
std::swap(loops[index1].v, loops[index2].v);
std::swap(loops[index1 - 1].e, loops[index2].e);
threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) {
for (const int i : selection.slice(range)) {
const IndexRange poly(polys[i].loopstart, polys[i].totloop);
int start = poly.start();
for (const int j : IndexRange(poly.size() / 2)) {
const int index1 = start + j + 1;
const int index2 = start + poly.size() - j - 1;
std::swap(loops[index1].v, loops[index2].v);
std::swap(loops[index1 - 1].e, loops[index2].e);
}
}
}
});
MutableAttributeAccessor attributes = mesh.attributes_for_write();
attributes.for_all(
@ -56,10 +57,12 @@ static void mesh_flip_faces(Mesh &mesh, const Field<bool> &selection_field)
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
using T = decltype(dummy);
MutableSpan<T> dst_span = attribute.span.typed<T>();
for (const int j : selection.index_range()) {
const MPoly &poly = polys[selection[j]];
dst_span.slice(poly.loopstart + 1, poly.totloop - 1).reverse();
}
threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) {
for (const int i : selection.slice(range)) {
const IndexRange poly(polys[i].loopstart, polys[i].totloop);
dst_span.slice(poly.drop_front(1)).reverse();
}
});
});
attribute.finish();
}