Cleanup: Sculpt: Add utility to duplicate mask data
Avoid the `PBVHVertRef` abstraction which is unnecesarily costly for such a simple thing as copying data. Instead we can use abstractions specific to each PBVH type (currently only `VArray` for meshes).
This commit is contained in:
parent
a52887abb0
commit
70ae6f5d41
|
@ -468,6 +468,9 @@ void PAINT_OT_visibility_invert(wmOperatorType *ot);
|
|||
/* `paint_mask.cc` */
|
||||
|
||||
namespace blender::ed::sculpt_paint::mask {
|
||||
|
||||
Array<float> duplicate_mask(const Object &object);
|
||||
|
||||
void PAINT_OT_mask_flood_fill(wmOperatorType *ot);
|
||||
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot);
|
||||
void PAINT_OT_mask_box_gesture(wmOperatorType *ot);
|
||||
|
|
|
@ -62,6 +62,55 @@
|
|||
|
||||
namespace blender::ed::sculpt_paint::mask {
|
||||
|
||||
Array<float> duplicate_mask(const Object &object)
|
||||
{
|
||||
const SculptSession &ss = *object.sculpt;
|
||||
switch (BKE_pbvh_type(ss.pbvh)) {
|
||||
case PBVH_FACES: {
|
||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray mask = *attributes.lookup_or_default<float>(
|
||||
".sculpt_mask", bke::AttrDomain::Point, 0.0f);
|
||||
Array<float> result(mask.size());
|
||||
mask.materialize(result);
|
||||
return result;
|
||||
}
|
||||
case PBVH_GRIDS: {
|
||||
const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
|
||||
const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
|
||||
const Span<CCGElem *> grids = subdiv_ccg.grids;
|
||||
|
||||
Array<float> result(grids.size() * key.grid_area);
|
||||
int index = 0;
|
||||
for (const int grid : grids.index_range()) {
|
||||
CCGElem *elem = grids[grid];
|
||||
for (const int i : IndexRange(key.grid_area)) {
|
||||
result[index] = *CCG_elem_offset_mask(&key, elem, i);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case PBVH_BMESH: {
|
||||
BMesh &bm = *ss.bm;
|
||||
const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask");
|
||||
Array<float> result(bm.totvert);
|
||||
if (offset == -1) {
|
||||
result.fill(0.0f);
|
||||
}
|
||||
else {
|
||||
BM_mesh_elem_table_ensure(&bm, BM_VERT);
|
||||
for (const int i : result.index_range()) {
|
||||
result[i] = BM_ELEM_CD_GET_FLOAT(BM_vert_at_index(&bm, i), offset);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return {};
|
||||
}
|
||||
|
||||
/* The gesture API doesn't write to this enum type,
|
||||
* it writes to eSelectOp from ED_select_utils.hh.
|
||||
* We must thus map the modes here to the desired
|
||||
|
|
|
@ -1143,7 +1143,6 @@ static void sculpt_expand_cache_data_free(Cache *expand_cache)
|
|||
{
|
||||
MEM_SAFE_FREE(expand_cache->vert_falloff);
|
||||
MEM_SAFE_FREE(expand_cache->face_falloff);
|
||||
MEM_SAFE_FREE(expand_cache->original_mask);
|
||||
MEM_SAFE_FREE(expand_cache->original_colors);
|
||||
MEM_delete<Cache>(expand_cache);
|
||||
}
|
||||
|
@ -1240,7 +1239,7 @@ static void sculpt_expand_restore_original_state(bContext *C, Object *ob, Cache
|
|||
SculptSession *ss = ob->sculpt;
|
||||
switch (expand_cache->target) {
|
||||
case SCULPT_EXPAND_TARGET_MASK:
|
||||
write_mask_data(ss, {expand_cache->original_mask, SCULPT_vertex_count_get(ss)});
|
||||
write_mask_data(ss, expand_cache->original_mask);
|
||||
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
@ -1439,13 +1438,7 @@ static void sculpt_expand_original_state_store(Object *ob, Cache *expand_cache)
|
|||
expand_cache->original_face_sets = face_set::duplicate_face_sets(mesh);
|
||||
|
||||
if (expand_cache->target == SCULPT_EXPAND_TARGET_MASK) {
|
||||
expand_cache->original_mask = static_cast<float *>(
|
||||
MEM_malloc_arrayN(totvert, sizeof(float), "initial mask"));
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
|
||||
|
||||
expand_cache->original_mask[i] = SCULPT_vertex_mask_get(ss, vertex);
|
||||
}
|
||||
expand_cache->original_mask = mask::duplicate_mask(*ob);
|
||||
}
|
||||
|
||||
if (expand_cache->target == SCULPT_EXPAND_TARGET_COLORS) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "paint_intern.hh"
|
||||
#include "sculpt_intern.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
@ -64,7 +65,7 @@ static EnumPropertyItem prop_mask_filter_types[] = {
|
|||
|
||||
static void mask_filter_task(SculptSession *ss,
|
||||
const int mode,
|
||||
float *prev_mask,
|
||||
const Span<float> prev_mask,
|
||||
const SculptMaskWriteInfo mask_write,
|
||||
PBVHNode *node)
|
||||
{
|
||||
|
@ -184,7 +185,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||
undo::push_node(ob, node, undo::Type::Mask);
|
||||
}
|
||||
|
||||
float *prev_mask = nullptr;
|
||||
Array<float> prev_mask;
|
||||
int iterations = RNA_int_get(op->ptr, "iterations");
|
||||
|
||||
/* Auto iteration count calculates the number of iteration based on the vertices of the mesh to
|
||||
|
@ -199,11 +200,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
|
||||
prev_mask = static_cast<float *>(MEM_mallocN(num_verts * sizeof(float), __func__));
|
||||
for (int j = 0; j < num_verts; j++) {
|
||||
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, j);
|
||||
prev_mask[j] = SCULPT_vertex_mask_get(ss, vertex);
|
||||
}
|
||||
prev_mask = duplicate_mask(*ob);
|
||||
}
|
||||
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
|
@ -211,10 +208,6 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||
mask_filter_task(ss, filter_type, prev_mask, mask_write, nodes[i]);
|
||||
}
|
||||
});
|
||||
|
||||
if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
|
||||
MEM_freeN(prev_mask);
|
||||
}
|
||||
}
|
||||
|
||||
undo::push_end(ob);
|
||||
|
|
|
@ -709,7 +709,7 @@ struct Cache {
|
|||
Array<int> initial_face_sets;
|
||||
|
||||
/* Original data of the sculpt as it was before running the Expand operator. */
|
||||
float *original_mask;
|
||||
Array<float> original_mask;
|
||||
Array<int> original_face_sets;
|
||||
float (*original_colors)[4];
|
||||
|
||||
|
|
Loading…
Reference in New Issue