Blender V5.0
object_select.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cctype>
10#include <cstdlib>
11#include <cstring>
12
13#include "MEM_guardedalloc.h"
14
15#include "DNA_anim_types.h"
16#include "DNA_armature_types.h"
18#include "DNA_light_types.h"
19#include "DNA_modifier_types.h"
20#include "DNA_scene_types.h"
21
22#include "BLI_listbase.h"
23#include "BLI_math_vector.h"
24#include "BLI_rand.h"
25#include "BLI_string_utils.hh"
26#include "BLI_utildefines.h"
27
28#include "BLT_translation.hh"
29
30#include "BKE_action.hh"
31#include "BKE_armature.hh"
32#include "BKE_collection.hh"
33#include "BKE_context.hh"
34#include "BKE_layer.hh"
35#include "BKE_lib_id.hh"
36#include "BKE_main.hh"
37#include "BKE_material.hh"
38#include "BKE_particle.h"
39#include "BKE_report.hh"
40#include "BKE_scene.hh"
41
42#include "DEG_depsgraph.hh"
43
44#include "WM_api.hh"
45#include "WM_message.hh"
46#include "WM_types.hh"
47
48#include "ED_armature.hh"
49#include "ED_keyframing.hh"
50#include "ED_object.hh"
51#include "ED_outliner.hh"
52#include "ED_screen.hh"
53#include "ED_select_utils.hh"
54
55#include "ANIM_armature.hh"
57#include "ANIM_keyingsets.hh"
58
59#include "UI_interface.hh"
61#include "UI_resources.hh"
62
63#include "RNA_access.hh"
64#include "RNA_define.hh"
65#include "RNA_enum_types.hh"
66
67#include "object_intern.hh"
68
69namespace blender::ed::object {
70
71/* -------------------------------------------------------------------- */
74
76{
77 if (mode == BA_INVERT) {
78 mode = (base->flag & BASE_SELECTED) != 0 ? BA_DESELECT : BA_SELECT;
79 }
80
81 if (base) {
82 switch (mode) {
83 case BA_SELECT:
84 if ((base->flag & BASE_SELECTABLE) != 0) {
85 base->flag |= BASE_SELECTED;
86 }
87 break;
88 case BA_DESELECT:
89 base->flag &= ~BASE_SELECTED;
90 break;
91 case BA_INVERT:
92 /* Never happens. */
93 break;
94 }
96 }
97}
98
99void base_active_refresh(Main *bmain, Scene *scene, ViewLayer *view_layer)
100{
103 wmMsgBus *mbus = ((wmWindowManager *)bmain->wm.first)->runtime->message_bus;
104 if (mbus != nullptr) {
105 WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
106 }
107}
108
110{
111 Scene *scene = CTX_data_scene(C);
112 ViewLayer *view_layer = CTX_data_view_layer(C);
113 view_layer->basact = base;
114 base_active_refresh(CTX_data_main(C), scene, view_layer);
115}
116
118{
119 Scene *scene = CTX_data_scene(C);
120 ViewLayer *view_layer = CTX_data_view_layer(C);
121
122 /* Currently we only need to be concerned with edit-mode. */
123 BKE_view_layer_synced_ensure(scene, view_layer);
124 Object *obedit = BKE_view_layer_edit_object_get(view_layer);
125 if (obedit) {
126 Object *ob = base->object;
127 if (((ob->mode & OB_MODE_EDIT) == 0) || (obedit->type != ob->type)) {
128 Main *bmain = CTX_data_main(C);
129 editmode_exit_multi_ex(bmain, scene, view_layer, EM_FREEDATA);
130 }
131 }
132 base_activate(C, base);
133}
134
136 const Scene *scene, ViewLayer *view_layer, View3D *v3d, int action, bool *r_any_visible)
137{
138 if (action == SEL_TOGGLE) {
139 action = SEL_SELECT;
140 FOREACH_VISIBLE_BASE_BEGIN (scene, view_layer, v3d, base) {
141 if (v3d && ((v3d->object_type_exclude_select & (1 << base->object->type)) != 0)) {
142 continue;
143 }
144 if ((base->flag & BASE_SELECTED) != 0) {
145 action = SEL_DESELECT;
146 break;
147 }
148 }
150 }
151
152 bool any_visible = false;
153 bool changed = false;
154 FOREACH_VISIBLE_BASE_BEGIN (scene, view_layer, v3d, base) {
155 if (v3d && ((v3d->object_type_exclude_select & (1 << base->object->type)) != 0)) {
156 continue;
157 }
158 switch (action) {
159 case SEL_SELECT:
160 if ((base->flag & BASE_SELECTED) == 0) {
161 base_select(base, BA_SELECT);
162 changed = true;
163 }
164 break;
165 case SEL_DESELECT:
166 if ((base->flag & BASE_SELECTED) != 0) {
168 changed = true;
169 }
170 break;
171 case SEL_INVERT:
172 if ((base->flag & BASE_SELECTED) != 0) {
174 changed = true;
175 }
176 else {
177 base_select(base, BA_SELECT);
178 changed = true;
179 }
180 break;
181 }
182 any_visible = true;
183 }
185 if (r_any_visible) {
186 *r_any_visible = any_visible;
187 }
188 return changed;
189}
190
191bool base_deselect_all(const Scene *scene, ViewLayer *view_layer, View3D *v3d, int action)
192{
193 return base_deselect_all_ex(scene, view_layer, v3d, action, nullptr);
194}
195
197
198/* -------------------------------------------------------------------- */
201
203{
205 if (base->flag & BASE_SELECTABLE) {
206 return 3;
207 }
208 return 2;
209 }
210 return 1;
211}
212
213Base *find_first_by_data_id(const Scene *scene, ViewLayer *view_layer, ID *id)
214{
216
217 /* Try active object. */
218 BKE_view_layer_synced_ensure(scene, view_layer);
219 Base *basact = BKE_view_layer_active_base_get(view_layer);
220
221 if (basact && basact->object && basact->object->data == id) {
222 return basact;
223 }
224
225 /* Try all objects. */
226 Base *base_best = nullptr;
227 int priority_best = 0;
228
230 if (base->object && base->object->data == id) {
231 if (base->flag & BASE_SELECTED) {
232 return base;
233 }
234
235 int priority_test = get_base_select_priority(base);
236
237 if (priority_test > priority_best) {
238 priority_best = priority_test;
239 base_best = base;
240 }
241 }
242 }
243
244 return base_best;
245}
246
247bool jump_to_object(bContext *C, Object *ob, const bool /*reveal_hidden*/)
248{
249 const Scene *scene = CTX_data_scene(C);
250 ViewLayer *view_layer = CTX_data_view_layer(C);
251 View3D *v3d = CTX_wm_view3d(C);
252 BKE_view_layer_synced_ensure(scene, view_layer);
253 Base *base = BKE_view_layer_base_find(view_layer, ob);
254
255 if (base == nullptr) {
256 return false;
257 }
258
259 /* TODO: use 'reveal_hidden', as is done with bones. */
260
261 if (BKE_view_layer_active_base_get(view_layer) != base || !(base->flag & BASE_SELECTED)) {
262 /* Select if not selected. */
263 if (!(base->flag & BASE_SELECTED)) {
264 base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
265
266 if (BASE_VISIBLE(v3d, base)) {
267 base_select(base, BA_SELECT);
268 }
269
271 }
272
273 /* Make active if not active. */
274 base_activate(C, base);
275 }
276
277 return true;
278}
279
280bool jump_to_bone(bContext *C, Object *ob, const char *bone_name, const bool reveal_hidden)
281{
282 /* Verify it's a valid armature object. */
283 if (ob == nullptr || ob->type != OB_ARMATURE) {
284 return false;
285 }
286
287 bArmature *arm = static_cast<bArmature *>(ob->data);
288
289 /* Activate the armature object. */
290 if (!jump_to_object(C, ob, reveal_hidden)) {
291 return false;
292 }
293
294 /* Switch to pose mode from object mode. */
295 if (!ELEM(ob->mode, OB_MODE_EDIT, OB_MODE_POSE)) {
297 }
298
299 if (ob->mode == OB_MODE_EDIT && arm->edbo != nullptr) {
300 /* In Edit mode select and activate the target Edit-Bone. */
301 EditBone *ebone = ED_armature_ebone_find_name(arm->edbo, bone_name);
302 if (ebone != nullptr) {
303 if (reveal_hidden) {
304 /* Unhide the bone. */
305 ebone->flag &= ~BONE_HIDDEN_A;
307 }
308
309 /* Select it. */
311
312 if (EBONE_SELECTABLE(arm, ebone)) {
313 ED_armature_ebone_select_set(ebone, true);
315 }
316
317 arm->act_edbone = ebone;
318
320 return true;
321 }
322 }
323 else if (ob->mode == OB_MODE_POSE && ob->pose != nullptr) {
324 /* In Pose mode select and activate the target Bone/Pose-Channel. */
325 bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
326 if (pchan != nullptr) {
327 if (reveal_hidden) {
328 /* Unhide the bone. */
331 }
332
333 /* Select it. */
335 ED_pose_bone_select(ob, pchan, true, true);
336
337 arm->act_bone = pchan->bone;
338
340 return true;
341 }
342 }
343
344 return false;
345}
346
348
349/* -------------------------------------------------------------------- */
352
354{
355 /* we don't check for linked scenes here, selection is
356 * still allowed then for inspection of scene */
358
359 if (CTX_data_edit_object(C)) {
360 return false;
361 }
362 if (obact && obact->mode) {
363 return false;
364 }
365
366 return true;
367}
368
370
371/* -------------------------------------------------------------------- */
374
376{
377 Scene *scene = CTX_data_scene(C);
378 ViewLayer *view_layer = CTX_data_view_layer(C);
379 View3D *v3d = CTX_wm_view3d(C);
380 short obtype, extend;
381
382 obtype = RNA_enum_get(op->ptr, "type");
383 extend = RNA_boolean_get(op->ptr, "extend");
384
385 if (extend == 0) {
386 base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
387 }
388
389 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
390 if (base->object->type == obtype) {
391 base_select(base, BA_SELECT);
392 }
393 }
395
398
400
401 return OPERATOR_FINISHED;
402}
403
405{
406 /* identifiers */
407 ot->name = "Select by Type";
408 ot->description = "Select all visible objects that are of a type";
409 ot->idname = "OBJECT_OT_select_by_type";
410
411 /* API callbacks. */
412 ot->invoke = WM_menu_invoke;
415
416 /* flags */
418
419 /* properties */
420 RNA_def_boolean(ot->srna,
421 "extend",
422 false,
423 "Extend",
424 "Extend selection instead of deselecting everything first");
425 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_type_items, 1, "Type", "");
427}
428
430
431/* -------------------------------------------------------------------- */
434
435enum {
443};
444
446 /* XXX deprecated animation system stuff. */
447 // {OBJECT_SELECT_LINKED_IPO, "IPO", 0, "Object IPO", ""},
448 {OBJECT_SELECT_LINKED_OBDATA, "OBDATA", 0, "Object Data", ""},
449 {OBJECT_SELECT_LINKED_MATERIAL, "MATERIAL", 0, "Material", ""},
450 {OBJECT_SELECT_LINKED_DUPGROUP, "DUPGROUP", 0, "Instanced Collection", ""},
451 {OBJECT_SELECT_LINKED_PARTICLE, "PARTICLE", 0, "Particle System", ""},
452 {OBJECT_SELECT_LINKED_LIBRARY, "LIBRARY", 0, "Library", ""},
453 {OBJECT_SELECT_LINKED_LIBRARY_OBDATA, "LIBRARY_OBDATA", 0, "Library (Object Data)", ""},
454 {0, nullptr, 0, nullptr, nullptr},
455};
456
457static bool object_select_all_by_obdata(bContext *C, void *obdata)
458{
459 bool changed = false;
460
461 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
462 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
463 if (base->object->data == obdata) {
464 base_select(base, BA_SELECT);
465 changed = true;
466 }
467 }
468 }
470
471 return changed;
472}
473
475{
476 bool changed = false;
477
478 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
479 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
480 Object *ob = base->object;
481 Material *mat1;
482 int a;
483
484 for (a = 1; a <= ob->totcol; a++) {
485 mat1 = BKE_object_material_get(ob, a);
486
487 if (mat1 == mat) {
488 base_select(base, BA_SELECT);
489 changed = true;
490 }
491 }
492 }
493 }
495
496 return changed;
497}
498
500{
501 bool changed = false;
502 Collection *instance_collection = (ob->transflag & OB_DUPLICOLLECTION) ?
504 nullptr;
505
506 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
507 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
508 Collection *instance_collection_other = (base->object->transflag & OB_DUPLICOLLECTION) ?
509 base->object->instance_collection :
510 nullptr;
511 if (instance_collection == instance_collection_other) {
512 base_select(base, BA_SELECT);
513 changed = true;
514 }
515 }
516 }
518
519 return changed;
520}
521
523{
524 ParticleSystem *psys_act = psys_get_current(ob);
525 bool changed = false;
526
527 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
528 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
529 /* Loop through other particles. */
530 LISTBASE_FOREACH (ParticleSystem *, psys, &base->object->particlesystem) {
531 if (psys->part == psys_act->part) {
532 base_select(base, BA_SELECT);
533 changed = true;
534 break;
535 }
536
537 if (base->flag & BASE_SELECTED) {
538 break;
539 }
540 }
541 }
542 }
544
545 return changed;
546}
547
549{
550 bool changed = false;
551
552 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
553 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
554 if (lib == base->object->id.lib) {
555 base_select(base, BA_SELECT);
556 changed = true;
557 }
558 }
559 }
561
562 return changed;
563}
564
566{
567 bool changed = false;
568
569 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
570 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
571 if (base->object->data && lib == ((ID *)base->object->data)->lib) {
572 base_select(base, BA_SELECT);
573 changed = true;
574 }
575 }
576 }
578
579 return changed;
580}
581
583{
584 int idtype = GS(id->name);
585 bool changed = false;
586
587 if (OB_DATA_SUPPORT_ID(idtype)) {
588 changed = object_select_all_by_obdata(C, id);
589 }
590 else if (idtype == ID_MA) {
591 changed = object_select_all_by_material(C, (Material *)id);
592 }
593 else if (idtype == ID_LI) {
594 changed = object_select_all_by_library(C, (Library *)id);
595 }
596
597 if (changed) {
598 Scene *scene = CTX_data_scene(C);
601 }
602}
603
605{
606 Scene *scene = CTX_data_scene(C);
607 ViewLayer *view_layer = CTX_data_view_layer(C);
608 View3D *v3d = CTX_wm_view3d(C);
609 Object *ob;
610 int nr = RNA_enum_get(op->ptr, "type");
611 bool changed = false, extend;
612
613 extend = RNA_boolean_get(op->ptr, "extend");
614
615 if (extend == 0) {
616 base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
617 }
618
619 BKE_view_layer_synced_ensure(scene, view_layer);
620 ob = BKE_view_layer_active_object_get(view_layer);
621 if (ob == nullptr) {
622 BKE_report(op->reports, RPT_ERROR, "No active object");
623 return OPERATOR_CANCELLED;
624 }
625
626 if (nr == OBJECT_SELECT_LINKED_IPO) {
627 /* XXX old animation system */
628 // if (ob->ipo == 0) return OPERATOR_CANCELLED;
629 // object_select_all_by_ipo(C, ob->ipo)
630 return OPERATOR_CANCELLED;
631 }
632 if (nr == OBJECT_SELECT_LINKED_OBDATA) {
633 if (ob->data == nullptr) {
634 return OPERATOR_CANCELLED;
635 }
636
637 changed = object_select_all_by_obdata(C, ob->data);
638 }
639 else if (nr == OBJECT_SELECT_LINKED_MATERIAL) {
640 Material *mat = nullptr;
641
642 mat = BKE_object_material_get(ob, ob->actcol);
643 if (mat == nullptr) {
644 return OPERATOR_CANCELLED;
645 }
646
647 changed = object_select_all_by_material(C, mat);
648 }
649 else if (nr == OBJECT_SELECT_LINKED_DUPGROUP) {
650 if (ob->instance_collection == nullptr) {
651 return OPERATOR_CANCELLED;
652 }
653
655 }
656 else if (nr == OBJECT_SELECT_LINKED_PARTICLE) {
658 return OPERATOR_CANCELLED;
659 }
660
661 changed = object_select_all_by_particle(C, ob);
662 }
663 else if (nr == OBJECT_SELECT_LINKED_LIBRARY) {
664 /* do nothing */
665 changed = object_select_all_by_library(C, ob->id.lib);
666 }
668 if (ob->data == nullptr) {
669 return OPERATOR_CANCELLED;
670 }
671
672 changed = object_select_all_by_library_obdata(C, ((ID *)ob->data)->lib);
673 }
674 else {
675 return OPERATOR_CANCELLED;
676 }
677
678 if (changed) {
682 return OPERATOR_FINISHED;
683 }
684
685 return OPERATOR_CANCELLED;
686}
687
689{
690 /* identifiers */
691 ot->name = "Select Linked";
692 ot->description = "Select all visible objects that are linked";
693 ot->idname = "OBJECT_OT_select_linked";
694
695 /* API callbacks. */
696 ot->invoke = WM_menu_invoke;
699
700 /* flags */
702
703 /* properties */
704 RNA_def_boolean(ot->srna,
705 "extend",
706 false,
707 "Extend",
708 "Extend selection instead of deselecting everything first");
709 ot->prop = RNA_def_enum(ot->srna, "type", prop_select_linked_types, 0, "Type", "");
710}
711
713
714/* -------------------------------------------------------------------- */
717
718enum {
730};
731
733 {OBJECT_GRPSEL_CHILDREN_RECURSIVE, "CHILDREN_RECURSIVE", 0, "Children", ""},
734 {OBJECT_GRPSEL_CHILDREN, "CHILDREN", 0, "Immediate Children", ""},
735 {OBJECT_GRPSEL_PARENT, "PARENT", 0, "Parent", ""},
736 {OBJECT_GRPSEL_SIBLINGS, "SIBLINGS", 0, "Siblings", "Shared parent"},
737 {OBJECT_GRPSEL_TYPE, "TYPE", 0, "Type", "Shared object type"},
738 {OBJECT_GRPSEL_COLLECTION, "COLLECTION", 0, "Collection", "Shared collection"},
739 {OBJECT_GRPSEL_HOOK, "HOOK", 0, "Hook", ""},
740 {OBJECT_GRPSEL_PASS, "PASS", 0, "Pass", "Render pass index"},
741 {OBJECT_GRPSEL_COLOR, "COLOR", 0, "Color", "Object color"},
743 "KEYINGSET",
744 0,
745 "Keying Set",
746 "Objects included in active Keying Set"},
747 {OBJECT_GRPSEL_LIGHT_TYPE, "LIGHT_TYPE", 0, "Light Type", "Matching light types"},
748 {0, nullptr, 0, nullptr, nullptr},
749};
750
751static bool select_grouped_children(bContext *C, Object *ob, const bool recursive)
752{
753 bool changed = false;
754
755 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
756 if (ob == base->object->parent) {
757 if ((base->flag & BASE_SELECTED) == 0) {
758 base_select(base, BA_SELECT);
759 changed = true;
760 }
761
762 if (recursive) {
763 changed |= select_grouped_children(C, base->object, true);
764 }
765 }
766 }
768 return changed;
769}
770
771/* Makes parent active and de-selected BKE_view_layer_active_object_get. */
773{
774 Scene *scene = CTX_data_scene(C);
775 ViewLayer *view_layer = CTX_data_view_layer(C);
776 View3D *v3d = CTX_wm_view3d(C);
777 Base *baspar, *basact = CTX_data_active_base(C);
778 bool changed = false;
779
780 if (!basact || !(basact->object->parent)) {
781 /* We know BKE_view_layer_active_object_get is valid. */
782 return false;
783 }
784
785 BKE_view_layer_synced_ensure(scene, view_layer);
786 baspar = BKE_view_layer_base_find(view_layer, basact->object->parent);
787
788 /* can be nullptr if parent in other scene */
789 if (baspar && BASE_SELECTABLE(v3d, baspar)) {
790 base_select(baspar, BA_SELECT);
791 base_activate(C, baspar);
792 changed = true;
793 }
794 return changed;
795}
796
797#define COLLECTION_MENU_MAX 24
798/* Select objects in the same group as the active */
800{
801 Main *bmain = CTX_data_main(C);
802 bool changed = false;
803 Collection *collection, *ob_collections[COLLECTION_MENU_MAX];
804 int collection_count = 0, i;
805 uiPopupMenu *pup;
806 uiLayout *layout;
807
808 for (collection = static_cast<Collection *>(bmain->collections.first);
809 collection && (collection_count < COLLECTION_MENU_MAX);
810 collection = static_cast<Collection *>(collection->id.next))
811 {
812 if (BKE_collection_has_object(collection, ob)) {
813 ob_collections[collection_count] = collection;
815 }
816 }
817
818 if (!collection_count) {
819 return false;
820 }
821 if (collection_count == 1) {
822 collection = ob_collections[0];
823 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
824 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
825 if (BKE_collection_has_object(collection, base->object)) {
826 base_select(base, BA_SELECT);
827 changed = true;
828 }
829 }
830 }
832 return changed;
833 }
834
835 /* build the menu. */
836 pup = UI_popup_menu_begin(C, IFACE_("Select Collection"), ICON_NONE);
837 layout = UI_popup_menu_layout(pup);
838
839 for (i = 0; i < collection_count; i++) {
840 collection = ob_collections[i];
841 PointerRNA op_ptr = layout->op(
842 "OBJECT_OT_select_same_collection", collection->id.name + 2, ICON_NONE);
843 RNA_string_set(&op_ptr, "collection", collection->id.name + 2);
844 }
845
846 UI_popup_menu_end(C, pup);
847 return changed; /* The operator already handle this! */
848}
849
851{
852 const Scene *scene = CTX_data_scene(C);
853 ViewLayer *view_layer = CTX_data_view_layer(C);
854 View3D *v3d = CTX_wm_view3d(C);
855
856 bool changed = false;
857 Base *base;
858 HookModifierData *hmd;
859
861 if (md->type == eModifierType_Hook) {
862 hmd = (HookModifierData *)md;
863 if (hmd->object) {
864 BKE_view_layer_synced_ensure(scene, view_layer);
865 base = BKE_view_layer_base_find(view_layer, hmd->object);
866 if (base && ((base->flag & BASE_SELECTED) == 0) && BASE_SELECTABLE(v3d, base)) {
867 base_select(base, BA_SELECT);
868 changed = true;
869 }
870 }
871 }
872 }
873 return changed;
874}
875
876/* Select objects with the same parent as the active (siblings),
877 * parent can be nullptr also */
879{
880 bool changed = false;
881
882 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
883 if ((base->object->parent == ob->parent) && ((base->flag & BASE_SELECTED) == 0)) {
884 base_select(base, BA_SELECT);
885 changed = true;
886 }
887 }
889 return changed;
890}
892{
893 Light *la = static_cast<Light *>(ob->data);
894
895 bool changed = false;
896
897 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
898 if (base->object->type == OB_LAMP) {
899 Light *la_test = static_cast<Light *>(base->object->data);
900 if ((la->type == la_test->type) && ((base->flag & BASE_SELECTED) == 0)) {
901 base_select(base, BA_SELECT);
902 changed = true;
903 }
904 }
905 }
907 return changed;
908}
910{
911 bool changed = false;
912
913 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
914 if ((base->object->type == ob->type) && ((base->flag & BASE_SELECTED) == 0)) {
915 base_select(base, BA_SELECT);
916 changed = true;
917 }
918 }
920 return changed;
921}
922
924{
925 bool changed = false;
926
927 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
928 if ((base->object->index == ob->index) && ((base->flag & BASE_SELECTED) == 0)) {
929 base_select(base, BA_SELECT);
930 changed = true;
931 }
932 }
934 return changed;
935}
936
938{
939 bool changed = false;
940
941 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
942 if (((base->flag & BASE_SELECTED) == 0) &&
943 compare_v3v3(base->object->color, ob->color, 0.005f))
944 {
945 base_select(base, BA_SELECT);
946 changed = true;
947 }
948 }
950 return changed;
951}
952
953static bool select_grouped_keyingset(bContext *C, Object * /*ob*/, ReportList *reports)
954{
956 bool changed = false;
957
958 /* firstly, validate KeyingSet */
959 if (ks == nullptr) {
960 BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
961 return false;
962 }
963 if (blender::animrig::validate_keyingset(C, nullptr, ks) !=
965 {
966 if (ks->paths.first == nullptr) {
967 if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
968 BKE_report(reports,
969 RPT_ERROR,
970 "Use another Keying Set, as the active one depends on the currently "
971 "selected objects or cannot find any targets due to unsuitable context");
972 }
973 else {
974 BKE_report(reports, RPT_ERROR, "Keying Set does not contain any paths");
975 }
976 }
977 return false;
978 }
979
980 /* select each object that Keying Set refers to */
981 /* TODO: perhaps to be more in line with the rest of these, we should only take objects
982 * if the passed in object is included in this too */
983 CTX_DATA_BEGIN (C, Base *, base, selectable_bases) {
984 /* only check for this object if it isn't selected already, to limit time wasted */
985 if ((base->flag & BASE_SELECTED) == 0) {
986 /* This is the slow way... we could end up with > 500 items here,
987 * with none matching, but end up doing this on 1000 objects. */
988 LISTBASE_FOREACH (KS_Path *, ksp, &ks->paths) {
989 /* if id matches, select then stop looping (match found) */
990 if (ksp->id == (ID *)base->object) {
991 base_select(base, BA_SELECT);
992 changed = true;
993 break;
994 }
995 }
996 }
997 }
999
1000 return changed;
1001}
1002
1004{
1005 Scene *scene = CTX_data_scene(C);
1006 ViewLayer *view_layer = CTX_data_view_layer(C);
1007 View3D *v3d = CTX_wm_view3d(C);
1008 Object *ob;
1009 const int type = RNA_enum_get(op->ptr, "type");
1010 bool changed = false, extend;
1011
1012 extend = RNA_boolean_get(op->ptr, "extend");
1013
1014 if (extend == 0) {
1015 changed = base_deselect_all(scene, view_layer, v3d, SEL_DESELECT);
1016 }
1017
1018 BKE_view_layer_synced_ensure(scene, view_layer);
1019 ob = BKE_view_layer_active_object_get(view_layer);
1020 if (ob == nullptr) {
1021 BKE_report(op->reports, RPT_ERROR, "No active object");
1022 return OPERATOR_CANCELLED;
1023 }
1024
1025 switch (type) {
1027 changed |= select_grouped_children(C, ob, true);
1028 break;
1030 changed |= select_grouped_children(C, ob, false);
1031 break;
1033 changed |= select_grouped_parent(C);
1034 break;
1036 changed |= select_grouped_siblings(C, ob);
1037 break;
1038 case OBJECT_GRPSEL_TYPE:
1039 changed |= select_grouped_type(C, ob);
1040 break;
1042 changed |= select_grouped_collection(C, ob);
1043 break;
1044 case OBJECT_GRPSEL_HOOK:
1045 changed |= select_grouped_object_hooks(C, ob);
1046 break;
1047 case OBJECT_GRPSEL_PASS:
1048 changed |= select_grouped_index_object(C, ob);
1049 break;
1051 changed |= select_grouped_color(C, ob);
1052 break;
1054 changed |= select_grouped_keyingset(C, ob, op->reports);
1055 break;
1057 if (ob->type != OB_LAMP) {
1058 BKE_report(op->reports, RPT_ERROR, "Active object must be a light");
1059 break;
1060 }
1061 changed |= select_grouped_lighttype(C, ob);
1062 break;
1063 default:
1064 break;
1065 }
1066
1067 if (changed) {
1071 return OPERATOR_FINISHED;
1072 }
1073
1074 return OPERATOR_CANCELLED;
1075}
1076
1078{
1079 /* identifiers */
1080 ot->name = "Select Grouped";
1081 ot->description = "Select all visible objects grouped by various properties";
1082 ot->idname = "OBJECT_OT_select_grouped";
1083
1084 /* API callbacks. */
1085 ot->invoke = WM_menu_invoke;
1088
1089 /* flags */
1090 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1091
1092 /* properties */
1093 RNA_def_boolean(ot->srna,
1094 "extend",
1095 false,
1096 "Extend",
1097 "Extend selection instead of deselecting everything first");
1098 ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
1099}
1100
1102
1103/* -------------------------------------------------------------------- */
1106
1108{
1109 Scene *scene = CTX_data_scene(C);
1110 ViewLayer *view_layer = CTX_data_view_layer(C);
1111 View3D *v3d = CTX_wm_view3d(C);
1112 int action = RNA_enum_get(op->ptr, "action");
1113 bool any_visible = false;
1114
1115 bool changed = base_deselect_all_ex(scene, view_layer, v3d, action, &any_visible);
1116
1117 if (changed) {
1120
1122
1123 return OPERATOR_FINISHED;
1124 }
1125 if (any_visible == false) {
1126 /* TODO(@ideasman42): Looks like we could remove this,
1127 * if not comment should say why its needed. */
1128 return OPERATOR_PASS_THROUGH;
1129 }
1130 return OPERATOR_CANCELLED;
1131}
1132
1134{
1135
1136 /* identifiers */
1137 ot->name = "(De)select All";
1138 ot->description = "Change selection of all visible objects in scene";
1139 ot->idname = "OBJECT_OT_select_all";
1140
1141 /* API callbacks. */
1142 ot->exec = object_select_all_exec;
1144
1145 /* flags */
1146 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1147
1149}
1150
1152
1153/* -------------------------------------------------------------------- */
1156
1158{
1159 Main *bmain = CTX_data_main(C);
1160 Collection *collection;
1161 char collection_name[MAX_ID_NAME - 2];
1162
1163 /* passthrough if no objects are visible */
1164 if (CTX_DATA_COUNT(C, visible_bases) == 0) {
1165 return OPERATOR_PASS_THROUGH;
1166 }
1167
1168 RNA_string_get(op->ptr, "collection", collection_name);
1169
1170 collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, collection_name);
1171
1172 if (!collection) {
1173 return OPERATOR_PASS_THROUGH;
1174 }
1175
1176 CTX_DATA_BEGIN (C, Base *, base, visible_bases) {
1177 if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLE) != 0)) {
1178 if (BKE_collection_has_object(collection, base->object)) {
1179 base_select(base, BA_SELECT);
1180 }
1181 }
1182 }
1184
1185 Scene *scene = CTX_data_scene(C);
1188
1190
1191 return OPERATOR_FINISHED;
1192}
1193
1195{
1196
1197 /* identifiers */
1198 ot->name = "Select Same Collection";
1199 ot->description = "Select object in the same collection";
1200 ot->idname = "OBJECT_OT_select_same_collection";
1201
1202 /* API callbacks. */
1205
1206 /* flags */
1207 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1208
1209 RNA_def_string(ot->srna,
1210 "collection",
1211 nullptr,
1212 MAX_ID_NAME - 2,
1213 "Collection",
1214 "Name of the collection to select");
1215}
1216
1218
1219/* -------------------------------------------------------------------- */
1222
1224{
1225 Main *bmain = CTX_data_main(C);
1226 Scene *scene = CTX_data_scene(C);
1227 ViewLayer *view_layer = CTX_data_view_layer(C);
1228 bool extend;
1229
1230 extend = RNA_boolean_get(op->ptr, "extend");
1231
1232 CTX_DATA_BEGIN (C, Base *, primbase, selected_bases) {
1233 char name_flip[MAXBONENAME];
1234
1235 BLI_string_flip_side_name(name_flip, primbase->object->id.name + 2, true, sizeof(name_flip));
1236
1237 if (!STREQ(name_flip, primbase->object->id.name + 2)) {
1238 Object *ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name_flip);
1239 if (ob) {
1240 BKE_view_layer_synced_ensure(scene, view_layer);
1241 Base *secbase = BKE_view_layer_base_find(view_layer, ob);
1242
1243 if (secbase) {
1244 base_select(secbase, BA_SELECT);
1245 }
1246 }
1247 }
1248
1249 if (extend == false) {
1250 base_select(primbase, BA_DESELECT);
1251 }
1252 }
1254
1255 /* undo? */
1258
1260
1261 return OPERATOR_FINISHED;
1262}
1263
1265{
1266
1267 /* identifiers */
1268 ot->name = "Select Mirror";
1269 ot->description =
1270 "Select the mirror objects of the selected object e.g. \"L.sword\" and \"R.sword\"";
1271 ot->idname = "OBJECT_OT_select_mirror";
1272
1273 /* API callbacks. */
1276
1277 /* flags */
1278 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1279
1280 RNA_def_boolean(ot->srna,
1281 "extend",
1282 false,
1283 "Extend",
1284 "Extend selection instead of deselecting everything first");
1285}
1286
1288
1289/* -------------------------------------------------------------------- */
1292
1293static bool object_select_more_less(bContext *C, const bool select)
1294{
1295 Scene *scene = CTX_data_scene(C);
1296 ViewLayer *view_layer = CTX_data_view_layer(C);
1297
1298 BKE_view_layer_synced_ensure(scene, view_layer);
1300 Object *ob = base->object;
1301 ob->flag &= ~OB_DONE;
1302 ob->id.tag &= ~ID_TAG_DOIT;
1303 /* parent may be in another scene */
1304 if (ob->parent) {
1305 ob->parent->flag &= ~OB_DONE;
1306 ob->parent->id.tag &= ~ID_TAG_DOIT;
1307 }
1308 }
1309
1310 Vector<PointerRNA> ctx_base_list;
1311 CTX_data_selectable_bases(C, &ctx_base_list);
1312
1313 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
1314 ob->flag |= OB_DONE;
1315 }
1317
1318 for (PointerRNA &ptr : ctx_base_list) {
1319 Object *ob = ((Base *)ptr.data)->object;
1320 if (ob->parent) {
1321 if ((ob->flag & OB_DONE) != (ob->parent->flag & OB_DONE)) {
1322 ob->id.tag |= ID_TAG_DOIT;
1323 ob->parent->id.tag |= ID_TAG_DOIT;
1324 }
1325 }
1326 }
1327
1328 bool changed = false;
1329 const short select_mode = select ? BA_SELECT : BA_DESELECT;
1330 const short select_flag = select ? BASE_SELECTED : 0;
1331
1332 for (PointerRNA &ptr : ctx_base_list) {
1333 Base *base = static_cast<Base *>(ptr.data);
1334 Object *ob = base->object;
1335 if ((ob->id.tag & ID_TAG_DOIT) && ((base->flag & BASE_SELECTED) != select_flag)) {
1336 base_select(base, eObjectSelect_Mode(select_mode));
1337 changed = true;
1338 }
1339 }
1340
1341 return changed;
1342}
1343
1345{
1346 bool changed = object_select_more_less(C, true);
1347
1348 if (changed) {
1349 Scene *scene = CTX_data_scene(C);
1352
1354
1355 return OPERATOR_FINISHED;
1356 }
1357 return OPERATOR_CANCELLED;
1358}
1359
1361{
1362 /* identifiers */
1363 ot->name = "Select More";
1364 ot->idname = "OBJECT_OT_select_more";
1365 ot->description = "Select connected parent/child objects";
1366
1367 /* API callbacks. */
1369 ot->poll = ED_operator_objectmode;
1370
1371 /* flags */
1372 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1373}
1374
1376{
1377 bool changed = object_select_more_less(C, false);
1378
1379 if (changed) {
1380 Scene *scene = CTX_data_scene(C);
1383
1385
1386 return OPERATOR_FINISHED;
1387 }
1388 return OPERATOR_CANCELLED;
1389}
1390
1392{
1393 /* identifiers */
1394 ot->name = "Select Less";
1395 ot->idname = "OBJECT_OT_select_less";
1396 ot->description = "Deselect objects at the boundaries of parent/child relationships";
1397
1398 /* API callbacks. */
1400 ot->poll = ED_operator_objectmode;
1401
1402 /* flags */
1403 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1404}
1405
1407
1408/* -------------------------------------------------------------------- */
1411
1413{
1414 const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT);
1415 const float randfac = RNA_float_get(op->ptr, "ratio");
1417
1418 Vector<PointerRNA> ctx_data_list;
1419 CTX_data_selectable_bases(C, &ctx_data_list);
1420 int elem_map_len = 0;
1421 Base **elem_map = static_cast<Base **>(
1422 MEM_mallocN(sizeof(*elem_map) * ctx_data_list.size(), __func__));
1423
1424 for (PointerRNA &ptr : ctx_data_list) {
1425 elem_map[elem_map_len++] = static_cast<Base *>(ptr.data);
1426 }
1427
1428 BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
1429 const int count_select = elem_map_len * randfac;
1430 for (int i = 0; i < count_select; i++) {
1432 }
1433 MEM_freeN(elem_map);
1434
1435 Scene *scene = CTX_data_scene(C);
1438
1440
1441 return OPERATOR_FINISHED;
1442}
1443
1445{
1446 /* identifiers */
1447 ot->name = "Select Random";
1448 ot->description = "Select or deselect random visible objects";
1449 ot->idname = "OBJECT_OT_select_random";
1450
1451 /* API callbacks. */
1452 // ot->invoke = object_select_random_invoke; /* TODO: need a number popup. */
1455
1456 /* flags */
1457 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1458
1459 /* properties */
1461}
1462
1464
1465} // namespace blender::ed::object
Functions to deal with Armatures.
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
void ANIM_armature_bonecoll_show_from_ebone(bArmature *armature, const EditBone *ebone)
void ANIM_armature_bonecoll_show_from_pchan(bArmature *armature, const bPoseChannel *pchan)
Functionality to interact with keying sets.
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
bool BKE_collection_has_object(Collection *collection, const Object *ob)
bool CTX_data_selectable_bases(const bContext *C, blender::Vector< PointerRNA > *list)
#define CTX_DATA_BEGIN(C, Type, instance, member)
Object * CTX_data_active_object(const bContext *C)
#define CTX_DATA_COUNT(C, member)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
Base * CTX_data_active_base(const bContext *C)
Main * CTX_data_main(const bContext *C)
#define CTX_DATA_END
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
#define FOREACH_VISIBLE_BASE_END
Definition BKE_layer.hh:417
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
#define FOREACH_VISIBLE_BASE_BEGIN(_scene, _view_layer, _v3d, _instance)
Definition BKE_layer.hh:404
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
Object * BKE_view_layer_edit_object_get(const ViewLayer *view_layer)
ID * BKE_libblock_find_name(Main *bmain, short type, const char *name, const std::optional< Library * > lib=std::nullopt) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition lib_id.cc:1710
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
struct ParticleSystem * psys_get_current(struct Object *ob)
Definition particle.cc:538
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
void BKE_scene_object_base_flag_sync_from_base(Base *base)
Definition scene.cc:2858
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
Random number functions.
void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_num, unsigned int seed)
Definition rand.cc:156
size_t BLI_string_flip_side_name(char *name_dst, const char *name_src, bool strip_number, size_t name_dst_maxncpy) ATTR_NONNULL(1
#define ELEM(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_ID
#define IFACE_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_TAG_DOIT
Definition DNA_ID.h:1036
@ ID_RECALC_SELECT
Definition DNA_ID.h:1101
#define MAX_ID_NAME
Definition DNA_ID.h:373
@ ID_LI
@ ID_MA
@ ID_GR
@ ID_OB
@ PCHAN_DRAW_HIDDEN
@ KEYINGSET_ABSOLUTE
#define MAXBONENAME
@ BONE_HIDDEN_A
Object groups, one object can be in many groups at once.
@ BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT
@ eModifierType_Hook
@ OB_MODE_EDIT
@ OB_MODE_POSE
#define OB_DATA_SUPPORT_ID(_id_type)
@ OB_ARMATURE
@ OB_LAMP
@ OB_DONE
@ OB_DUPLICOLLECTION
#define BASE_SELECTED(v3d, base)
#define BASE_SELECTABLE(v3d, base)
#define BASE_VISIBLE(v3d, base)
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
#define EBONE_SELECTABLE(arm, ebone)
void ED_outliner_select_sync_from_object_tag(bContext *C)
bool ED_operator_objectmode(bContext *C)
@ SEL_SELECT
@ SEL_INVERT
@ SEL_DESELECT
@ SEL_TOGGLE
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(bContext *C, const char *title, int icon) ATTR_NONNULL()
uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
#define ND_OB_ACTIVE
Definition WM_types.hh:440
#define ND_OB_SELECT
Definition WM_types.hh:442
#define NC_SCENE
Definition WM_types.hh:378
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
bool ED_armature_edit_deselect_all(Object *obedit)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
void ED_armature_edit_sync_selection(ListBase *edbo)
void ED_armature_ebone_select_set(EditBone *ebone, bool select)
static int collection_count(const ListBase *lb)
static unsigned long seed
Definition btSoftBody.h:39
int64_t size() const
#define GS(x)
#define active
#define select(A, B, C)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
KeyingSet * scene_get_active_keyingset(const Scene *scene)
ModifyKeyReturn validate_keyingset(bContext *C, blender::Vector< PointerRNA > *sources, KeyingSet *keyingset)
static bool select_grouped_object_hooks(bContext *C, Object *ob)
static bool select_grouped_index_object(bContext *C, Object *ob)
bool jump_to_object(bContext *C, Object *ob, bool reveal_hidden)
Base * find_first_by_data_id(const Scene *scene, ViewLayer *view_layer, ID *id)
void OBJECT_OT_select_more(wmOperatorType *ot)
static wmOperatorStatus object_select_more_exec(bContext *C, wmOperator *)
void OBJECT_OT_select_mirror(wmOperatorType *ot)
static wmOperatorStatus object_select_random_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_select_grouped_types[]
static wmOperatorStatus object_select_same_collection_exec(bContext *C, wmOperator *op)
static bool object_select_all_by_library_obdata(bContext *C, Library *lib)
void OBJECT_OT_select_all(wmOperatorType *ot)
static bool select_grouped_color(bContext *C, Object *ob)
void OBJECT_OT_select_same_collection(wmOperatorType *ot)
static wmOperatorStatus object_select_less_exec(bContext *C, wmOperator *)
void base_activate(bContext *C, Base *base)
static wmOperatorStatus object_select_all_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_select_linked_types[]
static bool select_grouped_parent(bContext *C)
void base_select(Base *base, eObjectSelect_Mode mode)
static bool object_select_all_by_material(bContext *C, Material *mat)
void OBJECT_OT_select_linked(wmOperatorType *ot)
void OBJECT_OT_select_by_type(wmOperatorType *ot)
static bool select_grouped_children(bContext *C, Object *ob, const bool recursive)
static bool object_select_all_by_library(bContext *C, Library *lib)
static bool object_select_all_by_instance_collection(bContext *C, Object *ob)
void OBJECT_OT_select_less(wmOperatorType *ot)
static bool select_grouped_siblings(bContext *C, Object *ob)
static bool select_grouped_type(bContext *C, Object *ob)
static bool object_select_more_less(bContext *C, const bool select)
static wmOperatorStatus object_select_by_type_exec(bContext *C, wmOperator *op)
void base_activate_with_mode_exit_if_needed(bContext *C, Base *base)
static bool objects_selectable_poll(bContext *C)
bool editmode_exit_multi_ex(Main *bmain, Scene *scene, ViewLayer *view_layer, int flag)
static wmOperatorStatus object_select_mirror_exec(bContext *C, wmOperator *op)
static bool object_select_all_by_obdata(bContext *C, void *obdata)
bool jump_to_bone(bContext *C, Object *ob, const char *bone_name, bool reveal_hidden)
void base_active_refresh(Main *bmain, Scene *scene, ViewLayer *view_layer)
void select_linked_by_id(bContext *C, ID *id)
static bool object_select_all_by_particle(bContext *C, Object *ob)
void OBJECT_OT_select_grouped(wmOperatorType *ot)
static bool select_grouped_keyingset(bContext *C, Object *, ReportList *reports)
bool base_deselect_all(const Scene *scene, ViewLayer *view_layer, View3D *v3d, int action)
bool base_deselect_all_ex(const Scene *scene, ViewLayer *view_layer, View3D *v3d, int action, bool *r_any_visible)
static bool select_grouped_lighttype(bContext *C, Object *ob)
static int get_base_select_priority(Base *base)
void OBJECT_OT_select_random(wmOperatorType *ot)
bool mode_set(bContext *C, eObjectMode mode)
static bool select_grouped_collection(bContext *C, Object *ob)
static wmOperatorStatus object_select_linked_exec(bContext *C, wmOperator *op)
static wmOperatorStatus object_select_grouped_exec(bContext *C, wmOperator *op)
#define COLLECTION_MENU_MAX
void ED_pose_bone_select_tag_update(Object *ob)
bool ED_pose_deselect_all(Object *ob, int select_mode, const bool ignore_visibility)
void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select, bool change_active)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
float RNA_float_get(PointerRNA *ptr, const char *name)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
const EnumPropertyItem rna_enum_object_type_items[]
short flag
struct Object * object
struct Object * object
Definition DNA_ID.h:414
int tag
Definition DNA_ID.h:442
struct Library * lib
Definition DNA_ID.h:420
char name[258]
Definition DNA_ID.h:432
void * next
Definition DNA_ID.h:417
ListBase paths
short type
void * first
ListBase wm
Definition BKE_main.hh:307
ListBase collections
Definition BKE_main.hh:298
ListBase particlesystem
short transflag
struct Collection * instance_collection
struct bPose * pose
ListBase modifiers
float color[4]
struct Object * parent
ParticleSettings * part
int object_type_exclude_select
struct Base * basact
struct EditBone * act_edbone
ListBase * edbo
struct Bone * bone
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
static DynamicLibrary lib
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
void WM_operator_properties_select_random(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)