diff options
author | Hans Goudey <h.goudey@me.com> | 2022-09-23 17:38:37 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-09-23 18:45:07 +0300 |
commit | 12becbf0dffe06b6f28c4cc444fe0312cf9249b9 (patch) | |
tree | fb7b54e30e9144021ba0714e0c2dd78eb8f5e928 /source/blender/editors/object/object_vgroup.cc | |
parent | e345686cb7f4a8ccdc10e85d4f05cded45850cf7 (diff) |
Mesh: Move selection flags to generic attributes
Using the attribute name semantics from T97452, this patch moves the
selection status of mesh elements from the `SELECT` of vertices, and
edges, and the `ME_FACE_SEL` of faces to generic boolean attribute
Storing this data as generic attributes can significantly simplify and
improve code, as described in T95965.
The attributes are called `.select_vert`, `.select_edge`, and
`.select_poly`. The `.` prefix means they are "UI attributes",so they
still contain original data edited by users, but they aren't meant to
be accessed procedurally by the user in arbitrary situations. They are
also be hidden in the spreadsheet and the attribute list.
Until 4.0, the attributes are still written to and read from the mesh
in the old way, so neither forward nor backward compatibility are
affected. This means memory requirements will be increased by one byte
per element when selection is used. When the flags are removed
completely, requirements will decrease.
Further notes:
* The `MVert` flag is empty at runtime now, so it can be ignored.
* `BMesh` is unchanged, otherwise the change would be much larger.
* Many tests have slightly different results, since the selection
attribute uses more generic propagation. Previously you couldn't
really rely on edit mode selections being propagated procedurally.
Now it mostly works as expected.
Similar to 2480b55f216c
Ref T95965
Differential Revision: https://developer.blender.org/D15795
Diffstat (limited to 'source/blender/editors/object/object_vgroup.cc')
-rw-r--r-- | source/blender/editors/object/object_vgroup.cc | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 1d1263494c7..44fea0b32f0 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -31,6 +31,7 @@ #include "BLI_utildefines_stack.h" #include "BLI_vector.hh" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_deform.h" @@ -154,6 +155,7 @@ bool ED_vgroup_parray_alloc(ID *id, int *dvert_tot, const bool use_vert_sel) { + using namespace blender; *dvert_tot = 0; *dvert_arr = nullptr; @@ -200,7 +202,6 @@ bool ED_vgroup_parray_alloc(ID *id, return true; } if (!me->deform_verts().is_empty()) { - const Span<MVert> verts = me->verts(); MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); *dvert_tot = me->totvert; @@ -208,8 +209,12 @@ bool ED_vgroup_parray_alloc(ID *id, MEM_mallocN(sizeof(void *) * me->totvert, __func__)); if (use_vert_sel) { + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + for (int i = 0; i < me->totvert; i++) { - (*dvert_arr)[i] = (verts[i].flag & SELECT) ? &dverts[i] : nullptr; + (*dvert_arr)[i] = select_vert[i] ? &dverts[i] : nullptr; } } else { @@ -636,6 +641,7 @@ static bool vgroup_normalize_active_vertex(Object *ob, eVGroupSelect subset_type static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type) { + using namespace blender; Mesh *me = static_cast<Mesh *>(ob->data); BMEditMesh *em = me->edit_mesh; MDeformVert *dvert_act; @@ -663,14 +669,17 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type) } } else { - const Span<MVert> verts = me->verts(); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + int v_act; dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); if (dvert_act) { MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); for (i = 0; i < me->totvert; i++) { - if ((verts[i].flag & SELECT) && &dverts[i] != dvert_act) { + if (select_vert[i] && &dverts[i] != dvert_act) { BKE_defvert_copy_subset(&dverts[i], dvert_act, vgroup_validmap, vgroup_tot); if (me->symmetry & ME_SYMMETRY_X) { ED_mesh_defvert_mirror_update_ob(ob, -1, i); @@ -1011,6 +1020,7 @@ void ED_vgroup_select_by_name(Object *ob, const char *name) /* only in editmode */ static void vgroup_select_verts(Object *ob, int select) { + using namespace blender; const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1; const ListBase *defbase = BKE_object_defgroup_list(ob); @@ -1051,26 +1061,21 @@ static void vgroup_select_verts(Object *ob, int select) else { const Span<MDeformVert> dverts = me->deform_verts(); if (!dverts.is_empty()) { - const bool *hide_vert = (const bool *)CustomData_get_layer_named( - &me->vdata, CD_PROP_BOOL, ".hide_vert"); - MVert *mv; - int i; - - mv = me->verts_for_write().data(); - - for (i = 0; i < me->totvert; i++, mv++) { - if (!(hide_vert != nullptr && hide_vert[i])) { + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( + ".hide_vert", ATTR_DOMAIN_POINT, false); + bke::SpanAttributeWriter<bool> select_vert = + attributes.lookup_or_add_for_write_only_span<bool>(".select_vert", ATTR_DOMAIN_POINT); + + for (const int i : select_vert.span.index_range()) { + if (!hide_vert[i]) { if (BKE_defvert_find_index(&dverts[i], def_nr)) { - if (select) { - mv->flag |= SELECT; - } - else { - mv->flag &= ~SELECT; - } + select_vert.span[i] = select; } } } + select_vert.finish(); paintvert_flush_flags(ob); } } @@ -1519,6 +1524,7 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, static void vgroup_fix( const bContext *C, Scene *UNUSED(scene), Object *ob, float distToBe, float strength, float cp) { + using namespace blender; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); @@ -1529,8 +1535,11 @@ static void vgroup_fix( if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL)) { return; } + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); for (i = 0; i < me->totvert && mvert; i++, mvert++) { - if (mvert->flag & SELECT) { + if (select_vert[i]) { blender::Vector<int> verts = getSurroundingVerts(me, i); const int count = verts.size(); if (!verts.is_empty()) { @@ -1893,6 +1902,7 @@ static void vgroup_smooth_subset(Object *ob, const int repeat, const float fac_expand) { + using namespace blender; const float ifac = 1.0f - fac; MDeformVert **dvert_array = nullptr; int dvert_tot = 0; @@ -1912,6 +1922,10 @@ static void vgroup_smooth_subset(Object *ob, BMesh *bm = em ? em->bm : nullptr; Mesh *me = em ? nullptr : static_cast<Mesh *>(ob->data); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + MeshElemMap *emap; int *emap_mem; @@ -1955,7 +1969,7 @@ static void vgroup_smooth_subset(Object *ob, nullptr; #define IS_ME_VERT_READ(v) (use_hide ? !(hide_vert && hide_vert[v]) : true) -#define IS_ME_VERT_WRITE(v) (use_select ? (((v)->flag & SELECT) != 0) : true) +#define IS_ME_VERT_WRITE(v) (use_select ? select_vert[v] : true) /* initialize used verts */ if (bm) { @@ -1975,11 +1989,9 @@ static void vgroup_smooth_subset(Object *ob, } } else { - const Span<MVert> verts = me->verts(); const blender::Span<MEdge> edges = me->edges(); for (int i = 0; i < dvert_tot; i++) { - const MVert *v = &verts[i]; - if (IS_ME_VERT_WRITE(v)) { + if (IS_ME_VERT_WRITE(i)) { for (int j = 0; j < emap[i].count; j++) { const MEdge *e = &edges[emap[i].indices[j]]; const int i_other = (e->v1 == i) ? e->v2 : e->v1; @@ -2053,7 +2065,7 @@ static void vgroup_smooth_subset(Object *ob, const blender::Span<MEdge> edges = me->edges(); /* checked already */ - BLI_assert(IS_ME_VERT_WRITE(&me->verts()[i])); + BLI_assert(IS_ME_VERT_WRITE(i)); for (j = 0; j < emap[i].count; j++) { const MEdge *e = &edges[emap[i].indices[j]]; @@ -2360,6 +2372,7 @@ void ED_vgroup_mirror(Object *ob, int *r_totmirr, int *r_totfail) { + using namespace blender; /* TODO: vgroup locking. * TODO: face masking. */ @@ -2458,7 +2471,6 @@ void ED_vgroup_mirror(Object *ob, } else { /* object mode / weight paint */ - const MVert *mv, *mv_mirr; int vidx, vidx_mirr; const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; @@ -2471,19 +2483,20 @@ void ED_vgroup_mirror(Object *ob, } BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); - const MVert *verts = me->verts().data(); MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); - for (vidx = 0, mv = verts; vidx < me->totvert; vidx++, mv++) { + for (vidx = 0; vidx < me->totvert; vidx++) { if (!BLI_BITMAP_TEST(vert_tag, vidx)) { if ((vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology)) != -1) { if (vidx != vidx_mirr) { - mv_mirr = &verts[vidx_mirr]; if (!BLI_BITMAP_TEST(vert_tag, vidx_mirr)) { if (use_vert_sel) { - sel = mv->flag & SELECT; - sel_mirr = mv_mirr->flag & SELECT; + sel = select_vert[vidx]; + sel_mirr = select_vert[vidx_mirr]; } if (sel || sel_mirr) { @@ -2587,6 +2600,7 @@ static void vgroup_delete_active(Object *ob) /* only in editmode */ static void vgroup_assign_verts(Object *ob, const float weight) { + using namespace blender; const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1; const ListBase *defbase = BKE_object_defgroup_list(ob); @@ -2625,15 +2639,16 @@ static void vgroup_assign_verts(Object *ob, const float weight) } } else { - const Span<MVert> verts = me->verts(); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); - MDeformVert *dv = dverts.data(); - for (int i = 0; i < me->totvert; i++, dv++) { - const MVert *mv = &verts[i]; - if (mv->flag & SELECT) { + for (int i = 0; i < me->totvert; i++) { + if (select_vert[i]) { MDeformWeight *dw; - dw = BKE_defvert_ensure_index(dv, def_nr); + dw = BKE_defvert_ensure_index(&dverts[i], def_nr); if (dw) { dw->weight = weight; } @@ -4314,6 +4329,7 @@ void OBJECT_OT_vertex_group_move(wmOperatorType *ot) static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) { + using namespace blender; MDeformVert *dvert_act; Mesh *me = static_cast<Mesh *>(ob->data); @@ -4348,7 +4364,6 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) } } else { - MDeformVert *dv; int v_act; dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); @@ -4356,14 +4371,14 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) return; } - const Span<MVert> verts = me->verts(); MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); + const bke::AttributeAccessor attributes = me->attributes(); + const VArray<bool> select_vert = attributes.lookup_or_default<bool>( + ".select_vert", ATTR_DOMAIN_POINT, false); - dv = dverts.data(); - for (i = 0; i < me->totvert; i++, dv++) { - if ((verts[i].flag & SELECT) && (dv != dvert_act)) { - - BKE_defvert_copy_index(dv, def_nr, dvert_act, def_nr); + for (i = 0; i < me->totvert; i++) { + if (select_vert[i] && (&dverts[i] != dvert_act)) { + BKE_defvert_copy_index(&dverts[i], def_nr, dvert_act, def_nr); if (me->symmetry & ME_SYMMETRY_X) { ED_mesh_defvert_mirror_update_ob(ob, -1, i); |