diff options
Diffstat (limited to 'source/blender/editors/mesh/editface.cc')
-rw-r--r-- | source/blender/editors/mesh/editface.cc | 150 |
1 files changed, 80 insertions, 70 deletions
diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 4dd0c40c91b..6bc8a20bf31 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -9,8 +9,6 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_span.hh" -#include "BLI_virtual_array.hh" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -19,9 +17,9 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_customdata.h" -#include "BKE_geometry_set.hh" #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_object.h" @@ -37,20 +35,20 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" -using blender::MutableSpan; -using blender::VArray; -using blender::bke::OutputAttribute_Typed; - /* own include */ -void paintface_flush_flags(bContext *C, Object *ob, short flag, const bool flush_hidden) +void paintface_flush_flags(bContext *C, + Object *ob, + const bool flush_selection, + const bool flush_hidden) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); MPoly *polys, *mp_orig; const int *index_array = nullptr; int totpoly; - BLI_assert((flag & SELECT) || flush_hidden); + BLI_assert(flush_selection || flush_hidden); if (me == nullptr) { return; @@ -60,7 +58,7 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag, const bool flush /* we could call this directly in all areas that change selection, * since this could become slow for realtime updates (circle-select for eg) */ - if (flag & SELECT) { + if (flush_selection) { BKE_mesh_flush_select_from_polys(me); } @@ -71,8 +69,11 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag, const bool flush return; } + bke::AttributeAccessor attributes_me = bke::mesh_attributes(*me); Mesh *me_orig = (Mesh *)ob_eval->runtime.data_orig; + bke::MutableAttributeAccessor attributes_orig = bke::mesh_attributes_for_write(*me_orig); Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval; + bke::MutableAttributeAccessor attributes_eval = bke::mesh_attributes_for_write(*me_eval); bool updated = false; if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) { @@ -80,13 +81,17 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag, const bool flush for (int i = 0; i < me->totpoly; i++) { me_orig->mpoly[i].flag = me->mpoly[i].flag; } - - /* If the mesh has only deform modifiers, the evaluated mesh shares arrays. */ - if (me_eval->mpoly == me_orig->mpoly) { - updated = true; + if (flush_hidden) { + const VArray<bool> hide_face_me = attributes_me.lookup_or_default<bool>( + ".hide_face", ATTR_DOMAIN_FACE, false); + bke::SpanAttributeWriter<bool> hide_face_orig = + attributes_orig.lookup_or_add_for_write_only_span<bool>(".hide_face", ATTR_DOMAIN_FACE); + hide_face_me.materialize(hide_face_orig.span); + hide_face_orig.finish(); } + /* Mesh polys => Final derived polys */ - else if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) { + if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) { polys = me_eval->mpoly; totpoly = me_eval->totpoly; @@ -98,6 +103,17 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag, const bool flush polys[i].flag = mp_orig->flag; } } + const VArray<bool> hide_face_orig = attributes_orig.lookup_or_default<bool>( + ".hide_face", ATTR_DOMAIN_FACE, false); + bke::SpanAttributeWriter<bool> hide_face_eval = + attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_face", ATTR_DOMAIN_FACE); + for (const int i : IndexRange(me_eval->totpoly)) { + const int orig_face_index = index_array[i]; + if (orig_face_index != ORIGINDEX_NONE) { + hide_face_eval.span[i] = hide_face_orig[orig_face_index]; + } + } + hide_face_eval.finish(); updated = true; } @@ -122,80 +138,77 @@ void paintface_flush_flags(bContext *C, Object *ob, short flag, const bool flush void paintface_hide(bContext *C, Object *ob, const bool unselected) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); if (me == nullptr || me->totpoly == 0) { return; } - MeshComponent component; - component.replace(me, GeometryOwnershipType::Editable); - - OutputAttribute_Typed<bool> face_hide_attribute = - component.attribute_try_get_for_output_only<bool>(".hide_face", ATTR_DOMAIN_FACE); - MutableSpan<bool> face_hide = face_hide_attribute.as_span(); + bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me); + bke::SpanAttributeWriter<bool> hide_face = attributes.lookup_or_add_for_write_span<bool>( + ".hide_face", ATTR_DOMAIN_FACE); for (int i = 0; i < me->totpoly; i++) { MPoly *mpoly = &me->mpoly[i]; - if (!face_hide[i]) { + if (!hide_face.span[i]) { if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) { - face_hide[i] = true; + hide_face.span[i] = true; } } - if (face_hide[i]) { + if (hide_face.span[i]) { mpoly->flag &= ~ME_FACE_SEL; } } - face_hide_attribute.save(); + hide_face.finish(); BKE_mesh_flush_hidden_from_polys(me); - paintface_flush_flags(C, ob, SELECT, true); + paintface_flush_flags(C, ob, true, true); } void paintface_reveal(bContext *C, Object *ob, const bool select) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); if (me == nullptr || me->totpoly == 0) { return; } - MeshComponent component; - component.replace(me, GeometryOwnershipType::Editable); + bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me); if (select) { - const VArray<bool> face_hide = component.attribute_get_for_read<bool>( + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( ".hide_face", ATTR_DOMAIN_FACE, false); for (int i = 0; i < me->totpoly; i++) { MPoly *mpoly = &me->mpoly[i]; - if (face_hide[i]) { + if (hide_face[i]) { mpoly->flag |= ME_FACE_SEL; } } } - component.attribute_try_delete(".hide_face"); + attributes.remove(".hide_face"); BKE_mesh_flush_hidden_from_polys(me); - paintface_flush_flags(C, ob, SELECT, true); + paintface_flush_flags(C, ob, true, true); } /* Set object-mode face selection seams based on edge data, uses hash table to find seam edges. */ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bool select) { + using namespace blender; bool do_it = true; bool mark = false; BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__); BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__); - MeshComponent component; - component.replace(me, GeometryOwnershipType::Editable); - - const VArray<bool> face_hide = component.attribute_get_for_read<bool>( + bke::AttributeAccessor attributes = bke::mesh_attributes(*me); + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( ".hide_face", ATTR_DOMAIN_FACE, false); if (index != (uint)-1) { @@ -208,7 +221,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo /* fill array by selection */ for (int i = 0; i < me->totpoly; i++) { MPoly *mp = &me->mpoly[i]; - if (face_hide[i]) { + if (hide_face[i]) { /* pass */ } else if (mp->flag & ME_FACE_SEL) { @@ -224,7 +237,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo /* expand selection */ for (int i = 0; i < me->totpoly; i++) { MPoly *mp = &me->mpoly[i]; - if (face_hide[i]) { + if (hide_face[i]) { continue; } @@ -279,20 +292,19 @@ void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const b select_linked_tfaces_with_seams(me, index, select); - paintface_flush_flags(C, ob, SELECT, false); + paintface_flush_flags(C, ob, true, false); } bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool flush_flags) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); if (me == nullptr) { return false; } - MeshComponent component; - component.replace(me, GeometryOwnershipType::Editable); - - const VArray<bool> face_hide = component.attribute_get_for_read<bool>( + bke::AttributeAccessor attributes = bke::mesh_attributes(*me); + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( ".hide_face", ATTR_DOMAIN_FACE, false); if (action == SEL_TOGGLE) { @@ -300,7 +312,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl for (int i = 0; i < me->totpoly; i++) { MPoly *mpoly = &me->mpoly[i]; - if (!face_hide[i] && mpoly->flag & ME_FACE_SEL) { + if (!hide_face[i] && mpoly->flag & ME_FACE_SEL) { action = SEL_DESELECT; break; } @@ -311,7 +323,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl for (int i = 0; i < me->totpoly; i++) { MPoly *mpoly = &me->mpoly[i]; - if (!face_hide[i]) { + if (!hide_face[i]) { switch (action) { case SEL_SELECT: if ((mpoly->flag & ME_FACE_SEL) == 0) { @@ -335,7 +347,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl if (changed) { if (flush_flags) { - paintface_flush_flags(C, ob, SELECT, false); + paintface_flush_flags(C, ob, true, false); } } return changed; @@ -343,6 +355,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) { + using namespace blender; bool ok = false; float vec[3], bmat[3][3]; @@ -354,15 +367,13 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) copy_m3_m4(bmat, ob->obmat); - MeshComponent component; - component.replace(const_cast<Mesh *>(me), GeometryOwnershipType::ReadOnly); - - const VArray<bool> face_hide = component.attribute_get_for_read<bool>( + bke::AttributeAccessor attributes = bke::mesh_attributes(*me); + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( ".hide_face", ATTR_DOMAIN_FACE, false); for (int i = 0; i < me->totpoly; i++) { MPoly *mp = &me->mpoly[i]; - if (face_hide[i] || !(mp->flag & ME_FACE_SEL)) { + if (hide_face[i] || !(mp->flag & ME_FACE_SEL)) { continue; } @@ -384,6 +395,7 @@ bool paintface_mouse_select(bContext *C, const SelectPick_Params *params, Object *ob) { + using namespace blender; MPoly *mpoly_sel = nullptr; uint index; bool changed = false; @@ -392,16 +404,14 @@ bool paintface_mouse_select(bContext *C, /* Get the face under the cursor */ Mesh *me = BKE_mesh_from_object(ob); - MeshComponent component; - component.replace(const_cast<Mesh *>(me), GeometryOwnershipType::ReadOnly); - - const VArray<bool> face_hide = component.attribute_get_for_read<bool>( + bke::AttributeAccessor attributes = bke::mesh_attributes(*me); + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( ".hide_face", ATTR_DOMAIN_FACE, false); if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) { if (index < me->totpoly) { mpoly_sel = me->mpoly + index; - if (!face_hide[index]) { + if (!hide_face[index]) { found = true; } } @@ -450,7 +460,7 @@ bool paintface_mouse_select(bContext *C, /* image window redraw */ - paintface_flush_flags(C, ob, SELECT, false); + paintface_flush_flags(C, ob, true, false); ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */ changed = true; } @@ -511,23 +521,24 @@ void paintvert_tag_select_update(bContext *C, Object *ob) bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); if (me == nullptr) { return false; } - MeshComponent component; - component.replace(const_cast<Mesh *>(me), GeometryOwnershipType::ReadOnly); - - const VArray<bool> vert_hide = component.attribute_get_for_read<bool>( - "vert_hide", ATTR_DOMAIN_POINT, false); + bke::AttributeAccessor attributes = bke::mesh_attributes(*me); + const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( + ".hide_vert", ATTR_DOMAIN_POINT, false); + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( + ".hide_face", ATTR_DOMAIN_FACE, false); if (action == SEL_TOGGLE) { action = SEL_SELECT; for (int i = 0; i < me->totvert; i++) { MVert *mvert = &me->mvert[i]; - if (!vert_hide[i] && mvert->flag & SELECT) { + if (!hide_face[i] && mvert->flag & SELECT) { action = SEL_DESELECT; break; } @@ -537,7 +548,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) bool changed = false; for (int i = 0; i < me->totvert; i++) { MVert *mvert = &me->mvert[i]; - if (!vert_hide[i]) { + if (!hide_vert[i]) { switch (action) { case SEL_SELECT: if ((mvert->flag & SELECT) == 0) { @@ -580,6 +591,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); if (me == nullptr || me->dvert == nullptr) { @@ -590,16 +602,14 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags) paintvert_deselect_all_visible(ob, SEL_DESELECT, false); } - MeshComponent component; - component.replace(const_cast<Mesh *>(me), GeometryOwnershipType::ReadOnly); - - const VArray<bool> vert_hide = component.attribute_get_for_read<bool>( - "vert_hide", ATTR_DOMAIN_POINT, false); + bke::AttributeAccessor attributes = bke::mesh_attributes(*me); + const VArray<bool> hide_face = attributes.lookup_or_default<bool>( + ".hide_face", ATTR_DOMAIN_FACE, false); for (int i = 0; i < me->totvert; i++) { MVert *mv = &me->mvert[i]; MDeformVert *dv = &me->dvert[i]; - if (!vert_hide[i]) { + if (!hide_face[i]) { if (dv->dw == nullptr) { /* if null weight then not grouped */ mv->flag |= SELECT; |