diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 97e718513f1..b0334495bf6 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -372,14 +372,11 @@ static void fill_mask_bmesh(Object &object, const float value, const Span nodes) +static void fill_mask( + Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object, const float value) { PBVH &pbvh = *object.sculpt->pbvh; + Vector nodes = bke::pbvh::search_gather(&pbvh, {}); switch (BKE_pbvh_type(&pbvh)) { case PBVH_FACES: fill_mask_mesh(object, value, nodes); @@ -489,12 +486,9 @@ static void invert_mask_bmesh(Object &object, const Span nodes) }); } -static void invert_mask(Main &bmain, - const Scene &scene, - Depsgraph &depsgraph, - Object &object, - const Span nodes) +static void invert_mask(Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object) { + Vector nodes = bke::pbvh::search_gather(object.sculpt->pbvh, {}); switch (BKE_pbvh_type(object.sculpt->pbvh)) { case PBVH_FACES: invert_mask_mesh(object, nodes); @@ -521,16 +515,15 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) BKE_sculpt_update_object_for_edit(&depsgraph, &object, false); undo::push_begin(&object, op); - Vector nodes = bke::pbvh::search_gather(object.sculpt->pbvh, {}); switch (mode) { case PAINT_MASK_FLOOD_VALUE: - fill_mask(bmain, scene, depsgraph, object, value, nodes); + fill_mask(bmain, scene, depsgraph, object, value); break; case PAINT_MASK_FLOOD_VALUE_INVERSE: - fill_mask(bmain, scene, depsgraph, object, 1.0f - value, nodes); + fill_mask(bmain, scene, depsgraph, object, 1.0f - value); break; case PAINT_MASK_INVERT: - invert_mask(bmain, scene, depsgraph, object, nodes); + invert_mask(bmain, scene, depsgraph, object); break; } diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index c63e51420e9..3a251a18b42 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -303,33 +303,6 @@ float SCULPT_mask_get_at_grids_vert_index(const SubdivCCG &subdiv_ccg, return *CCG_elem_offset_mask(&key, elem, index_in_grid); } -float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex) -{ - using namespace blender; - switch (BKE_pbvh_type(ss->pbvh)) { - case PBVH_FACES: { - const Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh); - const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray mask = *attributes.lookup_or_default( - ".sculpt_mask", bke::AttrDomain::Point, 0.0f); - return mask[vertex.i]; - } - case PBVH_BMESH: { - BMVert *v; - int cd_mask = CustomData_get_offset_named(&ss->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask"); - - v = (BMVert *)vertex.i; - return cd_mask != -1 ? BM_ELEM_CD_GET_FLOAT(v, cd_mask) : 0.0f; - } - case PBVH_GRIDS: { - return SCULPT_mask_get_at_grids_vert_index( - *ss->subdiv_ccg, *BKE_pbvh_get_grid_key(ss->pbvh), vertex.i); - } - } - - return 0.0f; -} - PBVHVertRef SCULPT_active_vertex_get(SculptSession *ss) { if (ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_BMESH, PBVH_GRIDS)) { diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index bfaebf283c7..7e821d01e03 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -2105,6 +2105,54 @@ static void sculpt_expand_undo_push(Object *ob, Cache *expand_cache) } } +static bool any_nonzero_mask(const Object &object) +{ + const SculptSession &ss = *object.sculpt; + switch (BKE_pbvh_type(ss.pbvh)) { + case PBVH_FACES: { + const Mesh &mesh = *static_cast(object.data); + const bke::AttributeAccessor attributes = mesh.attributes(); + const VArraySpan mask = *attributes.lookup(".sculpt_mask"); + if (mask.is_empty()) { + return false; + } + return std::any_of( + mask.begin(), mask.end(), [&](const float value) { return value > 0.0f; }); + } + case PBVH_GRIDS: { + const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; + const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); + if (!key.has_mask) { + return false; + } + return std::any_of(subdiv_ccg.grids.begin(), subdiv_ccg.grids.end(), [&](CCGElem *elem) { + for (const int i : IndexRange(key.grid_area)) { + if (*CCG_elem_offset_mask(&key, elem, i) > 0.0f) { + return true; + } + } + return false; + }); + } + case PBVH_BMESH: { + BMesh &bm = *ss.bm; + const int offset = CustomData_get_offset_named(&bm.vdata, CD_PROP_FLOAT, ".sculpt_mask"); + if (offset == -1) { + return false; + } + BMIter iter; + BMVert *vert; + BM_ITER_MESH (vert, &iter, &bm, BM_VERTS_OF_MESH) { + if (BM_ELEM_CD_GET_FLOAT(vert, offset) > 0.0f) { + return true; + } + } + return false; + } + } + return false; +} + static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -2134,19 +2182,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd); if (RNA_boolean_get(op->ptr, "use_auto_mask")) { - int verts_num = SCULPT_vertex_count_get(ss); - bool ok = true; - - for (int i = 0; i < verts_num; i++) { - PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); - - if (SCULPT_vertex_mask_get(ss, vertex) != 0.0f) { - ok = false; - break; - } - } - - if (ok) { + if (any_nonzero_mask(*ob)) { write_mask_data(ss, Array(SCULPT_vertex_count_get(ss), 1.0f)); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc index 98fbb2a40c8..e756b2adad8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc @@ -91,7 +91,7 @@ static void mask_filter_task(SculptSession *ss, switch (mode) { case MASK_FILTER_SMOOTH: case MASK_FILTER_SHARPEN: { - float val = smooth::neighbor_mask_average(ss, vd.vertex); + float val = smooth::neighbor_mask_average(ss, mask_write, vd.vertex); val -= mask; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index ec2f1e4fb5c..10e2ab6be52 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -877,7 +877,6 @@ void SCULPT_vertex_normal_get(const SculptSession *ss, PBVHVertRef vertex, float float SCULPT_mask_get_at_grids_vert_index(const SubdivCCG &subdiv_ccg, const CCGKey &key, int vert_index); -float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex); void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4]); void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4]); @@ -1522,7 +1521,7 @@ namespace blender::ed::sculpt_paint::smooth { void bmesh_four_neighbor_average(float avg[3], float direction[3], BMVert *v); void neighbor_coords_average(SculptSession *ss, float result[3], PBVHVertRef vertex); -float neighbor_mask_average(SculptSession *ss, PBVHVertRef vertex); +float neighbor_mask_average(SculptSession *ss, SculptMaskWriteInfo write_info, PBVHVertRef vertex); void neighbor_color_average(SculptSession *ss, float result[4], PBVHVertRef vertex); /** diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.cc b/source/blender/editors/sculpt_paint/sculpt_smooth.cc index 448a87d2c55..5ac45dcebc9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.cc @@ -134,22 +134,40 @@ void neighbor_coords_average(SculptSession *ss, float result[3], PBVHVertRef ver } } -float neighbor_mask_average(SculptSession *ss, PBVHVertRef vertex) +float neighbor_mask_average(SculptSession *ss, + const SculptMaskWriteInfo mask_write, + PBVHVertRef vertex) { float avg = 0.0f; int total = 0; - SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { - avg += SCULPT_vertex_mask_get(ss, ni.vertex); - total++; + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + avg += mask_write.layer[ni.vertex.i]; + total++; + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + break; + case PBVH_GRIDS: + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + avg += SCULPT_mask_get_at_grids_vert_index( + *ss->subdiv_ccg, *BKE_pbvh_get_grid_key(ss->pbvh), vertex.i); + total++; + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + break; + case PBVH_BMESH: + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + BMVert *vert = reinterpret_cast(vertex.i); + avg += BM_ELEM_CD_GET_FLOAT(vert, mask_write.bm_offset); + total++; + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + break; } - SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); - - if (total > 0) { - return avg / total; - } - return SCULPT_vertex_mask_get(ss, vertex); + BLI_assert(total > 0); + return avg / total; } void neighbor_color_average(SculptSession *ss, float result[4], PBVHVertRef vertex) @@ -289,7 +307,7 @@ static void smooth_mask_node(Object *ob, vd.vertex, thread_id, &automask_data); - float val = neighbor_mask_average(ss, vd.vertex) - vd.mask; + float val = neighbor_mask_average(ss, mask_write, vd.vertex) - vd.mask; val *= fade * bstrength; float new_mask = vd.mask + val; CLAMP(new_mask, 0.0f, 1.0f);