diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index fc5f7bcba74..6928395ac49 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -2003,23 +2003,22 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, Object *ob, MultiresModifierData *mmd) { + using namespace blender; + using namespace blender::bke; Mesh *me = static_cast(ob->data); - const blender::OffsetIndices faces = me->faces(); + const OffsetIndices faces = me->faces(); const Span corner_verts = me->corner_verts(); + MutableAttributeAccessor attributes = me->attributes_for_write(); int ret = 0; - const float *paint_mask = static_cast( - CustomData_get_layer_named(&me->vert_data, CD_PROP_FLOAT, ".sculpt_mask")); - /* if multires is active, create a grid paint mask layer if there * isn't one already */ if (mmd && !CustomData_has_layer(&me->loop_data, CD_GRID_PAINT_MASK)) { - GridPaintMask *gmask; int level = max_ii(1, mmd->sculptlvl); int gridsize = BKE_ccg_gridsize(level); int gridarea = gridsize * gridsize; - gmask = static_cast( + GridPaintMask *gmask = static_cast( CustomData_add_layer(&me->loop_data, CD_GRID_PAINT_MASK, CD_SET_DEFAULT, me->totloop)); for (int i = 0; i < me->totloop; i++) { @@ -2031,14 +2030,15 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, } /* If vertices already have mask, copy into multires data. */ - if (paint_mask) { + if (const VArray mask = *attributes.lookup(".sculpt_mask", ATTR_DOMAIN_POINT)) { + const VArraySpan mask_span(mask); for (const int i : faces.index_range()) { - const blender::IndexRange face = faces[i]; + const IndexRange face = faces[i]; /* Mask center. */ float avg = 0.0f; for (const int vert : corner_verts.slice(face)) { - avg += paint_mask[vert]; + avg += mask_span[vert]; } avg /= float(face.size()); @@ -2046,13 +2046,13 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, for (const int corner : face) { GridPaintMask *gpm = &gmask[corner]; const int vert = corner_verts[corner]; - const int prev = corner_verts[blender::bke::mesh::face_corner_prev(face, vert)]; - const int next = corner_verts[blender::bke::mesh::face_corner_next(face, vert)]; + const int prev = corner_verts[mesh::face_corner_prev(face, vert)]; + const int next = corner_verts[mesh::face_corner_next(face, vert)]; gpm->data[0] = avg; - gpm->data[1] = (paint_mask[vert] + paint_mask[next]) * 0.5f; - gpm->data[2] = (paint_mask[vert] + paint_mask[prev]) * 0.5f; - gpm->data[3] = paint_mask[vert]; + gpm->data[1] = (mask_span[vert] + mask_span[next]) * 0.5f; + gpm->data[2] = (mask_span[vert] + mask_span[prev]) * 0.5f; + gpm->data[3] = mask_span[vert]; } } } @@ -2066,9 +2066,7 @@ int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, } /* Create vertex paint mask layer if there isn't one already. */ - if (!paint_mask) { - CustomData_add_layer_named( - &me->vert_data, CD_PROP_FLOAT, CD_SET_DEFAULT, me->totvert, ".sculpt_mask"); + if (attributes.add(".sculpt_mask", ATTR_DOMAIN_POINT, AttributeInitDefaultValue())) { /* The evaluated mesh must be updated to contain the new data. */ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); ret |= SCULPT_MASK_LAYER_CALC_VERT; diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index 61efe453c5a..128edb7c917 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -679,8 +679,6 @@ static void pbvh_draw_args_init(const Mesh &mesh, PBVH *pbvh, PBVH_GPU_Args *arg args->hide_poly = pbvh->face_data ? static_cast(CustomData_get_layer_named( pbvh->face_data, CD_PROP_BOOL, ".hide_poly")) : nullptr; - args->face_sets = static_cast( - CustomData_get_layer_named(&pbvh->mesh->face_data, CD_PROP_INT32, ".sculpt_face_set")); } args->active_color = mesh.active_color_attribute; @@ -3167,12 +3165,10 @@ bool pbvh_has_mask(const PBVH *pbvh) case PBVH_GRIDS: return (pbvh->gridkey.has_mask != 0); case PBVH_FACES: - return (pbvh->vert_data && - CustomData_has_layer_named(pbvh->vert_data, CD_PROP_FLOAT, ".sculpt_mask")); + return pbvh->mesh->attributes().contains(".sculpt_mask"); case PBVH_BMESH: - return (pbvh->header.bm && - (CustomData_get_offset_named( - &pbvh->header.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask") != -1)); + return pbvh->header.bm && + (CustomData_has_layer_named(&pbvh->header.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask")); } return false; @@ -3183,8 +3179,7 @@ bool pbvh_has_face_sets(PBVH *pbvh) switch (pbvh->header.type) { case PBVH_GRIDS: case PBVH_FACES: - return pbvh->face_data && CustomData_get_layer_named( - pbvh->face_data, CD_PROP_INT32, ".sculpt_face_set") != nullptr; + return pbvh->mesh->attributes().contains(".sculpt_face_set"); case PBVH_BMESH: return false; } diff --git a/source/blender/draw/DRW_pbvh.hh b/source/blender/draw/DRW_pbvh.hh index f96a209457d..1f2049f53a6 100644 --- a/source/blender/draw/DRW_pbvh.hh +++ b/source/blender/draw/DRW_pbvh.hh @@ -52,7 +52,6 @@ struct PBVH_GPU_Args { const char *render_color; int face_sets_color_seed, face_sets_color_default; - const int *face_sets; /* for PBVH_FACES and PBVH_GRIDS */ SubdivCCG *subdiv_ccg; const DMFlagMat *grid_flag_mats; diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 9ab51d84c26..742c2082f1e 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -575,34 +575,32 @@ struct PBVHBatches { } } else if (vbo.type == CD_PBVH_FSET_TYPE) { - const int *face_sets = args.face_sets; - - if (!face_sets) { - uchar white[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; - - foreach_grids( - [&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int /*i*/) { - *static_cast(GPU_vertbuf_raw_step(&access)) = white; - }); - } - else { + const bke::AttributeAccessor attributes = args.me->attributes(); + if (const VArray face_sets = *attributes.lookup(".sculpt_face_set", + ATTR_DOMAIN_FACE)) { + const VArraySpan face_sets_span(face_sets); foreach_grids( [&](int /*x*/, int /*y*/, int grid_index, CCGElem * /*elems*/[4], int /*i*/) { uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; - if (face_sets) { - const int face_index = BKE_subdiv_ccg_grid_to_face_index(args.subdiv_ccg, - grid_index); - const int fset = face_sets[face_index]; + const int face_index = BKE_subdiv_ccg_grid_to_face_index(args.subdiv_ccg, + grid_index); + const int fset = face_sets_span[face_index]; - /* Skip for the default color Face Set to render it white. */ - if (fset != args.face_sets_color_default) { - BKE_paint_face_set_overlay_color_get( - fset, args.face_sets_color_seed, face_set_color); - } + /* Skip for the default color Face Set to render it white. */ + if (fset != args.face_sets_color_default) { + BKE_paint_face_set_overlay_color_get( + fset, args.face_sets_color_seed, face_set_color); } - *static_cast(GPU_vertbuf_raw_step(&access)) = face_set_color; + *static_cast(GPU_vertbuf_raw_step(&access)) = face_set_color; + }); + } + else { + const uchar white[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; + foreach_grids( + [&](int /*x*/, int /*y*/, int /*grid_index*/, CCGElem * /*elems*/[4], int /*i*/) { + *static_cast(GPU_vertbuf_raw_step(&access)) = white; }); } } @@ -697,6 +695,8 @@ struct PBVHBatches { GPUVertBuf &vert_buf = *vbo.vert_buf; + const bke::AttributeAccessor attributes = args.me->attributes(); + if (vbo.type == CD_PBVH_CO_TYPE) { extract_data_vert_faces(args, args.vert_positions, vert_buf); } @@ -704,35 +704,35 @@ struct PBVHBatches { fill_vbo_normal_faces(args, vert_buf); } else if (vbo.type == CD_PBVH_MASK_TYPE) { - if (const float *mask = static_cast( - CustomData_get_layer_named(args.vert_data, CD_PROP_FLOAT, ".sculpt_mask"))) + float *data = static_cast(GPU_vertbuf_get_data(&vert_buf)); + if (const VArray mask = *attributes.lookup(".sculpt_mask", ATTR_DOMAIN_POINT)) { + const VArraySpan mask_span(mask); const Span corner_verts = args.corner_verts; const Span looptris = args.mlooptri; const Span looptri_faces = args.looptri_faces; const bool *hide_poly = args.hide_poly; - float *data = static_cast(GPU_vertbuf_get_data(&vert_buf)); for (const int looptri_i : args.prim_indices) { if (hide_poly && hide_poly[looptri_faces[looptri_i]]) { continue; } for (int i : IndexRange(3)) { const int vert = corner_verts[looptris[looptri_i].tri[i]]; - *data = mask[vert]; + *data = mask_span[vert]; data++; } } } else { - MutableSpan(static_cast(GPU_vertbuf_get_data(vbo.vert_buf)), totvert).fill(0); + MutableSpan(data, totvert).fill(0); } } else if (vbo.type == CD_PBVH_FSET_TYPE) { - const int *face_sets = static_cast( - CustomData_get_layer_named(args.face_data, CD_PROP_INT32, ".sculpt_face_set")); uchar4 *data = static_cast(GPU_vertbuf_get_data(vbo.vert_buf)); - if (face_sets) { + if (const VArray face_sets = *attributes.lookup(".sculpt_face_set", + ATTR_DOMAIN_FACE)) { + const VArraySpan face_sets_span(face_sets); int last_face = -1; uchar4 fset_color(UCHAR_MAX); @@ -744,7 +744,7 @@ struct PBVHBatches { if (last_face != face_i) { last_face = face_i; - const int fset = face_sets[face_i]; + const int fset = face_sets_span[face_i]; if (fset != args.face_sets_color_default) { BKE_paint_face_set_overlay_color_get(fset, args.face_sets_color_seed, fset_color); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc index 6f87e66a8aa..1b7bdee85a2 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc @@ -10,6 +10,7 @@ #include "BLI_string.h" +#include "BKE_attribute.hh" #include "BKE_mesh.hh" #include "BKE_paint.hh" @@ -40,14 +41,6 @@ static void extract_sculpt_data_init(const MeshRenderData &mr, GPUVertBuf *vbo = static_cast(buf); GPUVertFormat *format = get_sculpt_data_format(); - CustomData *cd_vdata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->vdata : &mr.me->vert_data; - CustomData *cd_pdata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->pdata : &mr.me->face_data; - - const float *cd_mask = (const float *)CustomData_get_layer_named( - cd_vdata, CD_PROP_FLOAT, ".sculpt_mask"); - const int *cd_face_set = (const int *)CustomData_get_layer_named( - cd_pdata, CD_PROP_INT32, ".sculpt_face_set"); - GPU_vertbuf_init_with_format(vbo, format); GPU_vertbuf_data_alloc(vbo, mr.loop_len); @@ -59,8 +52,9 @@ static void extract_sculpt_data_init(const MeshRenderData &mr, gpuSculptData *vbo_data = (gpuSculptData *)GPU_vertbuf_get_data(vbo); if (mr.extract_type == MR_EXTRACT_BMESH) { - int cd_mask_ofs = CustomData_get_offset_named(cd_vdata, CD_PROP_FLOAT, ".sculpt_mask"); - int cd_face_set_ofs = CustomData_get_offset_named(cd_pdata, CD_PROP_INT32, ".sculpt_face_set"); + int cd_mask_ofs = CustomData_get_offset_named(&mr.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask"); + int cd_face_set_ofs = CustomData_get_offset_named( + &mr.bm->pdata, CD_PROP_INT32, ".sculpt_face_set"); BMIter f_iter; BMFace *efa; BM_ITER_MESH (efa, &f_iter, mr.bm, BM_FACES_OF_MESH) { @@ -68,12 +62,12 @@ static void extract_sculpt_data_init(const MeshRenderData &mr, l_iter = l_first = BM_FACE_FIRST_LOOP(efa); do { float v_mask = 0.0f; - if (cd_mask) { + if (cd_mask_ofs != -1) { v_mask = BM_ELEM_CD_GET_FLOAT(l_iter->v, cd_mask_ofs); } vbo_data->mask = v_mask; uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; - if (cd_face_set) { + if (cd_face_set_ofs != -1) { const int face_set_id = BM_ELEM_CD_GET_INT(l_iter->f, cd_face_set_ofs); if (face_set_id != mr.me->face_sets_color_default) { BKE_paint_face_set_overlay_color_get( @@ -86,17 +80,21 @@ static void extract_sculpt_data_init(const MeshRenderData &mr, } } else { + const bke::AttributeAccessor attributes = mr.me->attributes(); + const VArray mask = *attributes.lookup(".sculpt_mask", ATTR_DOMAIN_POINT); + const VArray face_set = *attributes.lookup(".sculpt_face_set", ATTR_DOMAIN_FACE); + for (int face_index = 0; face_index < mr.face_len; face_index++) { for (const int corner : mr.faces[face_index]) { float v_mask = 0.0f; - if (cd_mask) { - v_mask = cd_mask[mr.corner_verts[corner]]; + if (mask) { + v_mask = mask[mr.corner_verts[corner]]; } vbo_data->mask = v_mask; uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; - if (cd_face_set) { - const int face_set_id = cd_face_set[face_index]; + if (face_set) { + const int face_set_id = face_set[face_index]; /* Skip for the default color Face Set to render it white. */ if (face_set_id != mr.me->face_sets_color_default) { BKE_paint_face_set_overlay_color_get( @@ -119,19 +117,19 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache &subdiv_cache, GPUVertBuf *vbo = static_cast(buffer); Mesh *coarse_mesh = mr.me; - CustomData *cd_vdata = &coarse_mesh->vert_data; - CustomData *cd_pdata = &coarse_mesh->face_data; /* First, interpolate mask if available. */ GPUVertBuf *mask_vbo = nullptr; GPUVertBuf *subdiv_mask_vbo = nullptr; - const float *cd_mask = (const float *)CustomData_get_layer_named( - cd_vdata, CD_PROP_FLOAT, ".sculpt_mask"); + + const bke::AttributeAccessor attributes = coarse_mesh->attributes(); + const VArray mask = *attributes.lookup(".sculpt_mask", ATTR_DOMAIN_POINT); const OffsetIndices coarse_faces = coarse_mesh->faces(); const Span coarse_corner_verts = coarse_mesh->corner_verts(); - if (cd_mask) { + if (mask) { + const VArraySpan mask_span(mask); GPUVertFormat mask_format = {0}; GPU_vertformat_attr_add(&mask_format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); @@ -142,7 +140,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache &subdiv_cache, for (int i = 0; i < coarse_mesh->faces_num; i++) { for (const int vert : coarse_corner_verts.slice(coarse_faces[i])) { - *v_mask++ = cd_mask[vert]; + *v_mask++ = mask_span[vert]; } } @@ -165,8 +163,7 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache &subdiv_cache, }; gpuFaceSet *face_sets = (gpuFaceSet *)GPU_vertbuf_get_data(face_set_vbo); - const int *cd_face_set = (const int *)CustomData_get_layer_named( - cd_pdata, CD_PROP_INT32, ".sculpt_face_set"); + const VArray cd_face_sets = *attributes.lookup(".sculpt_mask", ATTR_DOMAIN_POINT); GPUVertFormat *format = get_sculpt_data_format(); GPU_vertbuf_init_build_on_device(vbo, format, subdiv_cache.num_subdiv_loops); @@ -176,8 +173,8 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache &subdiv_cache, const int face_index = subdiv_loop_face_index[i]; uchar face_set_color[4] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX, UCHAR_MAX}; - if (cd_face_set) { - const int face_set_id = cd_face_set[face_index]; + if (cd_face_sets) { + const int face_set_id = cd_face_sets[face_index]; /* Skip for the default color Face Set to render it white. */ if (face_set_id != coarse_mesh->face_sets_color_default) { BKE_paint_face_set_overlay_color_get( diff --git a/source/blender/editors/mesh/editmesh_mask_extract.cc b/source/blender/editors/mesh/editmesh_mask_extract.cc index 5c66861dbbe..80f42f87c36 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.cc +++ b/source/blender/editors/mesh/editmesh_mask_extract.cc @@ -12,6 +12,7 @@ #include "BLT_translation.h" +#include "BKE_attribute.hh" #include "BKE_context.hh" #include "BKE_editmesh.hh" #include "BKE_layer.h" @@ -205,13 +206,14 @@ static int geometry_extract_apply(bContext *C, C, OB_MESH, nullptr, ob->loc, ob->rot, false, local_view_bits); BKE_mesh_nomain_to_mesh(new_mesh, static_cast(new_ob->data), new_ob); + Mesh *new_ob_mesh = static_cast(new_ob->data); + /* Remove the Face Sets as they need to be recreated when entering Sculpt Mode in the new object. * TODO(pablodobarro): In the future we can try to preserve them from the original mesh. */ - Mesh *new_ob_mesh = static_cast(new_ob->data); - CustomData_free_layer_named(&new_ob_mesh->face_data, ".sculpt_face_set", new_ob_mesh->faces_num); + new_ob_mesh->attributes_for_write().remove(".sculpt_face_set"); /* Remove the mask from the new object so it can be sculpted directly after extracting. */ - CustomData_free_layer_named(&new_ob_mesh->vert_data, ".sculpt_mask", new_ob_mesh->totvert); + new_ob_mesh->attributes_for_write().remove(".sculpt_mask"); BKE_mesh_copy_parameters_for_eval(new_ob_mesh, mesh); @@ -509,7 +511,7 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) BM_mesh_free(bm); /* Remove the mask from the new object so it can be sculpted directly after slicing. */ - CustomData_free_layer_named(&new_ob_mesh->vert_data, ".sculpt_mask", new_ob_mesh->totvert); + new_ob_mesh->attributes_for_write().remove(".sculpt_mask"); Mesh *new_mesh = static_cast(new_ob->data); BKE_mesh_nomain_to_mesh(new_ob_mesh, new_mesh, new_ob); diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index 3944ae0f654..f930ee38d68 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -294,24 +294,22 @@ static void join_mesh_single(Depsgraph *depsgraph, * of them will have different IDs for their Face Sets. */ static void mesh_join_offset_face_sets_ID(Mesh *mesh, int *face_set_offset) { - if (!mesh->faces_num) { - return; - } - - int *face_sets = (int *)CustomData_get_layer_named_for_write( - &mesh->face_data, CD_PROP_INT32, ".sculpt_face_set", mesh->faces_num); + using namespace blender; + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + bke::SpanAttributeWriter face_sets = attributes.lookup_for_write_span( + ".sculpt_face_set"); if (!face_sets) { return; } int max_face_set = 0; - for (int f = 0; f < mesh->faces_num; f++) { + for (const int i : face_sets.span.index_range()) { /* As face sets encode the visibility in the integer sign, the offset needs to be added or * subtracted depending on the initial sign of the integer to get the new ID. */ - if (face_sets[f] <= *face_set_offset) { - face_sets[f] += *face_set_offset; + if (face_sets.span[i] <= *face_set_offset) { + face_sets.span[i] += *face_set_offset; } - max_face_set = max_ii(max_face_set, face_sets[f]); + max_face_set = max_ii(max_face_set, face_sets.span[i]); } *face_set_offset = max_face_set; } diff --git a/source/blender/editors/sculpt_paint/paint_hide.cc b/source/blender/editors/sculpt_paint/paint_hide.cc index 170c609588e..29b50207181 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.cc +++ b/source/blender/editors/sculpt_paint/paint_hide.cc @@ -21,6 +21,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_attribute.hh" #include "BKE_ccg.h" #include "BKE_context.hh" #include "BKE_mesh.hh" @@ -73,38 +74,36 @@ static void partialvis_update_mesh(Object *ob, PartialVisArea area, float planes[4][4]) { - Mesh *me = static_cast(ob->data); + using namespace blender; + Mesh *mesh = static_cast(ob->data); const blender::Span positions = BKE_pbvh_get_vert_positions(pbvh); - const float *paint_mask; bool any_changed = false, any_visible = false; const blender::Span verts = BKE_pbvh_node_get_vert_indices(node); - paint_mask = static_cast( - CustomData_get_layer_named(&me->vert_data, CD_PROP_FLOAT, ".sculpt_mask")); - bool *hide_vert = static_cast(CustomData_get_layer_named_for_write( - &me->vert_data, CD_PROP_BOOL, ".hide_vert", me->totvert)); - if (hide_vert == nullptr) { - hide_vert = static_cast(CustomData_add_layer_named( - &me->vert_data, CD_PROP_BOOL, CD_SET_DEFAULT, me->totvert, ".hide_vert")); - } + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + const VArray mask = *attributes.lookup_or_default( + ".sculpt_mask", ATTR_DOMAIN_POINT, 0.0f); + + bke::SpanAttributeWriter hide_vert = attributes.lookup_or_add_for_write_span( + ".hide_vert", ATTR_DOMAIN_POINT); SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); for (const int vert : verts) { - float vmask = paint_mask ? paint_mask[vert] : 0; - /* Hide vertex if in the hide volume. */ - if (is_effected(area, planes, positions[vert], vmask)) { - hide_vert[vert] = (action == PARTIALVIS_HIDE); + if (is_effected(area, planes, positions[vert], mask[vert])) { + hide_vert.span[vert] = (action == PARTIALVIS_HIDE); any_changed = true; } - if (!hide_vert[vert]) { + if (!hide_vert.span[vert]) { any_visible = true; } } + hide_vert.finish(); + if (any_changed) { BKE_pbvh_node_mark_rebuild_draw(node); BKE_pbvh_node_fully_hidden_set(node, !any_visible); diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index fb0d256d1b4..b79e121630c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -21,6 +21,7 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" +#include "BKE_attribute.hh" #include "BKE_brush.hh" #include "BKE_ccg.h" #include "BKE_colortools.h" @@ -1196,17 +1197,19 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp static void write_mask_data(SculptSession *ss, const Span mask) { + using namespace blender; Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, {}); switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh); - float *layer = static_cast(CustomData_get_layer_named_for_write( - &mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask", mesh->totvert)); + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + bke::SpanAttributeWriter attribute = attributes.lookup_or_add_for_write_span( + ".sculpt_mask", ATTR_DOMAIN_POINT); for (PBVHNode *node : nodes) { PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { - layer[vd.index] = mask[vd.index]; + attribute.span[vd.index] = mask[vd.index]; } BKE_pbvh_vertex_iter_end; BKE_pbvh_node_mark_redraw(node); diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 68631fdd15f..2bd4538c77c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -66,14 +66,16 @@ using blender::Vector; int ED_sculpt_face_sets_find_next_available_id(Mesh *mesh) { - const int *face_sets = static_cast( - CustomData_get_layer_named(&mesh->face_data, CD_PROP_INT32, ".sculpt_face_set")); - if (!face_sets) { + using namespace blender; + const VArray attribute = *mesh->attributes().lookup(".sculpt_face_set", + ATTR_DOMAIN_FACE); + if (!attribute) { return SCULPT_FACE_SET_NONE; } + const VArraySpan face_sets(attribute); int next_face_set_id = 0; - for (int i = 0; i < mesh->faces_num; i++) { + for (const int i : face_sets.index_range()) { next_face_set_id = max_ii(next_face_set_id, face_sets[i]); } next_face_set_id++; @@ -83,15 +85,17 @@ int ED_sculpt_face_sets_find_next_available_id(Mesh *mesh) void ED_sculpt_face_sets_initialize_none_to_id(Mesh *mesh, const int new_id) { - int *face_sets = static_cast(CustomData_get_layer_named_for_write( - &mesh->face_data, CD_PROP_INT32, ".sculpt_face_set", mesh->faces_num)); + using namespace blender; + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + bke::SpanAttributeWriter face_sets = attributes.lookup_for_write_span( + ".sculpt_face_set"); if (!face_sets) { return; } - for (int i = 0; i < mesh->faces_num; i++) { - if (face_sets[i] == SCULPT_FACE_SET_NONE) { - face_sets[i] = new_id; + for (const int i : face_sets.span.index_range()) { + if (face_sets.span[i] == SCULPT_FACE_SET_NONE) { + face_sets.span[i] = new_id; } } } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index 54973574909..b79d2c3db9d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -567,22 +567,20 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m SubdivCCG *subdiv_ccg = ss->subdiv_ccg; if (unode->maxvert) { - /* Regular mesh restore. */ - float *vmask = static_cast(CustomData_get_layer_named_for_write( - &mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask", mesh->totvert)); - if (!vmask) { - vmask = static_cast(CustomData_add_layer_named( - &mesh->vert_data, CD_PROP_FLOAT, CD_SET_DEFAULT, mesh->totvert, ".sculpt_mask")); - } + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + bke::SpanAttributeWriter mask = attributes.lookup_or_add_for_write_span( + ".sculpt_mask", ATTR_DOMAIN_POINT); const Span index = unode->index; for (int i = 0; i < unode->totvert; i++) { - if (vmask[index[i]] != unode->mask[i]) { - SWAP(float, vmask[index[i]], unode->mask[i]); + if (mask.span[index[i]] != unode->mask[i]) { + std::swap(mask.span[index[i]], unode->mask[i]); modified_vertices[index[i]] = true; } } + + mask.finish(); } else if (unode->maxgrid && subdiv_ccg != nullptr) { /* Multires restore. */ @@ -600,7 +598,7 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m grid = grids[unode->grids[j]]; for (int i = 0; i < gridsize * gridsize; i++) { - SWAP(float, *CCG_elem_offset_mask(&key, grid, i), mask[index]); + std::swap(*CCG_elem_offset_mask(&key, grid, i), mask[index]); index++; } }