Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_select.c
| Show First 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | void ED_view3d_viewcontext_init(bContext *C, ViewContext *vc) | ||||
| vc->engine_type = CTX_data_engine_type(C); | vc->engine_type = CTX_data_engine_type(C); | ||||
| vc->v3d = CTX_wm_view3d(C); | vc->v3d = CTX_wm_view3d(C); | ||||
| vc->win = CTX_wm_window(C); | vc->win = CTX_wm_window(C); | ||||
| vc->rv3d = CTX_wm_region_view3d(C); | vc->rv3d = CTX_wm_region_view3d(C); | ||||
| vc->obact = CTX_data_active_object(C); | vc->obact = CTX_data_active_object(C); | ||||
| vc->obedit = CTX_data_edit_object(C); | vc->obedit = CTX_data_edit_object(C); | ||||
| } | } | ||||
| void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact) | |||||
| { | |||||
| vc->obact = obact; | |||||
| if (vc->obedit) { | |||||
| BLI_assert(BKE_object_is_in_editmode(obact)); | |||||
| vc->obedit = obact; | |||||
| /* previous selections are now invalid. */ | |||||
| vc->v3d->flag |= V3D_INVALID_BACKBUF; | |||||
| if (vc->em) { | |||||
| vc->em = BKE_editmesh_from_object(vc->obedit); | |||||
| } | |||||
| } | |||||
| } | |||||
| /* ********************** view3d_select: selection manipulations ********************* */ | /* ********************** view3d_select: selection manipulations ********************* */ | ||||
| /* local prototypes */ | /* local prototypes */ | ||||
| static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, const bool select) | static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, const bool select) | ||||
| { | { | ||||
| BMVert *eve; | BMVert *eve; | ||||
| BMIter iter; | BMIter iter; | ||||
| ▲ Show 20 Lines • Show All 256 Lines • ▼ Show 20 Lines | for (base = view_layer->object_bases.first; base; base = base->next) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void do_lasso_select_objects( | static void do_lasso_select_objects( | ||||
| ViewContext *vc, const int mcords[][2], const short moves, | ViewContext *vc, const int mcords[][2], const short moves, | ||||
| const bool extend, const bool select) | const bool extend, const bool select) | ||||
| { | { | ||||
| bool is_pose_mode = vc->obact ? (vc->obact->mode & OB_MODE_POSE) : false; | |||||
| Base *base; | Base *base; | ||||
| if (extend == false && select) | if (extend == false && select) | ||||
| object_deselect_all_visible(vc->view_layer); | object_deselect_all_visible(vc->view_layer); | ||||
| for (base = vc->view_layer->object_bases.first; base; base = base->next) { | for (base = vc->view_layer->object_bases.first; base; base = base->next) { | ||||
| if (BASE_SELECTABLE(base)) { /* use this to avoid un-needed lasso lookups */ | if (BASE_SELECTABLE(base)) { /* use this to avoid un-needed lasso lookups */ | ||||
| if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) { | if (ED_view3d_project_base(vc->ar, base) == V3D_PROJ_RET_OK) { | ||||
| if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) { | if (BLI_lasso_is_point_inside(mcords, moves, base->sx, base->sy, IS_CLIPPED)) { | ||||
| ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT); | ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT); | ||||
| } | } | ||||
| } | } | ||||
| if (vc->obact == base->object && (base->object->mode & OB_MODE_POSE)) { | if (is_pose_mode && | ||||
| ((vc->obact == base->object) || (base->flag & BASE_SELECTED)) && | |||||
| (base->object->mode & OB_MODE_POSE)) | |||||
| { | |||||
| do_lasso_select_pose(vc, base->object, mcords, moves, select); | do_lasso_select_pose(vc, base->object, mcords, moves, select); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) | static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 410 Lines • ▼ Show 20 Lines | else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { | ||||
| PE_lasso_select(C, mcords, moves, extend, select); | PE_lasso_select(C, mcords, moves, extend, select); | ||||
| } | } | ||||
| else { | else { | ||||
| do_lasso_select_objects(vc, mcords, moves, extend, select); | do_lasso_select_objects(vc, mcords, moves, extend, select); | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); | WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); | ||||
| } | } | ||||
| } | } | ||||
| else { /* Edit Mode */ | else { /* Edit Mode */ | ||||
| /* don't indent to avoid diff noise! */ | |||||
| FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, ob->mode, ob_iter) { | |||||
| ED_view3d_viewcontext_init_object(vc, ob_iter); | |||||
| /* --- */ | |||||
| switch (vc->obedit->type) { | switch (vc->obedit->type) { | ||||
| case OB_MESH: | case OB_MESH: | ||||
| do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select); | do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select); | ||||
| break; | break; | ||||
| case OB_CURVE: | case OB_CURVE: | ||||
| case OB_SURF: | case OB_SURF: | ||||
| do_lasso_select_curve(vc, mcords, moves, extend, select); | do_lasso_select_curve(vc, mcords, moves, extend, select); | ||||
| break; | break; | ||||
| case OB_LATTICE: | case OB_LATTICE: | ||||
| do_lasso_select_lattice(vc, mcords, moves, extend, select); | do_lasso_select_lattice(vc, mcords, moves, extend, select); | ||||
| break; | break; | ||||
| case OB_ARMATURE: | case OB_ARMATURE: | ||||
| do_lasso_select_armature(vc, mcords, moves, extend, select); | do_lasso_select_armature(vc, mcords, moves, extend, select); | ||||
| break; | break; | ||||
| case OB_MBALL: | case OB_MBALL: | ||||
| do_lasso_select_meta(vc, mcords, moves, extend, select); | do_lasso_select_meta(vc, mcords, moves, extend, select); | ||||
| break; | break; | ||||
| default: | default: | ||||
| assert(!"lasso select on incorrect object type"); | assert(!"lasso select on incorrect object type"); | ||||
| break; | break; | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data); | ||||
| } FOREACH_OBJECT_IN_MODE_END; | |||||
| } | } | ||||
| } | } | ||||
| /* lasso operator gives properties, but since old code works | /* lasso operator gives properties, but since old code works | ||||
| * with short array we convert */ | * with short array we convert */ | ||||
| static int view3d_lasso_select_exec(bContext *C, wmOperator *op) | static int view3d_lasso_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 508 Lines • ▼ Show 20 Lines | static bool ed_object_select_pick( | ||||
| CTX_data_eval_ctx(C, &eval_ctx); | CTX_data_eval_ctx(C, &eval_ctx); | ||||
| ED_view3d_viewcontext_init(C, &vc); | ED_view3d_viewcontext_init(C, &vc); | ||||
| is_obedit = (vc.obedit != NULL); | is_obedit = (vc.obedit != NULL); | ||||
| if (object) { | if (object) { | ||||
| /* signal for view3d_opengl_select to skip editmode objects */ | /* signal for view3d_opengl_select to skip editmode objects */ | ||||
| vc.obedit = NULL; | vc.obedit = NULL; | ||||
| } | } | ||||
| /* In pose mode we don't want to mess with object selection. */ | |||||
| const bool is_pose_mode = (vc.obact && vc.obact->mode & OB_MODE_POSE); | |||||
| /* always start list from basact in wire mode */ | /* always start list from basact in wire mode */ | ||||
| startbase = FIRSTBASE(view_layer); | startbase = FIRSTBASE(view_layer); | ||||
| if (BASACT(view_layer) && BASACT(view_layer)->next) startbase = BASACT(view_layer)->next; | if (BASACT(view_layer) && BASACT(view_layer)->next) startbase = BASACT(view_layer)->next; | ||||
| /* This block uses the control key to make the object selected by its center point rather than its contents */ | /* This block uses the control key to make the object selected by its center point rather than its contents */ | ||||
| /* in editmode do not activate */ | /* in editmode do not activate */ | ||||
| if (obcenter) { | if (obcenter) { | ||||
| ▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | if (hits > 0) { | ||||
| } | } | ||||
| /* prevent bone selecting to pass on to object selecting */ | /* prevent bone selecting to pass on to object selecting */ | ||||
| if (basact == BASACT(view_layer)) | if (basact == BASACT(view_layer)) | ||||
| basact = NULL; | basact = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* so, do we have something selected? */ | /* so, do we have something selected? */ | ||||
| if (basact) { | if (basact) { | ||||
| retval = true; | retval = true; | ||||
| if (vc.obedit) { | if (vc.obedit) { | ||||
| /* only do select */ | /* only do select */ | ||||
| deselectall_except(view_layer, basact); | deselectall_except(view_layer, basact); | ||||
| ED_object_base_select(basact, BA_SELECT); | ED_object_base_select(basact, BA_SELECT); | ||||
| Show All 15 Lines | else if (BASE_SELECTABLE(basact)) { | ||||
| ED_object_base_select(basact, BA_DESELECT); | ED_object_base_select(basact, BA_DESELECT); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| ED_object_base_select(basact, BA_SELECT); | ED_object_base_select(basact, BA_SELECT); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* When enabled, this puts other objects out of multi pose-mode. */ | |||||
| if (is_pose_mode == false) { | |||||
| deselectall_except(view_layer, basact); | deselectall_except(view_layer, basact); | ||||
| ED_object_base_select(basact, BA_SELECT); | ED_object_base_select(basact, BA_SELECT); | ||||
| } | } | ||||
| } | |||||
| if ((oldbasact != basact) && (is_obedit == false)) { | if ((oldbasact != basact) && (is_obedit == false)) { | ||||
| ED_object_base_activate(C, basact); /* adds notifier */ | ED_object_base_activate(C, basact); /* adds notifier */ | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); | WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 423 Lines • ▼ Show 20 Lines | else { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||
| static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) | static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend) | ||||
| { | { | ||||
| EvaluationContext eval_ctx; | EvaluationContext eval_ctx; | ||||
| Bone *bone; | Bone *bone; | ||||
| Object *ob = vc->obact; | |||||
| unsigned int *vbuffer = NULL; /* selection buffer */ | unsigned int *vbuffer = NULL; /* selection buffer */ | ||||
| unsigned int *col; /* color in buffer */ | unsigned int *col; /* color in buffer */ | ||||
| int bone_only; | int bone_only; | ||||
| int bone_selected = 0; | int bone_selected = 0; | ||||
| int totobj = MAXPICKBUF; /* XXX solve later */ | int totobj = MAXPICKBUF; /* XXX solve later */ | ||||
| int hits; | int hits; | ||||
| CTX_data_eval_ctx(C, &eval_ctx); | CTX_data_eval_ctx(C, &eval_ctx); | ||||
| if ((ob) && (ob->mode & OB_MODE_POSE)) | if (vc->obact && (vc->obact->mode & OB_MODE_POSE)) | ||||
| bone_only = 1; | bone_only = 1; | ||||
| else | else | ||||
| bone_only = 0; | bone_only = 0; | ||||
| if (extend == false && select) { | if (extend == false && select) { | ||||
| if (bone_only) { | if (bone_only) { | ||||
| CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) | FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, OB_MODE_POSE, ob_iter) { | ||||
| { | bArmature *arm = ob_iter->data; | ||||
| for (bPoseChannel *pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) { | |||||
| if (PBONE_VISIBLE(arm, pchan->bone)) { | |||||
| if ((select == false) || ((pchan->bone->flag & BONE_UNSELECTABLE) == 0)) { | if ((select == false) || ((pchan->bone->flag & BONE_UNSELECTABLE) == 0)) { | ||||
| pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); | pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); | ||||
| } | } | ||||
| } | } | ||||
| CTX_DATA_END; | } | ||||
| } FOREACH_OBJECT_IN_MODE_END; | |||||
| } | } | ||||
| else { | else { | ||||
| object_deselect_all_visible(vc->view_layer); | object_deselect_all_visible(vc->view_layer); | ||||
| } | } | ||||
| } | } | ||||
| /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ | /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ | ||||
| vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer"); | vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer"); | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | for (base = vc->view_layer->object_bases.first; base && hits; base = base->next) { | ||||
| if (bone_selected) { | if (bone_selected) { | ||||
| if (base->object && (base->object->type == OB_ARMATURE)) { | if (base->object && (base->object->type == OB_ARMATURE)) { | ||||
| bArmature *arm = base->object->data; | bArmature *arm = base->object->data; | ||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object); | WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object); | ||||
| if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { | if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { | ||||
| /* mask modifier ('armature' mode), etc. */ | /* mask modifier ('armature' mode), etc. */ | ||||
| DEG_id_tag_update(&ob->id, OB_RECALC_DATA); | DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); | WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); | ||||
| } | } | ||||
| MEM_freeN(vbuffer); | MEM_freeN(vbuffer); | ||||
| Show All 17 Lines | static int view3d_borderselect_exec(bContext *C, wmOperator *op) | ||||
| CTX_data_eval_ctx(C, &eval_ctx); | CTX_data_eval_ctx(C, &eval_ctx); | ||||
| ED_view3d_viewcontext_init(C, &vc); | ED_view3d_viewcontext_init(C, &vc); | ||||
| select = !RNA_boolean_get(op->ptr, "deselect"); | select = !RNA_boolean_get(op->ptr, "deselect"); | ||||
| extend = RNA_boolean_get(op->ptr, "extend"); | extend = RNA_boolean_get(op->ptr, "extend"); | ||||
| WM_operator_properties_border_to_rcti(op, &rect); | WM_operator_properties_border_to_rcti(op, &rect); | ||||
| if (vc.obedit) { | if (vc.obedit) { | ||||
| /* don't indent to avoid diff noise! */ | |||||
| FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, vc.obedit->mode, ob_iter) { | |||||
| ED_view3d_viewcontext_init_object(&vc, ob_iter); | |||||
| /* --- */ | |||||
| switch (vc.obedit->type) { | switch (vc.obedit->type) { | ||||
| case OB_MESH: | case OB_MESH: | ||||
| vc.em = BKE_editmesh_from_object(vc.obedit); | vc.em = BKE_editmesh_from_object(vc.obedit); | ||||
| ret = do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend); | ret |= do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend); | ||||
| // if (EM_texFaceCheck()) | |||||
| if (ret & OPERATOR_FINISHED) { | if (ret & OPERATOR_FINISHED) { | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | ||||
| } | } | ||||
| break; | break; | ||||
| case OB_CURVE: | case OB_CURVE: | ||||
| case OB_SURF: | case OB_SURF: | ||||
| ret = do_nurbs_box_select(&vc, &rect, select, extend); | ret |= do_nurbs_box_select(&vc, &rect, select, extend); | ||||
| if (ret & OPERATOR_FINISHED) { | if (ret & OPERATOR_FINISHED) { | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | ||||
| } | } | ||||
| break; | break; | ||||
| case OB_MBALL: | case OB_MBALL: | ||||
| ret = do_meta_box_select(&eval_ctx, &vc, &rect, select, extend); | ret |= do_meta_box_select(&eval_ctx, &vc, &rect, select, extend); | ||||
| if (ret & OPERATOR_FINISHED) { | if (ret & OPERATOR_FINISHED) { | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | ||||
| } | } | ||||
| break; | break; | ||||
| case OB_ARMATURE: | case OB_ARMATURE: | ||||
| ret = do_armature_box_select(&eval_ctx, &vc, &rect, select, extend); | ret |= do_armature_box_select(&eval_ctx, &vc, &rect, select, extend); | ||||
| if (ret & OPERATOR_FINISHED) { | if (ret & OPERATOR_FINISHED) { | ||||
| WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit); | WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit); | ||||
| } | } | ||||
| break; | break; | ||||
| case OB_LATTICE: | case OB_LATTICE: | ||||
| ret = do_lattice_box_select(&vc, &rect, select, extend); | ret |= do_lattice_box_select(&vc, &rect, select, extend); | ||||
| if (ret & OPERATOR_FINISHED) { | if (ret & OPERATOR_FINISHED) { | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data); | ||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| assert(!"border select on incorrect object type"); | assert(!"border select on incorrect object type"); | ||||
| break; | break; | ||||
| } | }} FOREACH_OBJECT_IN_MODE_END; | ||||
| } | } | ||||
| else { /* no editmode, unified for bones and objects */ | else { /* no editmode, unified for bones and objects */ | ||||
| if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) { | if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) { | ||||
| ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend); | ret |= ED_sculpt_mask_box_select(C, &vc, &rect, select, extend); | ||||
| } | } | ||||
| else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { | else if (vc.obact && BKE_paint_select_face_test(vc.obact)) { | ||||
| ret = do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend); | ret |= do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend); | ||||
| } | } | ||||
| else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { | else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) { | ||||
| ret = do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend); | ret |= do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend); | ||||
| } | } | ||||
| else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { | else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { | ||||
| ret = PE_border_select(C, &rect, select, extend); | ret |= PE_border_select(C, &rect, select, extend); | ||||
| } | } | ||||
| else { /* object mode with none active */ | else { /* object mode with none active */ | ||||
| ret = do_object_pose_box_select(C, &vc, &rect, select, extend); | ret |= do_object_pose_box_select(C, &vc, &rect, select, extend); | ||||
| } | } | ||||
| } | } | ||||
| if (ret & OPERATOR_FINISHED) { | |||||
| ret = OPERATOR_FINISHED; | |||||
| } | |||||
| else { | |||||
| ret = OPERATOR_CANCELLED; | |||||
| } | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| /* *****************Selection Operators******************* */ | /* *****************Selection Operators******************* */ | ||||
| /* ****** Border Select ****** */ | /* ****** Border Select ****** */ | ||||
| void VIEW3D_OT_select_border(wmOperatorType *ot) | void VIEW3D_OT_select_border(wmOperatorType *ot) | ||||
| ▲ Show 20 Lines • Show All 624 Lines • ▼ Show 20 Lines | static bool object_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) | ||||
| } | } | ||||
| return changed; | return changed; | ||||
| } | } | ||||
| /* not a real operator, only for circle test */ | /* not a real operator, only for circle test */ | ||||
| static int view3d_circle_select_exec(bContext *C, wmOperator *op) | static int view3d_circle_select_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | ViewContext vc; | ||||
| Object *obact = CTX_data_active_object(C); | EvaluationContext eval_ctx; | ||||
| CTX_data_eval_ctx(C, &eval_ctx); | |||||
| const int radius = RNA_int_get(op->ptr, "radius"); | const int radius = RNA_int_get(op->ptr, "radius"); | ||||
| const bool select = !RNA_boolean_get(op->ptr, "deselect"); | const bool select = !RNA_boolean_get(op->ptr, "deselect"); | ||||
| const int mval[2] = {RNA_int_get(op->ptr, "x"), | const int mval[2] = {RNA_int_get(op->ptr, "x"), | ||||
| RNA_int_get(op->ptr, "y")}; | RNA_int_get(op->ptr, "y")}; | ||||
| if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) || | |||||
| ED_view3d_viewcontext_init(C, &vc); | |||||
| Object *obact = vc.obact; | |||||
| Object *obedit = vc.obedit; | |||||
| if (obedit || BKE_paint_select_elem_test(obact) || | |||||
| (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) | (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) | ||||
| { | { | ||||
| EvaluationContext eval_ctx; | |||||
| ViewContext vc; | |||||
| view3d_operator_needs_opengl(C); | view3d_operator_needs_opengl(C); | ||||
| CTX_data_eval_ctx(C, &eval_ctx); | /* don't indent to avoid diff noise! */ | ||||
| ED_view3d_viewcontext_init(C, &vc); | FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, obact->mode, ob_iter) { | ||||
| ED_view3d_viewcontext_init_object(&vc, ob_iter); | |||||
| /* --- */ | |||||
| obact = vc.obact; | |||||
| obedit = vc.obedit; | |||||
| if (CTX_data_edit_object(C)) { | if (CTX_data_edit_object(C)) { | ||||
| obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius); | obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); | ||||
| } | } | ||||
| else if (BKE_paint_select_face_test(obact)) { | else if (BKE_paint_select_face_test(obact)) { | ||||
| paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); | paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); | ||||
| } | } | ||||
| else if (BKE_paint_select_vert_test(obact)) { | else if (BKE_paint_select_vert_test(obact)) { | ||||
| paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); | paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); | ||||
| WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); | WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); | ||||
| } | } | ||||
| else if (obact->mode & OB_MODE_POSE) | else if (obact->mode & OB_MODE_POSE) | ||||
| pose_circle_select(&vc, select, mval, (float)radius); | pose_circle_select(&vc, select, mval, (float)radius); | ||||
| else | else | ||||
| return PE_circle_select(C, select, mval, (float)radius); | return PE_circle_select(C, select, mval, (float)radius); | ||||
| } FOREACH_OBJECT_IN_MODE_END; | |||||
| } | } | ||||
| else if (obact && obact->mode & OB_MODE_SCULPT) { | else if (obact && obact->mode & OB_MODE_SCULPT) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| else { | else { | ||||
| ViewContext vc; | |||||
| ED_view3d_viewcontext_init(C, &vc); | |||||
| if (object_circle_select(&vc, select, mval, (float)radius)) { | if (object_circle_select(&vc, select, mval, (float)radius)) { | ||||
| WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); | WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc.scene); | ||||
| } | } | ||||
| } | } | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void VIEW3D_OT_select_circle(wmOperatorType *ot) | void VIEW3D_OT_select_circle(wmOperatorType *ot) | ||||
| { | { | ||||
| Show All 16 Lines | |||||