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.
This commit is contained in:
Campbell Barton 2019-05-20 16:29:04 +10:00
parent c09f461e04
commit 3184460ff7
1 changed files with 184 additions and 104 deletions

View File

@ -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;
}