Sculpt: Improve performance of face set creation from selection
Skip BMesh conversion and read the selection attribute directly. With a Ryzen 3700x, my test face of a simple 4 million face grid became over 4000 times faster, from 2.6s to 0.6ms.
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
#include "BLI_math_vector.hh"
|
#include "BLI_math_vector.hh"
|
||||||
#include "BLI_span.hh"
|
#include "BLI_span.hh"
|
||||||
#include "BLI_task.h"
|
#include "BLI_task.h"
|
||||||
|
#include "BLI_task.hh"
|
||||||
|
|
||||||
#include "DNA_brush_types.h"
|
#include "DNA_brush_types.h"
|
||||||
#include "DNA_customdata_types.h"
|
#include "DNA_customdata_types.h"
|
||||||
@@ -313,6 +314,7 @@ static EnumPropertyItem prop_sculpt_face_set_create_types[] = {
|
|||||||
|
|
||||||
static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
|
using namespace blender;
|
||||||
Object *ob = CTX_data_active_object(C);
|
Object *ob = CTX_data_active_object(C);
|
||||||
SculptSession *ss = ob->sculpt;
|
SculptSession *ss = ob->sculpt;
|
||||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||||
@@ -396,25 +398,16 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == SCULPT_FACE_SET_SELECTION) {
|
if (mode == SCULPT_FACE_SET_SELECTION) {
|
||||||
BMesh *bm;
|
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||||
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
|
const VArraySpan<bool> select_poly = attributes.lookup_or_default<bool>(
|
||||||
BMeshCreateParams create_params{};
|
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||||
create_params.use_toolflags = true;
|
threading::parallel_for(IndexRange(mesh->totvert), 4096, [&](const IndexRange range) {
|
||||||
bm = BM_mesh_create(&allocsize, &create_params);
|
for (const int i : range) {
|
||||||
|
if (select_poly[i]) {
|
||||||
BMeshFromMeshParams convert_params{};
|
ss->face_sets[i] = next_face_set;
|
||||||
convert_params.calc_vert_normal = true;
|
}
|
||||||
convert_params.calc_face_normal = true;
|
|
||||||
BM_mesh_bm_from_me(bm, mesh, &convert_params);
|
|
||||||
|
|
||||||
BMIter iter;
|
|
||||||
BMFace *f;
|
|
||||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
|
||||||
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
|
||||||
ss->face_sets[BM_elem_index_get(f)] = next_face_set;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
BM_mesh_free(bm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < totnode; i++) {
|
for (int i = 0; i < totnode; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user