diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.cc')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.cc | 167 |
1 files changed, 107 insertions, 60 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index 447bf99b000..a0b3802076a 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -45,6 +45,7 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_curve.h" #include "BKE_editmesh.h" @@ -337,28 +338,29 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, EditSelectBuf_Cache *esel, const eSelectOp sel_op) { - MVert *verts = BKE_mesh_verts_for_write(me); - MVert *mv = verts; + using namespace blender; bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - if (mv) { - const bool *hide_vert = (const bool *)CustomData_get_layer_named( - &me->vdata, CD_PROP_BOOL, ".hide_vert"); + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>( + ".select_vert", ATTR_DOMAIN_POINT); + const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( + ".hide_vert", ATTR_DOMAIN_POINT, false); - for (int index = 0; index < me->totvert; index++, mv++) { - if (!(hide_vert && hide_vert[index])) { - const bool is_select = mv->flag & SELECT; - const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index); - const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); - if (sel_op_result != -1) { - SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT); - changed = true; - } + for (int index = 0; index < me->totvert; index++) { + if (!hide_vert[index]) { + const bool is_select = select_vert.span[index]; + const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index); + const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); + if (sel_op_result != -1) { + select_vert.span[index] = sel_op_result == 1; + changed = true; } } } + select_vert.finish(); return changed; } @@ -367,27 +369,29 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me, EditSelectBuf_Cache *esel, const eSelectOp sel_op) { - MPoly *polys = BKE_mesh_polys_for_write(me); + using namespace blender; bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - if (polys) { - const bool *hide_poly = (const bool *)CustomData_get_layer_named( - &me->vdata, CD_PROP_BOOL, ".hide_poly"); + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>( + ".select_poly", ATTR_DOMAIN_FACE); + const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( + ".hide_poly", ATTR_DOMAIN_FACE, false); - for (int index = 0; index < me->totpoly; index++) { - if (!(hide_poly && hide_poly[index])) { - const bool is_select = polys[index].flag & ME_FACE_SEL; - const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index); - const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); - if (sel_op_result != -1) { - SET_FLAG_FROM_TEST(polys[index].flag, sel_op_result, ME_FACE_SEL); - changed = true; - } + for (int index = 0; index < me->totpoly; index++) { + if (!hide_poly[index]) { + const bool is_select = select_poly.span[index]; + const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index); + const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); + if (sel_op_result != -1) { + select_poly.span[index] = sel_op_result == 1; + changed = true; } } } + select_poly.finish(); return changed; } @@ -1154,20 +1158,27 @@ static bool do_lasso_select_meta(ViewContext *vc, return data.is_changed; } +struct LassoSelectUserData_ForMeshVert { + LassoSelectUserData lasso_data; + blender::MutableSpan<bool> select_vert; +}; static void do_lasso_select_meshobject__doSelectVert(void *userData, - MVert *mv, + MVert * /*mv*/, const float screen_co[2], - int UNUSED(index)) + int index) { - LassoSelectUserData *data = static_cast<LassoSelectUserData *>(userData); - const bool is_select = mv->flag & SELECT; + using namespace blender; + LassoSelectUserData_ForMeshVert *mesh_data = static_cast<LassoSelectUserData_ForMeshVert *>( + userData); + LassoSelectUserData *data = &mesh_data->lasso_data; + const bool is_select = mesh_data->select_vert[index]; const bool is_inside = (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && BLI_lasso_is_point_inside( data->mcoords, data->mcoords_len, screen_co[0], screen_co[1], IS_CLIPPED)); const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside); if (sel_op_result != -1) { - SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT); + mesh_data->select_vert[index] = sel_op_result == 1; data->is_changed = true; } } @@ -1177,6 +1188,7 @@ static bool do_lasso_select_paintvert(ViewContext *vc, const int mcoords_len, const eSelectOp sel_op) { + using namespace blender; const bool use_zbuf = !XRAY_ENABLED(vc->v3d); Object *ob = vc->obact; Mesh *me = static_cast<Mesh *>(ob->data); @@ -1210,16 +1222,22 @@ static bool do_lasso_select_paintvert(ViewContext *vc, } } else { - LassoSelectUserData data; + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>( + ".select_vert", ATTR_DOMAIN_POINT); + + LassoSelectUserData_ForMeshVert data; + data.select_vert = select_vert.span; - view3d_userdata_lassoselect_init(&data, vc, &rect, mcoords, mcoords_len, sel_op); + view3d_userdata_lassoselect_init(&data.lasso_data, vc, &rect, mcoords, mcoords_len, sel_op); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); meshobject_foreachScreenVert( vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - changed |= data.is_changed; + changed |= data.lasso_data.is_changed; + select_vert.finish(); } if (changed) { @@ -2825,20 +2843,22 @@ static bool ed_wpaint_vertex_select_pick(bContext *C, const SelectPick_Params *params, Object *obact) { + using namespace blender; View3D *v3d = CTX_wm_view3d(C); const bool use_zbuf = !XRAY_ENABLED(v3d); Mesh *me = static_cast<Mesh *>(obact->data); /* already checked for nullptr */ uint index = 0; - MVert *verts = BKE_mesh_verts_for_write(me); - - MVert *mv; bool changed = false; bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index); + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::AttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write<bool>( + ".select_vert", ATTR_DOMAIN_POINT); + if (params->sel_op == SEL_OP_SET) { - if ((found && params->select_passthrough) && (verts[index].flag & SELECT)) { + if ((found && params->select_passthrough) && select_vert.varray[index]) { found = false; } else if (found || params->deselect_all) { @@ -2848,23 +2868,22 @@ static bool ed_wpaint_vertex_select_pick(bContext *C, } if (found) { - mv = &verts[index]; switch (params->sel_op) { case SEL_OP_ADD: { - mv->flag |= SELECT; + select_vert.varray.set(index, true); break; } case SEL_OP_SUB: { - mv->flag &= ~SELECT; + select_vert.varray.set(index, false); break; } case SEL_OP_XOR: { - mv->flag ^= SELECT; + select_vert.varray.set(index, !select_vert.varray[index]); break; } case SEL_OP_SET: { paintvert_deselect_all_visible(obact, SEL_DESELECT, false); - mv->flag |= SELECT; + select_vert.varray.set(index, true); break; } case SEL_OP_AND: { @@ -2874,13 +2893,15 @@ static bool ed_wpaint_vertex_select_pick(bContext *C, } /* update mselect */ - if (mv->flag & SELECT) { + if (select_vert.varray[index]) { BKE_mesh_mselect_active_set(me, index, ME_VSEL); } else { BKE_mesh_mselect_validate(me); } + select_vert.finish(); + paintvert_flush_flags(obact); changed = true; @@ -3117,17 +3138,23 @@ bool edge_inside_circle(const float cent[2], return (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < radius_squared); } +struct BoxSelectUserData_ForMeshVert { + BoxSelectUserData box_data; + blender::MutableSpan<bool> select_vert; +}; static void do_paintvert_box_select__doSelectVert(void *userData, - MVert *mv, + MVert * /*mv*/, const float screen_co[2], - int UNUSED(index)) + int index) { - BoxSelectUserData *data = static_cast<BoxSelectUserData *>(userData); - const bool is_select = mv->flag & SELECT; + BoxSelectUserData_ForMeshVert *mesh_data = static_cast<BoxSelectUserData_ForMeshVert *>( + userData); + BoxSelectUserData *data = &mesh_data->box_data; + const bool is_select = mesh_data->select_vert[index]; const bool is_inside = BLI_rctf_isect_pt_v(data->rect_fl, screen_co); const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside); if (sel_op_result != -1) { - SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT); + mesh_data->select_vert[index] = sel_op_result == 1; data->is_changed = true; } } @@ -3136,6 +3163,7 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op) { + using namespace blender; const bool use_zbuf = !XRAY_ENABLED(vc->v3d); Mesh *me = static_cast<Mesh *>(vc->obact->data); @@ -3164,15 +3192,21 @@ static bool do_paintvert_box_select(ViewContext *vc, } } else { - BoxSelectUserData data; + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>( + ".select_vert", ATTR_DOMAIN_POINT); - view3d_userdata_boxselect_init(&data, vc, rect, sel_op); + BoxSelectUserData_ForMeshVert data; + data.select_vert = select_vert.span; + + view3d_userdata_boxselect_init(&data.box_data, vc, rect, sel_op); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); meshobject_foreachScreenVert( vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - changed |= data.is_changed; + changed |= data.box_data.is_changed; + select_vert.finish(); } if (changed) { @@ -4124,15 +4158,21 @@ static bool paint_facesel_circle_select(ViewContext *vc, return changed; } +struct CircleSelectUserData_ForMeshVert { + CircleSelectUserData circle_data; + blender::MutableSpan<bool> select_vert; +}; static void paint_vertsel_circle_select_doSelectVert(void *userData, - MVert *mv, + MVert * /*mv*/, const float screen_co[2], - int UNUSED(index)) + int index) { - CircleSelectUserData *data = static_cast<CircleSelectUserData *>(userData); + CircleSelectUserData_ForMeshVert *mesh_data = static_cast<CircleSelectUserData_ForMeshVert *>( + userData); + CircleSelectUserData *data = &mesh_data->circle_data; if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { - SET_FLAG_FROM_TEST(mv->flag, data->select, SELECT); + mesh_data->select_vert[index] = data->select; data->is_changed = true; } } @@ -4142,6 +4182,7 @@ static bool paint_vertsel_circle_select(ViewContext *vc, const int mval[2], float rad) { + using namespace blender; BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB)); const bool use_zbuf = !XRAY_ENABLED(vc->v3d); Object *ob = vc->obact; @@ -4173,14 +4214,20 @@ static bool paint_vertsel_circle_select(ViewContext *vc, } } else { - CircleSelectUserData data; + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>( + ".select_vert", ATTR_DOMAIN_POINT); + + CircleSelectUserData_ForMeshVert data; + data.select_vert = select_vert.span; ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ - view3d_userdata_circleselect_init(&data, vc, select, mval, rad); + view3d_userdata_circleselect_init(&data.circle_data, vc, select, mval, rad); meshobject_foreachScreenVert( vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - changed |= data.is_changed; + changed |= data.circle_data.is_changed; + select_vert.finish(); } if (changed) { |