Blender  V2.93
pose_select.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <string.h>
25 
26 #include "DNA_anim_types.h"
27 #include "DNA_armature_types.h"
28 #include "DNA_constraint_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 
33 #include "MEM_guardedalloc.h"
34 
35 #include "BLI_blenlib.h"
36 
37 #include "BKE_action.h"
38 #include "BKE_armature.h"
39 #include "BKE_constraint.h"
40 #include "BKE_context.h"
41 #include "BKE_gpencil_modifier.h"
42 #include "BKE_layer.h"
43 #include "BKE_modifier.h"
44 #include "BKE_object.h"
45 #include "BKE_report.h"
46 
47 #include "DEG_depsgraph.h"
48 
49 #include "RNA_access.h"
50 #include "RNA_define.h"
51 
52 #include "WM_api.h"
53 #include "WM_types.h"
54 
55 #include "ED_armature.h"
56 #include "ED_keyframing.h"
57 #include "ED_mesh.h"
58 #include "ED_object.h"
59 #include "ED_outliner.h"
60 #include "ED_screen.h"
61 #include "ED_select_utils.h"
62 #include "ED_view3d.h"
63 
64 #include "armature_intern.h"
65 
66 /* utility macros for storing a temp int in the bone (selection flag) */
67 #define PBONE_PREV_FLAG_GET(pchan) ((void)0, (POINTER_AS_INT((pchan)->temp)))
68 #define PBONE_PREV_FLAG_SET(pchan, val) ((pchan)->temp = POINTER_FROM_INT(val))
69 
70 /* ***************** Pose Select Utilities ********************* */
71 
72 /* Note: SEL_TOGGLE is assumed to have already been handled! */
73 static void pose_do_bone_select(bPoseChannel *pchan, const int select_mode)
74 {
75  /* select pchan only if selectable, but deselect works always */
76  switch (select_mode) {
77  case SEL_SELECT:
78  if (!(pchan->bone->flag & BONE_UNSELECTABLE)) {
79  pchan->bone->flag |= BONE_SELECTED;
80  }
81  break;
82  case SEL_DESELECT:
84  break;
85  case SEL_INVERT:
86  if (pchan->bone->flag & BONE_SELECTED) {
88  }
89  else if (!(pchan->bone->flag & BONE_UNSELECTABLE)) {
90  pchan->bone->flag |= BONE_SELECTED;
91  }
92  break;
93  }
94 }
95 
97 {
98  BLI_assert(ob->type == OB_ARMATURE);
99  bArmature *arm = ob->data;
102 
103  if (arm->flag & ARM_HAS_VIZ_DEPS) {
104  /* mask modifier ('armature' mode), etc. */
106  }
107 
109 }
110 
111 /* Utility method for changing the selection status of a bone */
113 {
114  bArmature *arm;
115 
116  /* sanity checks */
117  /* XXX: actually, we can probably still get away with no object - at most we have no updates */
118  if (ELEM(NULL, ob, ob->pose, pchan, pchan->bone)) {
119  return;
120  }
121 
122  arm = ob->data;
123 
124  /* can only change selection state if bone can be modified */
125  if (PBONE_SELECTABLE(arm, pchan->bone)) {
126  /* change selection state - activate too if selected */
127  if (select) {
128  pchan->bone->flag |= BONE_SELECTED;
129  arm->act_bone = pchan->bone;
130  }
131  else {
132  pchan->bone->flag &= ~BONE_SELECTED;
133  arm->act_bone = NULL;
134  }
135 
136  /* TODO: select and activate corresponding vgroup? */
138  }
139 }
140 
142  View3D *v3d,
143  Object *ob,
144  Bone *bone,
145  const bool extend,
146  const bool deselect,
147  const bool toggle)
148 {
149  if (!ob || !ob->pose) {
150  return;
151  }
152 
153  Object *ob_act = OBACT(view_layer);
154  BLI_assert(OBEDIT_FROM_VIEW_LAYER(view_layer) == NULL);
155 
156  /* If the bone cannot be affected, don't do anything. */
157  if (bone == NULL || (bone->flag & BONE_UNSELECTABLE)) {
158  return;
159  }
160  bArmature *arm = ob->data;
161 
162  /* Since we do unified select, we don't shift+select a bone if the
163  * armature object was not active yet.
164  * Note, special exception for armature mode so we can do multi-select
165  * we could check for multi-select explicitly but think its fine to
166  * always give predictable behavior in weight paint mode - campbell */
167  if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) {
168  /* When we are entering into posemode via toggle-select,
169  * from another active object - always select the bone. */
170  if (!extend && !deselect && toggle) {
171  /* Re-select the bone again later in this function. */
172  bone->flag &= ~BONE_SELECTED;
173  }
174  }
175 
176  if (!extend && !deselect && !toggle) {
177  {
178  /* Don't use 'BKE_object_pose_base_array_get_unique'
179  * because we may be selecting from object mode. */
180  FOREACH_VISIBLE_BASE_BEGIN (view_layer, v3d, base_iter) {
181  Object *ob_iter = base_iter->object;
182  if ((ob_iter->type == OB_ARMATURE) && (ob_iter->mode & OB_MODE_POSE)) {
183  if (ED_pose_deselect_all(ob_iter, SEL_DESELECT, true)) {
185  }
186  }
187  }
189  }
191  arm->act_bone = bone;
192  }
193  else {
194  if (extend) {
196  arm->act_bone = bone;
197  }
198  else if (deselect) {
199  bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
200  }
201  else if (toggle) {
202  if (bone->flag & BONE_SELECTED) {
203  /* If not active, we make it active. */
204  if (bone != arm->act_bone) {
205  arm->act_bone = bone;
206  }
207  else {
208  bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
209  }
210  }
211  else {
213  arm->act_bone = bone;
214  }
215  }
216  }
217 
218  if (ob_act) {
219  /* In weightpaint we select the associated vertex group too. */
220  if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
221  if (bone == arm->act_bone) {
222  ED_vgroup_select_by_name(ob_act, bone->name);
224  }
225  }
226  /* If there are some dependencies for visualizing armature state
227  * (e.g. Mask Modifier in 'Armature' mode), force update.
228  */
229  else if (arm->flag & ARM_HAS_VIZ_DEPS) {
230  /* NOTE: ob not ob_act here is intentional - it's the source of the
231  * bones being selected [T37247]
232  */
234  }
235 
236  /* Tag armature for copy-on-write update (since act_bone is in armature not object). */
238  }
239 }
240 
246  View3D *v3d,
247  Base *base,
248  const uint *buffer,
249  short hits,
250  bool extend,
251  bool deselect,
252  bool toggle,
253  bool do_nearest)
254 {
255  Object *ob = base->object;
256  Bone *nearBone;
257 
258  if (!ob || !ob->pose) {
259  return 0;
260  }
261 
262  /* Callers happen to already get the active base */
263  Base *base_dummy = NULL;
265  &base, 1, buffer, hits, 1, do_nearest, &base_dummy);
266 
267  ED_armature_pose_select_pick_bone(view_layer, v3d, ob, nearBone, extend, deselect, toggle);
268 
269  return nearBone != NULL;
270 }
271 
281 {
282  BLI_assert(base_select && (base_select->object->type == OB_ARMATURE));
283  Object *ob_active = OBACT(view_layer);
284  BLI_assert(ob_active && (ob_active->mode & OB_MODE_ALL_WEIGHT_PAINT));
285 
286  if (ob_active->type == OB_GPENCIL) {
287  GpencilVirtualModifierData virtualModifierData;
289  &virtualModifierData);
290  for (; md; md = md->next) {
291  if (md->type == eGpencilModifierType_Armature) {
293  Object *ob_arm = agmd->object;
294  if (ob_arm != NULL) {
295  Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
296  if ((base_arm != NULL) && (base_arm != base_select) &&
297  (base_arm->flag & BASE_SELECTED)) {
299  }
300  }
301  }
302  }
303  }
304  else {
305  VirtualModifierData virtualModifierData;
306  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob_active, &virtualModifierData);
307  for (; md; md = md->next) {
308  if (md->type == eModifierType_Armature) {
310  Object *ob_arm = amd->object;
311  if (ob_arm != NULL) {
312  Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
313  if ((base_arm != NULL) && (base_arm != base_select) &&
314  (base_arm->flag & BASE_SELECTED)) {
316  }
317  }
318  }
319  }
320  }
321  if ((base_select->flag & BASE_SELECTED) == 0) {
322  ED_object_base_select(base_select, BA_SELECT);
323  }
324 }
325 
326 /* 'select_mode' is usual SEL_SELECT/SEL_DESELECT/SEL_TOGGLE/SEL_INVERT.
327  * When true, 'ignore_visibility' makes this func also affect invisible bones
328  * (hidden or on hidden layers). */
329 bool ED_pose_deselect_all(Object *ob, int select_mode, const bool ignore_visibility)
330 {
331  bArmature *arm = ob->data;
332  bPoseChannel *pchan;
333 
334  /* we call this from outliner too */
335  if (ob->pose == NULL) {
336  return false;
337  }
338 
339  /* Determine if we're selecting or deselecting */
340  if (select_mode == SEL_TOGGLE) {
341  select_mode = SEL_SELECT;
342  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
343  if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) {
344  if (pchan->bone->flag & BONE_SELECTED) {
345  select_mode = SEL_DESELECT;
346  break;
347  }
348  }
349  }
350  }
351 
352  /* Set the flags accordingly */
353  bool changed = false;
354  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
355  /* ignore the pchan if it isn't visible or if its selection cannot be changed */
356  if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) {
357  int flag_prev = pchan->bone->flag;
358  pose_do_bone_select(pchan, select_mode);
359  changed = (changed || flag_prev != pchan->bone->flag);
360  }
361  }
362  return changed;
363 }
364 
365 static bool ed_pose_is_any_selected(Object *ob, bool ignore_visibility)
366 {
367  bArmature *arm = ob->data;
368  LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
369  if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) {
370  if (pchan->bone->flag & BONE_SELECTED) {
371  return true;
372  }
373  }
374  }
375  return false;
376 }
377 
378 static bool ed_pose_is_any_selected_multi(Base **bases, uint bases_len, bool ignore_visibility)
379 {
380  for (uint base_index = 0; base_index < bases_len; base_index++) {
381  Object *ob_iter = bases[base_index]->object;
382  if (ed_pose_is_any_selected(ob_iter, ignore_visibility)) {
383  return true;
384  }
385  }
386  return false;
387 }
388 
390  uint bases_len,
391  int select_mode,
392  const bool ignore_visibility)
393 {
394  if (select_mode == SEL_TOGGLE) {
395  select_mode = ed_pose_is_any_selected_multi(bases, bases_len, ignore_visibility) ?
396  SEL_DESELECT :
397  SEL_SELECT;
398  }
399 
400  bool changed_multi = false;
401  for (uint base_index = 0; base_index < bases_len; base_index++) {
402  Object *ob_iter = bases[base_index]->object;
403  if (ED_pose_deselect_all(ob_iter, select_mode, ignore_visibility)) {
405  changed_multi = true;
406  }
407  }
408  return changed_multi;
409 }
410 
411 bool ED_pose_deselect_all_multi(bContext *C, int select_mode, const bool ignore_visibility)
412 {
414  ViewContext vc;
416  uint bases_len = 0;
417 
418  Base **bases = BKE_object_pose_base_array_get_unique(vc.view_layer, vc.v3d, &bases_len);
419  bool changed_multi = ED_pose_deselect_all_multi_ex(
420  bases, bases_len, select_mode, ignore_visibility);
421  MEM_freeN(bases);
422  return changed_multi;
423 }
424 
425 /* ***************** Selections ********************** */
426 
427 static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
428 {
429  Bone *curBone;
430 
431  /* stop when unconnected child is encountered, or when unselectable bone is encountered */
432  if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE)) {
433  return;
434  }
435 
436  if (extend) {
437  bone->flag &= ~BONE_SELECTED;
438  }
439  else {
440  bone->flag |= BONE_SELECTED;
441  }
442 
443  for (curBone = bone->childbase.first; curBone; curBone = curBone->next) {
444  selectconnected_posebonechildren(ob, curBone, extend);
445  }
446 }
447 
448 /* within active object context */
449 /* previously known as "selectconnected_posearmature" */
451 {
452  Bone *bone, *curBone, *next = NULL;
453  const bool extend = RNA_boolean_get(op->ptr, "extend");
454 
456 
457  Base *base = NULL;
458  bone = ED_armature_pick_bone(C, event->mval, !extend, &base);
459 
460  if (!bone) {
461  return OPERATOR_CANCELLED;
462  }
463 
464  /* Select parents */
465  for (curBone = bone; curBone; curBone = next) {
466  /* ignore bone if cannot be selected */
467  if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
468  if (extend) {
469  curBone->flag &= ~BONE_SELECTED;
470  }
471  else {
472  curBone->flag |= BONE_SELECTED;
473  }
474 
475  if (curBone->flag & BONE_CONNECTED) {
476  next = curBone->parent;
477  }
478  else {
479  next = NULL;
480  }
481  }
482  else {
483  next = NULL;
484  }
485  }
486 
487  /* Select children */
488  for (curBone = bone->childbase.first; curBone; curBone = curBone->next) {
489  selectconnected_posebonechildren(base->object, curBone, extend);
490  }
491 
493 
495 
496  return OPERATOR_FINISHED;
497 }
498 
500 {
502 }
503 
505 {
506  /* identifiers */
507  ot->name = "Select Connected";
508  ot->idname = "POSE_OT_select_linked_pick";
509  ot->description = "Select bones linked by parent/child connections under the mouse cursor";
510 
511  /* callbacks */
512  /* leave 'exec' unset */
515 
516  /* flags */
518 
519  /* props */
521  "extend",
522  false,
523  "Extend",
524  "Extend selection instead of deselecting everything first");
525 }
526 
528 {
529  Bone *curBone, *next = NULL;
530 
531  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
532  if ((pchan->bone->flag & BONE_SELECTED) == 0) {
533  continue;
534  }
535 
536  bArmature *arm = ob->data;
537 
538  /* Select parents */
539  for (curBone = pchan->bone; curBone; curBone = next) {
540  if (PBONE_SELECTABLE(arm, curBone)) {
541  curBone->flag |= BONE_SELECTED;
542 
543  if (curBone->flag & BONE_CONNECTED) {
544  next = curBone->parent;
545  }
546  else {
547  next = NULL;
548  }
549  }
550  else {
551  next = NULL;
552  }
553  }
554 
555  /* Select children */
556  for (curBone = pchan->bone->childbase.first; curBone; curBone = curBone->next) {
557  selectconnected_posebonechildren(ob, curBone, false);
558  }
560  }
561  CTX_DATA_END;
562 
564 
565  return OPERATOR_FINISHED;
566 }
567 
569 {
570  /* identifiers */
571  ot->name = "Select Connected";
572  ot->idname = "POSE_OT_select_linked";
573  ot->description = "Select all bones linked by parent/child connections to the current selection";
574 
575  /* callbacks */
578 
579  /* flags */
581 }
582 
583 /* -------------------------------------- */
584 
586 {
587  int action = RNA_enum_get(op->ptr, "action");
588 
590  int multipaint = scene->toolsettings->multipaint;
591 
592  if (action == SEL_TOGGLE) {
593  action = CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT;
594  }
595 
596  Object *ob_prev = NULL;
597 
598  /* Set the flags. */
599  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
600  bArmature *arm = ob->data;
601  pose_do_bone_select(pchan, action);
602 
603  if (ob_prev != ob) {
604  /* weightpaint or mask modifiers need depsgraph updates */
605  if (multipaint || (arm->flag & ARM_HAS_VIZ_DEPS)) {
607  }
608  /* need to tag armature for cow updates, or else selection doesn't update */
610  ob_prev = ob;
611  }
612  }
613  CTX_DATA_END;
614 
616 
618 
619  return OPERATOR_FINISHED;
620 }
621 
623 {
624  /* identifiers */
625  ot->name = "(De)select All";
626  ot->idname = "POSE_OT_select_all";
627  ot->description = "Toggle selection status of all bones";
628 
629  /* api callbacks */
632 
633  /* flags */
635 
637 }
638 
639 /* -------------------------------------- */
640 
642 {
644  bArmature *arm = (bArmature *)ob->data;
645  bPoseChannel *pchan, *parent;
646 
647  /* Determine if there is an active bone */
648  pchan = CTX_data_active_pose_bone(C);
649  if (pchan) {
650  parent = pchan->parent;
651  if ((parent) && !(parent->bone->flag & (BONE_HIDDEN_P | BONE_UNSELECTABLE))) {
652  parent->bone->flag |= BONE_SELECTED;
653  arm->act_bone = parent->bone;
654  }
655  else {
656  return OPERATOR_CANCELLED;
657  }
658  }
659  else {
660  return OPERATOR_CANCELLED;
661  }
662 
664 
666  return OPERATOR_FINISHED;
667 }
668 
670 {
671  /* identifiers */
672  ot->name = "Select Parent Bone";
673  ot->idname = "POSE_OT_select_parent";
674  ot->description = "Select bones that are parents of the currently selected bones";
675 
676  /* api callbacks */
679 
680  /* flags */
682 }
683 
684 /* -------------------------------------- */
685 
687 {
688  bConstraint *con;
689  int found = 0;
690 
691  CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) {
692  if (pchan->bone->flag & BONE_SELECTED) {
693  for (con = pchan->constraints.first; con; con = con->next) {
695  ListBase targets = {NULL, NULL};
696  bConstraintTarget *ct;
697 
698  if (cti && cti->get_constraint_targets) {
699  cti->get_constraint_targets(con, &targets);
700 
701  for (ct = targets.first; ct; ct = ct->next) {
702  Object *ob = ct->tar;
703 
704  /* Any armature that is also in pose mode should be selected. */
705  if ((ct->subtarget[0] != '\0') && (ob != NULL) && (ob->type == OB_ARMATURE) &&
706  (ob->mode == OB_MODE_POSE)) {
708  if ((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) {
711  found = 1;
712  }
713  }
714  }
715 
716  if (cti->flush_constraint_targets) {
717  cti->flush_constraint_targets(con, &targets, 1);
718  }
719  }
720  }
721  }
722  }
723  CTX_DATA_END;
724 
725  if (!found) {
726  return OPERATOR_CANCELLED;
727  }
728 
730 
731  return OPERATOR_FINISHED;
732 }
733 
735 {
736  /* identifiers */
737  ot->name = "Select Constraint Target";
738  ot->idname = "POSE_OT_select_constraint_target";
739  ot->description = "Select bones used as targets for the currently selected bones";
740 
741  /* api callbacks */
744 
745  /* flags */
747 }
748 
749 /* -------------------------------------- */
750 
751 /* No need to convert to multi-objects. Just like we keep the non-active bones
752  * selected we then keep the non-active objects untouched (selected/unselected). */
754 {
756  bArmature *arm = ob->data;
757  bPoseChannel *pchan_act;
758  int direction = RNA_enum_get(op->ptr, "direction");
759  const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
760  bool changed = false;
761 
762  pchan_act = BKE_pose_channel_active(ob);
763  if (pchan_act == NULL) {
764  return OPERATOR_CANCELLED;
765  }
766 
767  if (direction == BONE_SELECT_PARENT) {
768  if (pchan_act->parent) {
769  Bone *bone_parent;
770  bone_parent = pchan_act->parent->bone;
771 
772  if (PBONE_SELECTABLE(arm, bone_parent)) {
773  if (!add_to_sel) {
774  pchan_act->bone->flag &= ~BONE_SELECTED;
775  }
776  bone_parent->flag |= BONE_SELECTED;
777  arm->act_bone = bone_parent;
778 
779  changed = true;
780  }
781  }
782  }
783  else { /* direction == BONE_SELECT_CHILD */
784  bPoseChannel *pchan_iter;
785  Bone *bone_child = NULL;
786  int pass;
787 
788  /* first pass, only connected bones (the logical direct child) */
789  for (pass = 0; pass < 2 && (bone_child == NULL); pass++) {
790  for (pchan_iter = ob->pose->chanbase.first; pchan_iter; pchan_iter = pchan_iter->next) {
791  /* possible we have multiple children, some invisible */
792  if (PBONE_SELECTABLE(arm, pchan_iter->bone)) {
793  if (pchan_iter->parent == pchan_act) {
794  if ((pass == 1) || (pchan_iter->bone->flag & BONE_CONNECTED)) {
795  bone_child = pchan_iter->bone;
796  break;
797  }
798  }
799  }
800  }
801  }
802 
803  if (bone_child) {
804  arm->act_bone = bone_child;
805 
806  if (!add_to_sel) {
807  pchan_act->bone->flag &= ~BONE_SELECTED;
808  }
809  bone_child->flag |= BONE_SELECTED;
810 
811  changed = true;
812  }
813  }
814 
815  if (changed == false) {
816  return OPERATOR_CANCELLED;
817  }
818 
820 
822 
823  return OPERATOR_FINISHED;
824 }
825 
827 {
828  static const EnumPropertyItem direction_items[] = {
829  {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
830  {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
831  {0, NULL, 0, NULL, NULL},
832  };
833 
834  /* identifiers */
835  ot->name = "Select Hierarchy";
836  ot->idname = "POSE_OT_select_hierarchy";
837  ot->description = "Select immediate parent/children of selected bones";
838 
839  /* api callbacks */
842 
843  /* flags */
845 
846  /* props */
847  ot->prop = RNA_def_enum(
848  ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
849  RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
850 }
851 
852 /* -------------------------------------- */
853 
854 /* modes for select same */
855 typedef enum ePose_SelectSame_Mode {
860 
861 static bool pose_select_same_group(bContext *C, bool extend)
862 {
863  ViewLayer *view_layer = CTX_data_view_layer(C);
864  bool *group_flags_array;
865  bool *group_flags = NULL;
866  int groups_len = 0;
867  bool changed = false, tagged = false;
868  Object *ob_prev = NULL;
869  uint ob_index;
870 
871  uint objects_len = 0;
872  Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
873 
874  for (ob_index = 0; ob_index < objects_len; ob_index++) {
875  Object *ob = BKE_object_pose_armature_get(objects[ob_index]);
876  bArmature *arm = (ob) ? ob->data : NULL;
877  bPose *pose = (ob) ? ob->pose : NULL;
878 
879  /* Sanity checks. */
880  if (ELEM(NULL, ob, pose, arm)) {
881  continue;
882  }
883 
884  ob->id.tag &= ~LIB_TAG_DOIT;
885  groups_len = MAX2(groups_len, BLI_listbase_count(&pose->agroups));
886  }
887 
888  /* Nothing to do here. */
889  if (groups_len == 0) {
890  MEM_freeN(objects);
891  return false;
892  }
893 
894  /* alloc a small array to keep track of the groups to use
895  * - each cell stores on/off state for whether group should be used
896  * - size is (groups_len + 1), since (index = 0) is used for no-group
897  */
898  groups_len++;
899  group_flags_array = MEM_callocN(objects_len * groups_len * sizeof(bool),
900  "pose_select_same_group");
901 
902  group_flags = NULL;
903  ob_index = -1;
904  ob_prev = NULL;
905  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
906  if (ob != ob_prev) {
907  ob_index++;
908  group_flags = group_flags_array + (ob_index * groups_len);
909  ob_prev = ob;
910  }
911 
912  /* keep track of group as group to use later? */
913  if (pchan->bone->flag & BONE_SELECTED) {
914  group_flags[pchan->agrp_index] = true;
915  tagged = true;
916  }
917 
918  /* deselect all bones before selecting new ones? */
919  if ((extend == false) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
920  pchan->bone->flag &= ~BONE_SELECTED;
921  }
922  }
923  CTX_DATA_END;
924 
925  /* small optimization: only loop through bones a second time if there are any groups tagged */
926  if (tagged) {
927  group_flags = NULL;
928  ob_index = -1;
929  ob_prev = NULL;
930  /* only if group matches (and is not selected or current bone) */
931  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
932  if (ob != ob_prev) {
933  ob_index++;
934  group_flags = group_flags_array + (ob_index * groups_len);
935  ob_prev = ob;
936  }
937 
938  if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
939  /* check if the group used by this bone is counted */
940  if (group_flags[pchan->agrp_index]) {
941  pchan->bone->flag |= BONE_SELECTED;
942  ob->id.tag |= LIB_TAG_DOIT;
943  }
944  }
945  }
946  CTX_DATA_END;
947  }
948 
949  for (ob_index = 0; ob_index < objects_len; ob_index++) {
950  Object *ob = objects[ob_index];
951  if (ob->id.tag & LIB_TAG_DOIT) {
953  changed = true;
954  }
955  }
956 
957  /* Cleanup. */
958  MEM_freeN(group_flags_array);
959  MEM_freeN(objects);
960 
961  return changed;
962 }
963 
964 static bool pose_select_same_layer(bContext *C, bool extend)
965 {
966  ViewLayer *view_layer = CTX_data_view_layer(C);
967  int *layers_array, *layers = NULL;
968  Object *ob_prev = NULL;
969  uint ob_index;
970  bool changed = false;
971 
972  uint objects_len = 0;
973  Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
974 
975  for (ob_index = 0; ob_index < objects_len; ob_index++) {
976  Object *ob = objects[ob_index];
977  ob->id.tag &= ~LIB_TAG_DOIT;
978  }
979 
980  layers_array = MEM_callocN(objects_len * sizeof(*layers_array), "pose_select_same_layer");
981 
982  /* Figure out what bones are selected. */
983  layers = NULL;
984  ob_prev = NULL;
985  ob_index = -1;
986  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
987  if (ob != ob_prev) {
988  layers = &layers_array[++ob_index];
989  ob_prev = ob;
990  }
991 
992  /* Keep track of layers to use later? */
993  if (pchan->bone->flag & BONE_SELECTED) {
994  *layers |= pchan->bone->layer;
995  }
996 
997  /* Deselect all bones before selecting new ones? */
998  if ((extend == false) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
999  pchan->bone->flag &= ~BONE_SELECTED;
1000  }
1001  }
1002  CTX_DATA_END;
1003 
1004  bool any_layer = false;
1005  for (ob_index = 0; ob_index < objects_len; ob_index++) {
1006  if (layers_array[ob_index]) {
1007  any_layer = true;
1008  break;
1009  }
1010  }
1011 
1012  if (!any_layer) {
1013  goto cleanup;
1014  }
1015 
1016  /* Select bones that are on same layers as layers flag. */
1017  ob_prev = NULL;
1018  ob_index = -1;
1019  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob) {
1020  if (ob != ob_prev) {
1021  layers = &layers_array[++ob_index];
1022  ob_prev = ob;
1023  }
1024 
1025  /* if bone is on a suitable layer, and the bone can have its selection changed, select it */
1026  if ((*layers & pchan->bone->layer) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
1027  pchan->bone->flag |= BONE_SELECTED;
1028  ob->id.tag |= LIB_TAG_DOIT;
1029  }
1030  }
1031  CTX_DATA_END;
1032 
1033  for (ob_index = 0; ob_index < objects_len; ob_index++) {
1034  Object *ob = objects[ob_index];
1035  if (ob->id.tag & LIB_TAG_DOIT) {
1037  changed = true;
1038  }
1039  }
1040 
1041 cleanup:
1042  /* Cleanup. */
1043  MEM_freeN(layers_array);
1044  MEM_freeN(objects);
1045 
1046  return changed;
1047 }
1048 
1049 static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool extend)
1050 {
1051  ViewLayer *view_layer = CTX_data_view_layer(C);
1052  bool changed_multi = false;
1054  KS_Path *ksp;
1055 
1056  /* sanity checks: validate Keying Set and object */
1057  if (ks == NULL) {
1058  BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
1059  return false;
1060  }
1061  if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
1062  if (ks->paths.first == NULL) {
1063  if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
1064  BKE_report(reports,
1065  RPT_ERROR,
1066  "Use another Keying Set, as the active one depends on the currently "
1067  "selected items or cannot find any targets due to unsuitable context");
1068  }
1069  else {
1070  BKE_report(reports, RPT_ERROR, "Keying Set does not contain any paths");
1071  }
1072  }
1073  return false;
1074  }
1075 
1076  /* if not extending selection, deselect all selected first */
1077  if (extend == false) {
1078  CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) {
1079  if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
1080  pchan->bone->flag &= ~BONE_SELECTED;
1081  }
1082  }
1083  CTX_DATA_END;
1084  }
1085 
1086  uint objects_len = 0;
1087  Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
1088 
1089  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1090  Object *ob = BKE_object_pose_armature_get(objects[ob_index]);
1091  bArmature *arm = (ob) ? ob->data : NULL;
1092  bPose *pose = (ob) ? ob->pose : NULL;
1093  bool changed = false;
1094 
1095  /* Sanity checks. */
1096  if (ELEM(NULL, ob, pose, arm)) {
1097  continue;
1098  }
1099 
1100  /* iterate over elements in the Keying Set, setting selection depending on whether
1101  * that bone is visible or not...
1102  */
1103  for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
1104  /* only items related to this object will be relevant */
1105  if ((ksp->id == &ob->id) && (ksp->rna_path != NULL)) {
1106  if (strstr(ksp->rna_path, "bones")) {
1107  char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones[");
1108 
1109  if (boneName) {
1110  bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName);
1111  MEM_freeN(boneName);
1112 
1113  if (pchan) {
1114  /* select if bone is visible and can be affected */
1115  if (PBONE_SELECTABLE(arm, pchan->bone)) {
1116  pchan->bone->flag |= BONE_SELECTED;
1117  changed = true;
1118  }
1119  }
1120  }
1121  }
1122  }
1123  }
1124 
1125  if (changed || !extend) {
1127  changed_multi = true;
1128  }
1129  }
1130  MEM_freeN(objects);
1131 
1132  return changed_multi;
1133 }
1134 
1136 {
1138  const ePose_SelectSame_Mode type = RNA_enum_get(op->ptr, "type");
1139  const bool extend = RNA_boolean_get(op->ptr, "extend");
1140  bool changed = false;
1141 
1142  /* sanity check */
1143  if (ob->pose == NULL) {
1144  return OPERATOR_CANCELLED;
1145  }
1146 
1147  /* selection types */
1148  switch (type) {
1149  case POSE_SEL_SAME_LAYER: /* layer */
1150  changed = pose_select_same_layer(C, extend);
1151  break;
1152 
1153  case POSE_SEL_SAME_GROUP: /* group */
1154  changed = pose_select_same_group(C, extend);
1155  break;
1156 
1157  case POSE_SEL_SAME_KEYINGSET: /* Keying Set */
1158  changed = pose_select_same_keyingset(C, op->reports, extend);
1159  break;
1160 
1161  default:
1162  printf("pose_select_grouped() - Unknown selection type %u\n", type);
1163  break;
1164  }
1165 
1166  /* report done status */
1167  if (changed) {
1169 
1170  return OPERATOR_FINISHED;
1171  }
1172  return OPERATOR_CANCELLED;
1173 }
1174 
1176 {
1177  static const EnumPropertyItem prop_select_grouped_types[] = {
1178  {POSE_SEL_SAME_LAYER, "LAYER", 0, "Layer", "Shared layers"},
1179  {POSE_SEL_SAME_GROUP, "GROUP", 0, "Group", "Shared group"},
1181  "KEYINGSET",
1182  0,
1183  "Keying Set",
1184  "All bones affected by active Keying Set"},
1185  {0, NULL, 0, NULL, NULL},
1186  };
1187 
1188  /* identifiers */
1189  ot->name = "Select Grouped";
1190  ot->description = "Select all visible bones grouped by similar properties";
1191  ot->idname = "POSE_OT_select_grouped";
1192 
1193  /* api callbacks */
1197 
1198  /* flags */
1200 
1201  /* properties */
1203  "extend",
1204  false,
1205  "Extend",
1206  "Extend selection instead of deselecting everything first");
1207  ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
1208 }
1209 
1210 /* -------------------------------------- */
1211 
1216 {
1217  ViewLayer *view_layer = CTX_data_view_layer(C);
1218  Object *ob_active = CTX_data_active_object(C);
1219 
1220  const bool is_weight_paint = (ob_active->mode & OB_MODE_WEIGHT_PAINT) != 0;
1221  const bool active_only = RNA_boolean_get(op->ptr, "only_active");
1222  const bool extend = RNA_boolean_get(op->ptr, "extend");
1223 
1224  uint objects_len = 0;
1225  Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
1226 
1227  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1228  Object *ob = objects[ob_index];
1229  bArmature *arm = ob->data;
1230  bPoseChannel *pchan, *pchan_mirror_act = NULL;
1231 
1232  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1233  const int flag = (pchan->bone->flag & BONE_SELECTED);
1234  PBONE_PREV_FLAG_SET(pchan, flag);
1235  }
1236 
1237  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1238  if (PBONE_SELECTABLE(arm, pchan->bone)) {
1239  bPoseChannel *pchan_mirror;
1240  int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
1241 
1242  if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
1243  (PBONE_VISIBLE(arm, pchan_mirror->bone))) {
1244  const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
1245  flag_new |= flag_mirror;
1246 
1247  if (pchan->bone == arm->act_bone) {
1248  pchan_mirror_act = pchan_mirror;
1249  }
1250 
1251  /* Skip all but the active or its mirror. */
1252  if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
1253  continue;
1254  }
1255  }
1256 
1257  pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) |
1258  flag_new;
1259  }
1260  }
1261 
1262  if (pchan_mirror_act) {
1263  arm->act_bone = pchan_mirror_act->bone;
1264 
1265  /* In weightpaint we select the associated vertex group too. */
1266  if (is_weight_paint) {
1267  ED_vgroup_select_by_name(ob_active, pchan_mirror_act->name);
1268  DEG_id_tag_update(&ob_active->id, ID_RECALC_GEOMETRY);
1269  }
1270  }
1271 
1273 
1274  /* Need to tag armature for cow updates, or else selection doesn't update. */
1276  }
1277  MEM_freeN(objects);
1278 
1280 
1281  return OPERATOR_FINISHED;
1282 }
1283 
1285 {
1286  /* identifiers */
1287  ot->name = "Select Mirror";
1288  ot->idname = "POSE_OT_select_mirror";
1289  ot->description = "Mirror the bone selection";
1290 
1291  /* api callbacks */
1294 
1295  /* flags */
1297 
1298  /* properties */
1300  ot->srna, "only_active", false, "Active Only", "Only operate on the active bone");
1301  RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
1302 }
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
struct bPoseChannel * BKE_pose_channel_active(struct Object *ob)
Definition: action.c:708
struct bPoseChannel * BKE_pose_channel_get_mirrored(const struct bPose *pose, const char *name)
#define PBONE_VISIBLE(arm, bone)
Definition: BKE_armature.h:338
#define PBONE_SELECTABLE(arm, bone)
Definition: BKE_armature.h:343
const bConstraintTypeInfo * BKE_constraint_typeinfo_get(struct bConstraint *con)
Definition: constraint.c:5435
#define CTX_DATA_BEGIN_WITH_ID(C, Type, instance, member, Type_id, instance_id)
Definition: BKE_context.h:266
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
#define CTX_DATA_BEGIN(C, Type, instance, member)
Definition: BKE_context.h:252
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
#define CTX_DATA_COUNT(C, member)
Definition: BKE_context.h:272
#define CTX_DATA_END
Definition: BKE_context.h:260
struct bPoseChannel * CTX_data_active_pose_bone(const bContext *C)
Definition: context.c:1351
struct GpencilModifierData * BKE_gpencil_modifiers_get_virtual_modifierlist(const struct Object *ob, struct GpencilVirtualModifierData *data)
#define FOREACH_VISIBLE_BASE_END
Definition: BKE_layer.h:319
#define FOREACH_VISIBLE_BASE_BEGIN(_view_layer, _v3d, _instance)
Definition: BKE_layer.h:306
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:394
struct ModifierData * BKE_modifiers_get_virtual_modifierlist(const struct Object *ob, struct VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.c:2487
struct Object ** BKE_object_pose_array_get_unique(struct ViewLayer *view_layer, struct View3D *v3d, unsigned int *r_objects_len)
Definition: object.c:2552
struct Base ** BKE_object_pose_base_array_get_unique(struct ViewLayer *view_layer, struct View3D *v3d, unsigned int *r_bases_len)
Definition: object.c:2600
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:432
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_SELECT
Definition: DNA_ID.h:638
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ KEYINGSET_ABSOLUTE
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_UNSELECTABLE
@ BONE_HIDDEN_P
@ BONE_TIPSEL
@ BONE_CONNECTED
@ ARM_HAS_VIZ_DEPS
@ eGpencilModifierType_Armature
@ BASE_SELECTED
@ eModifierType_Armature
#define OB_MODE_ALL_WEIGHT_PAINT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_POSE
Object is a sort of wrapper for general info.
@ OB_ARMATURE
@ OB_GPENCIL
#define OBEDIT_FROM_VIEW_LAYER(view_layer)
#define OBACT(_view_layer)
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
#define BONE_SELECT_CHILD
Definition: ED_armature.h:70
#define BONE_SELECT_PARENT
Definition: ED_armature.h:69
void ED_vgroup_select_by_name(struct Object *ob, const char *name)
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode)
Definition: object_select.c:98
@ BA_DESELECT
Definition: ED_object.h:146
@ BA_SELECT
Definition: ED_object.h:147
void ED_outliner_select_sync_from_pose_bone_tag(struct bContext *C)
Definition: outliner_sync.c:68
bool ED_operator_posemode(struct bContext *C)
Definition: screen_ops.c:484
bool ED_operator_view3d_active(struct bContext *C)
Definition: screen_ops.c:230
@ SEL_SELECT
@ SEL_INVERT
@ SEL_DESELECT
@ SEL_TOGGLE
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
void view3d_operator_needs_opengl(const struct bContext *C)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
#define NC_GEOM
Definition: WM_types.h:294
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_DATA
Definition: WM_types.h:408
#define ND_BONE_SELECT
Definition: WM_types.h:361
#define NC_OBJECT
Definition: WM_types.h:280
struct Bone * ED_armature_pick_bone(struct bContext *C, const int xy[2], bool findunsel, struct Base **r_base)
struct Bone * ED_armature_pick_bone_from_selectbuffer(struct Base **bases, uint bases_len, const uint *buffer, short hits, bool findunsel, bool do_nearest, struct Base **r_base)
Scene scene
const Depsgraph * depsgraph
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
eModifyKey_Returns ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
Definition: keyingsets.c:936
KeyingSet * ANIM_scene_get_active_keyingset(const Scene *scene)
Definition: keyingsets.c:674
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong * next
static const EnumPropertyItem prop_select_grouped_types[]
void POSE_OT_select_parent(wmOperatorType *ot)
Definition: pose_select.c:669
static bool pose_select_same_group(bContext *C, bool extend)
Definition: pose_select.c:861
bool ED_pose_deselect_all_multi_ex(Base **bases, uint bases_len, int select_mode, const bool ignore_visibility)
Definition: pose_select.c:389
#define PBONE_PREV_FLAG_SET(pchan, val)
Definition: pose_select.c:68
static bool ed_pose_is_any_selected_multi(Base **bases, uint bases_len, bool ignore_visibility)
Definition: pose_select.c:378
static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
Definition: pose_select.c:753
static int pose_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
Definition: pose_select.c:527
static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op))
Definition: pose_select.c:686
void POSE_OT_select_hierarchy(wmOperatorType *ot)
Definition: pose_select.c:826
void POSE_OT_select_grouped(wmOperatorType *ot)
Definition: pose_select.c:1175
void POSE_OT_select_linked_pick(wmOperatorType *ot)
Definition: pose_select.c:504
static void pose_do_bone_select(bPoseChannel *pchan, const int select_mode)
Definition: pose_select.c:73
static bool pose_select_same_layer(bContext *C, bool extend)
Definition: pose_select.c:964
void ED_pose_bone_select_tag_update(Object *ob)
Definition: pose_select.c:96
bool ED_pose_deselect_all(Object *ob, int select_mode, const bool ignore_visibility)
Definition: pose_select.c:329
static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: pose_select.c:450
void POSE_OT_select_mirror(wmOperatorType *ot)
Definition: pose_select.c:1284
static bool ed_pose_is_any_selected(Object *ob, bool ignore_visibility)
Definition: pose_select.c:365
bool ED_pose_deselect_all_multi(bContext *C, int select_mode, const bool ignore_visibility)
Definition: pose_select.c:411
static int pose_select_mirror_exec(bContext *C, wmOperator *op)
Definition: pose_select.c:1215
void POSE_OT_select_all(wmOperatorType *ot)
Definition: pose_select.c:622
void POSE_OT_select_constraint_target(wmOperatorType *ot)
Definition: pose_select.c:734
void ED_armature_pose_select_pick_bone(ViewLayer *view_layer, View3D *v3d, Object *ob, Bone *bone, const bool extend, const bool deselect, const bool toggle)
Definition: pose_select.c:141
static bool pose_select_linked_pick_poll(bContext *C)
Definition: pose_select.c:499
bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer, View3D *v3d, Base *base, const uint *buffer, short hits, bool extend, bool deselect, bool toggle, bool do_nearest)
Definition: pose_select.c:245
ePose_SelectSame_Mode
Definition: pose_select.c:855
@ POSE_SEL_SAME_GROUP
Definition: pose_select.c:857
@ POSE_SEL_SAME_LAYER
Definition: pose_select.c:856
@ POSE_SEL_SAME_KEYINGSET
Definition: pose_select.c:858
static int pose_de_select_all_exec(bContext *C, wmOperator *op)
Definition: pose_select.c:585
static int pose_select_parent_exec(bContext *C, wmOperator *UNUSED(op))
Definition: pose_select.c:641
void ED_armature_pose_select_in_wpaint_mode(ViewLayer *view_layer, Base *base_select)
Definition: pose_select.c:280
static bool pose_select_same_keyingset(bContext *C, ReportList *reports, bool extend)
Definition: pose_select.c:1049
void POSE_OT_select_linked(wmOperatorType *ot)
Definition: pose_select.c:568
#define PBONE_PREV_FLAG_GET(pchan)
Definition: pose_select.c:67
static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
Definition: pose_select.c:427
void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
Definition: pose_select.c:112
static int pose_select_grouped_exec(bContext *C, wmOperator *op)
Definition: pose_select.c:1135
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
short flag
struct Object * object
struct Bone * parent
char name[64]
struct Bone * next
ListBase childbase
struct GpencilModifierData * next
int tag
Definition: DNA_ID.h:292
struct KS_Path * next
char * rna_path
ListBase paths
void * first
Definition: DNA_listBase.h:47
struct ModifierData * next
struct bPose * pose
void * data
struct ToolSettings * toolsettings
struct ViewLayer * view_layer
Definition: ED_view3d.h:77
struct View3D * v3d
Definition: ED_view3d.h:81
struct bConstraintTarget * next
int(* get_constraint_targets)(struct bConstraint *con, struct ListBase *list)
void(* flush_constraint_targets)(struct bConstraint *con, struct ListBase *list, bool no_copy)
struct bConstraint * next
struct Bone * bone
struct bPoseChannel * parent
struct bPoseChannel * next
ListBase chanbase
int mval[2]
Definition: WM_types.h:583
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
struct PointerRNA * ptr
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_operator_properties_select_all(wmOperatorType *ot)
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982