From 3184460ff7f4f660a70ec7a18a3a882eb2de57f8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 May 2019 16:29:04 +1000 Subject: 3D View: re-use select id buffer for circle select on cursor-motion The new selection code was redrawing everything for each update. Use the gestures wmGenericUserData to store the cache between executions and ensure it's freed. --- .../blender/editors/space_view3d/view3d_select.c | 288 +++++++++++++-------- 1 file changed, 184 insertions(+), 104 deletions(-) (limited to 'source/blender/editors/space_view3d') diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 414ae392399..b3b4910c525 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -232,6 +232,22 @@ static void editselect_buf_cache_free(struct EditSelectBuf_Cache *esel) MEM_SAFE_FREE(esel->bases); } +static void editselect_buf_cache_free_voidp(void *esel_voidp) +{ + editselect_buf_cache_free(esel_voidp); + MEM_freeN(esel_voidp); +} + +static void editselect_buf_cache_init_with_generic_userdata(wmGenericUserData *wm_userdata, + ViewContext *vc) +{ + struct EditSelectBuf_Cache *esel = MEM_callocN(sizeof(*esel), __func__); + wm_userdata->data = esel; + wm_userdata->free_fn = editselect_buf_cache_free_voidp; + wm_userdata->use_free = true; + editselect_buf_cache_init(esel, vc); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -775,9 +791,9 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, } static bool do_lasso_select_mesh(ViewContext *vc, + wmGenericUserData *wm_userdata, const int mcords[][2], short moves, - struct EditSelectBuf_Cache *esel, const eSelectOp sel_op) { LassoSelectUserData data; @@ -805,10 +821,11 @@ static bool do_lasso_select_mesh(ViewContext *vc, const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d); + struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { - /* Lazy initialize. */ - if (esel->sel_id_ctx == NULL) { - editselect_buf_cache_init(esel, vc); + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + esel = wm_userdata->data; const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); } @@ -1091,11 +1108,11 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, } } static bool do_lasso_select_paintvert(ViewContext *vc, + wmGenericUserData *wm_userdata, const int mcords[][2], short moves, const eSelectOp sel_op) { - struct EditSelectBuf_Cache esel = {NULL}; const bool use_zbuf = !XRAY_ENABLED(vc->v3d); Object *ob = vc->obact; Mesh *me = ob->data; @@ -1113,15 +1130,20 @@ static bool do_lasso_select_paintvert(ViewContext *vc, BLI_lasso_boundbox(&rect, mcords, moves); + struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { - editselect_buf_cache_init(&esel, vc); - - const uint buffer_len = EDBM_select_id_context_elem_len(esel.sel_id_ctx); - esel.select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + esel = wm_userdata->data; + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); + } } if (use_zbuf) { - changed |= edbm_backbuf_check_and_select_verts_obmode(me, &esel, sel_op); + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); + } } else { LassoSelectUserData data; @@ -1136,8 +1158,6 @@ static bool do_lasso_select_paintvert(ViewContext *vc, changed |= data.is_changed; } - editselect_buf_cache_free(&esel); - if (changed) { if (SEL_OP_CAN_DESELECT(sel_op)) { BKE_mesh_mselect_validate(me); @@ -1149,6 +1169,7 @@ static bool do_lasso_select_paintvert(ViewContext *vc, return changed; } static bool do_lasso_select_paintface(ViewContext *vc, + wmGenericUserData *wm_userdata, const int mcords[][2], short moves, const eSelectOp sel_op) @@ -1169,13 +1190,16 @@ static bool do_lasso_select_paintface(ViewContext *vc, BLI_lasso_boundbox(&rect, mcords, moves); - { - struct EditSelectBuf_Cache esel = {NULL}; - editselect_buf_cache_init(&esel, vc); - const uint buffer_len = EDBM_select_id_context_elem_len(esel.sel_id_ctx); - esel.select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); - changed |= edbm_backbuf_check_and_select_faces_obmode(me, &esel, sel_op); - editselect_buf_cache_free(&esel); + struct EditSelectBuf_Cache *esel = wm_userdata->data; + if (esel == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + esel = wm_userdata->data; + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect); + } + + if (esel->select_bitmap) { + changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); } if (changed) { @@ -1224,12 +1248,15 @@ static bool view3d_lasso_select( Object *ob = CTX_data_active_object(C); bool changed_multi = false; + wmGenericUserData wm_userdata_buf = {0}; + wmGenericUserData *wm_userdata = &wm_userdata_buf; + if (vc->obedit == NULL) { /* Object Mode */ if (BKE_paint_select_face_test(ob)) { - changed_multi |= do_lasso_select_paintface(vc, mcords, moves, sel_op); + changed_multi |= do_lasso_select_paintface(vc, wm_userdata, mcords, moves, sel_op); } else if (BKE_paint_select_vert_test(ob)) { - changed_multi |= do_lasso_select_paintvert(vc, mcords, moves, sel_op); + changed_multi |= do_lasso_select_paintvert(vc, wm_userdata, mcords, moves, sel_op); } else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { @@ -1246,17 +1273,13 @@ static bool view3d_lasso_select( } } else { /* Edit Mode */ - - /* TODO(campbell): cache selection buffer between executions. */ - struct EditSelectBuf_Cache esel = {NULL}; - FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, vc->v3d, ob->type, ob->mode, ob_iter) { ED_view3d_viewcontext_init_object(vc, ob_iter); bool changed = false; switch (vc->obedit->type) { case OB_MESH: - changed = do_lasso_select_mesh(vc, mcords, moves, &esel, sel_op); + changed = do_lasso_select_mesh(vc, wm_userdata, mcords, moves, sel_op); break; case OB_CURVE: case OB_SURF: @@ -1283,9 +1306,10 @@ static bool view3d_lasso_select( } } FOREACH_OBJECT_IN_MODE_END; - - editselect_buf_cache_free(&esel); } + + WM_generic_user_data_free(wm_userdata); + return changed_multi; } @@ -2467,7 +2491,10 @@ static void do_paintvert_box_select__doSelectVert(void *userData, data->is_changed = true; } } -static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op) +static bool do_paintvert_box_select(ViewContext *vc, + wmGenericUserData *wm_userdata, + const rcti *rect, + const eSelectOp sel_op) { const bool use_zbuf = !XRAY_ENABLED(vc->v3d); @@ -2487,12 +2514,16 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSe /* pass */ } else if (use_zbuf) { - struct EditSelectBuf_Cache esel = {NULL}; - editselect_buf_cache_init(&esel, vc); - const uint buffer_len = EDBM_select_id_context_elem_len(esel.sel_id_ctx); - esel.select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); - changed |= edbm_backbuf_check_and_select_verts_obmode(me, &esel, sel_op); - editselect_buf_cache_free(&esel); + struct EditSelectBuf_Cache *esel = wm_userdata->data; + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + esel = wm_userdata->data; + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); + } + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); + } } else { BoxSelectUserData data; @@ -2516,7 +2547,10 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSe return changed; } -static bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op) +static bool do_paintface_box_select(ViewContext *vc, + wmGenericUserData *wm_userdata, + const rcti *rect, + int sel_op) { Object *ob = vc->obact; Mesh *me; @@ -2535,12 +2569,16 @@ static bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_o /* pass */ } else { - struct EditSelectBuf_Cache esel = {NULL}; - editselect_buf_cache_init(&esel, vc); - const uint buffer_len = EDBM_select_id_context_elem_len(esel.sel_id_ctx); - esel.select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); - changed |= edbm_backbuf_check_and_select_faces_obmode(me, &esel, sel_op); - editselect_buf_cache_free(&esel); + struct EditSelectBuf_Cache *esel = wm_userdata->data; + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + esel = wm_userdata->data; + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); + } + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); + } } if (changed) { @@ -2705,8 +2743,8 @@ static void do_mesh_box_select__doSelectFace(void *userData, } } static bool do_mesh_box_select(ViewContext *vc, + wmGenericUserData *wm_userdata, const rcti *rect, - struct EditSelectBuf_Cache *esel, const eSelectOp sel_op) { BoxSelectUserData data; @@ -2726,12 +2764,13 @@ static bool do_mesh_box_select(ViewContext *vc, GPU_matrix_set(vc->rv3d->viewmat); - const int use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d); + const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d); + struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { - /* Lazy initialize. */ - if (esel->sel_id_ctx == NULL) { - editselect_buf_cache_init(esel, vc); + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + esel = wm_userdata->data; const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect); } @@ -3091,6 +3130,9 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) rcti rect; bool changed_multi = false; + wmGenericUserData wm_userdata_buf = {0}; + wmGenericUserData *wm_userdata = &wm_userdata_buf; + view3d_operator_needs_opengl(C); BKE_object_update_select_id(CTX_data_main(C)); @@ -3101,9 +3143,6 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) WM_operator_properties_border_to_rcti(op, &rect); if (vc.obedit) { - - struct EditSelectBuf_Cache esel = {NULL}; - FOREACH_OBJECT_IN_MODE_BEGIN ( vc.view_layer, vc.v3d, vc.obedit->type, vc.obedit->mode, ob_iter) { ED_view3d_viewcontext_init_object(&vc, ob_iter); @@ -3112,7 +3151,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) switch (vc.obedit->type) { case OB_MESH: vc.em = BKE_editmesh_from_object(vc.obedit); - changed = do_mesh_box_select(&vc, &rect, &esel, sel_op); + changed = do_mesh_box_select(&vc, wm_userdata, &rect, sel_op); if (changed) { DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); @@ -3154,8 +3193,6 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) changed_multi |= changed; } FOREACH_OBJECT_IN_MODE_END; - - editselect_buf_cache_free(&esel); } else { /* no editmode, unified for bones and objects */ if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) { @@ -3164,10 +3201,10 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false); } else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { - changed_multi = do_paintface_box_select(&vc, &rect, sel_op); + changed_multi = do_paintface_box_select(&vc, wm_userdata, &rect, sel_op); } else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { - changed_multi = do_paintvert_box_select(&vc, &rect, sel_op); + changed_multi = do_paintvert_box_select(&vc, wm_userdata, &rect, sel_op); } else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { changed_multi = PE_box_select(C, &rect, sel_op); @@ -3180,6 +3217,8 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op) } } + WM_generic_user_data_free(wm_userdata); + if (changed_multi) { return OPERATOR_FINISHED; } @@ -3286,7 +3325,7 @@ static void mesh_circle_doSelectFace(void *userData, } static bool mesh_circle_select(ViewContext *vc, - struct EditSelectBuf_Cache *esel, + wmGenericUserData *wm_userdata, eSelectOp sel_op, const int mval[2], float rad) @@ -3308,22 +3347,26 @@ static bool mesh_circle_select(ViewContext *vc, view3d_userdata_circleselect_init(&data, vc, select, mval, rad); - const int use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d); + const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d); if (use_zbuf) { - /* Lazy initialize. */ - if (esel->sel_id_ctx == NULL) { - editselect_buf_cache_init(esel, vc); - const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); - esel->select_bitmap = ED_select_buffer_bitmap_from_circle( - buffer_len, mval, (int)(rad + 1.0f)); + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); } } + struct EditSelectBuf_Cache *esel = wm_userdata->data; + + if (use_zbuf) { + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); + } if (ts->selectmode & SCE_SELECT_VERTEX) { if (use_zbuf) { - changed |= edbm_backbuf_check_and_select_verts( - esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_verts( + esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + } } else { mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); @@ -3332,8 +3375,10 @@ static bool mesh_circle_select(ViewContext *vc, if (ts->selectmode & SCE_SELECT_EDGE) { if (use_zbuf) { - changed |= edbm_backbuf_check_and_select_edges( - esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_edges( + esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + } } else { mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR); @@ -3342,14 +3387,23 @@ static bool mesh_circle_select(ViewContext *vc, if (ts->selectmode & SCE_SELECT_FACE) { if (use_zbuf) { - changed |= edbm_backbuf_check_and_select_faces( - esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_faces( + esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB); + } } else { mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } + if (use_zbuf) { + if (esel->select_bitmap != NULL) { + MEM_freeN(esel->select_bitmap); + esel->select_bitmap = NULL; + } + } + changed |= data.is_changed; if (changed) { @@ -3359,6 +3413,7 @@ static bool mesh_circle_select(ViewContext *vc, } static bool paint_facesel_circle_select(ViewContext *vc, + wmGenericUserData *wm_userdata, const eSelectOp sel_op, const int mval[2], float rad) @@ -3373,14 +3428,19 @@ static bool paint_facesel_circle_select(ViewContext *vc, changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false); } + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + } + { - /* TODO(campbell): cache selection buffer between executions. */ - struct EditSelectBuf_Cache esel = {NULL}; - editselect_buf_cache_init(&esel, vc); - const uint buffer_len = EDBM_select_id_context_elem_len(esel.sel_id_ctx); - esel.select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); - changed |= edbm_backbuf_check_and_select_faces_obmode(me, &esel, sel_op); - editselect_buf_cache_free(&esel); + struct EditSelectBuf_Cache *esel = wm_userdata->data; + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); + MEM_freeN(esel->select_bitmap); + esel->select_bitmap = NULL; + } } if (changed) { @@ -3402,12 +3462,12 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, } } static bool paint_vertsel_circle_select(ViewContext *vc, + wmGenericUserData *wm_userdata, const eSelectOp sel_op, const int mval[2], float rad) { BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB)); - struct EditSelectBuf_Cache esel = {NULL}; const bool use_zbuf = !XRAY_ENABLED(vc->v3d); Object *ob = vc->obact; Mesh *me = ob->data; @@ -3422,15 +3482,20 @@ static bool paint_vertsel_circle_select(ViewContext *vc, const bool select = (sel_op != SEL_OP_SUB); if (use_zbuf) { - /* TODO(campbell): cache selection buffer between executions. */ - editselect_buf_cache_init(&esel, vc); - - const uint buffer_len = EDBM_select_id_context_elem_len(esel.sel_id_ctx); - esel.select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); + if (wm_userdata->data == NULL) { + editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc); + } } if (use_zbuf) { - changed |= edbm_backbuf_check_and_select_verts_obmode(me, &esel, sel_op); + struct EditSelectBuf_Cache *esel = wm_userdata->data; + const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx); + esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f)); + if (esel->select_bitmap != NULL) { + changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); + MEM_freeN(esel->select_bitmap); + esel->select_bitmap = NULL; + } } else { CircleSelectUserData data; @@ -3443,8 +3508,6 @@ static bool paint_vertsel_circle_select(ViewContext *vc, changed |= data.is_changed; } - editselect_buf_cache_free(&esel); - if (changed) { if (sel_op == SEL_OP_SUB) { BKE_mesh_mselect_validate(me); @@ -3779,28 +3842,40 @@ static bool mball_circle_select(ViewContext *vc, /** Callbacks for circle selection in Editmode */ static bool obedit_circle_select(ViewContext *vc, - struct EditSelectBuf_Cache *esel, + wmGenericUserData *wm_userdata, const eSelectOp sel_op, const int mval[2], float rad) { + bool changed = false; BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB)); switch (vc->obedit->type) { case OB_MESH: - return mesh_circle_select(vc, esel, sel_op, mval, rad); + changed = mesh_circle_select(vc, wm_userdata, sel_op, mval, rad); + break; case OB_CURVE: case OB_SURF: - return nurbscurve_circle_select(vc, sel_op, mval, rad); + changed = nurbscurve_circle_select(vc, sel_op, mval, rad); + break; case OB_LATTICE: - return lattice_circle_select(vc, sel_op, mval, rad); + changed = lattice_circle_select(vc, sel_op, mval, rad); + break; case OB_ARMATURE: - return armature_circle_select(vc, sel_op, mval, rad); + changed = armature_circle_select(vc, sel_op, mval, rad); + break; case OB_MBALL: - return mball_circle_select(vc, sel_op, mval, rad); + changed = mball_circle_select(vc, sel_op, mval, rad); + break; default: BLI_assert(0); - return false; + break; } + + if (changed) { + DEG_id_tag_update(vc->obact->data, ID_RECALC_SELECT); + WM_main_add_notifier(NC_GEOM | ND_SELECT, vc->obact->data); + } + return changed; } static bool object_circle_select(ViewContext *vc, @@ -3849,8 +3924,13 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) const int radius = RNA_int_get(op->ptr, "radius"); const int mval[2] = {RNA_int_get(op->ptr, "x"), RNA_int_get(op->ptr, "y")}; + /* Allow each selection type to allocate their own data thats used between executions. */ + wmGesture *gesture = op->customdata; /* NULL when non-modal. */ + wmGenericUserData wm_userdata_buf = {0}; + wmGenericUserData *wm_userdata = gesture ? &gesture->user_data : &wm_userdata_buf; + const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"), - WM_gesture_is_modal_first(op->customdata)); + WM_gesture_is_modal_first(gesture)); ED_view3d_viewcontext_init(C, &vc); @@ -3859,9 +3939,9 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) if (obedit || BKE_paint_select_elem_test(obact) || (obact && (obact->mode & OB_MODE_POSE))) { view3d_operator_needs_opengl(C); - BKE_object_update_select_id(CTX_data_main(C)); - - struct EditSelectBuf_Cache esel = {NULL}; + if (obedit == NULL) { + BKE_object_update_select_id(CTX_data_main(C)); + } FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) { ED_view3d_viewcontext_init_object(&vc, ob_iter); @@ -3870,16 +3950,13 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) obedit = vc.obedit; if (obedit) { - if (obedit_circle_select(&vc, &esel, sel_op, mval, (float)radius)) { - DEG_id_tag_update(obact->data, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); - } + obedit_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius); } else if (BKE_paint_select_face_test(obact)) { - paint_facesel_circle_select(&vc, sel_op, mval, (float)radius); + paint_facesel_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius); } else if (BKE_paint_select_vert_test(obact)) { - paint_vertsel_circle_select(&vc, sel_op, mval, (float)radius); + paint_vertsel_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius); } else if (obact->mode & OB_MODE_POSE) { pose_circle_select(&vc, sel_op, mval, (float)radius); @@ -3889,8 +3966,6 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) } } FOREACH_OBJECT_IN_MODE_END; - - editselect_buf_cache_free(&esel); } else if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) { if (PE_circle_select(C, sel_op, mval, (float)radius)) { @@ -3908,6 +3983,11 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) } } + /* Otherwise this is freed by the gesture. */ + if (wm_userdata == &wm_userdata_buf) { + WM_generic_user_data_free(wm_userdata); + } + return OPERATOR_FINISHED; } -- cgit v1.2.3