From da4bd24c3e6122c74fbc6dcc81604ee7a0dd3fe0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 18 Oct 2022 23:44:07 -0500 Subject: 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. --- .../editors/sculpt_paint/sculpt_face_set.cc | 29 ++++++++-------------- 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index ee1238e0f24..8fb4dea668e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -18,6 +18,7 @@ #include "BLI_math_vector.hh" #include "BLI_span.hh" #include "BLI_task.h" +#include "BLI_task.hh" #include "DNA_brush_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) { + using namespace blender; Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; 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) { - BMesh *bm; - const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh); - BMeshCreateParams create_params{}; - create_params.use_toolflags = true; - bm = BM_mesh_create(&allocsize, &create_params); - - BMeshFromMeshParams convert_params{}; - 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; + const bke::AttributeAccessor attributes = mesh->attributes(); + const VArraySpan select_poly = attributes.lookup_or_default( + ".select_poly", ATTR_DOMAIN_FACE, false); + threading::parallel_for(IndexRange(mesh->totvert), 4096, [&](const IndexRange range) { + for (const int i : range) { + if (select_poly[i]) { + ss->face_sets[i] = next_face_set; + } } - } - BM_mesh_free(bm); + }); } for (int i = 0; i < totnode; i++) { -- cgit v1.2.3