Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / armature / pose_select.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2009 full recode.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/armature/pose_select.c
27  *  \ingroup edarmature
28  */
29
30 #include <string.h>
31
32 #include "DNA_anim_types.h"
33 #include "DNA_armature_types.h"
34 #include "DNA_constraint_types.h"
35 #include "DNA_object_types.h"
36 #include "DNA_scene_types.h"
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_blenlib.h"
41
42 #include "BKE_action.h"
43 #include "BKE_armature.h"
44 #include "BKE_constraint.h"
45 #include "BKE_context.h"
46 #include "BKE_object.h"
47 #include "BKE_report.h"
48 #include "BKE_layer.h"
49
50 #include "DEG_depsgraph.h"
51
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54
55 #include "WM_api.h"
56 #include "WM_types.h"
57
58 #include "ED_armature.h"
59 #include "ED_keyframing.h"
60 #include "ED_mesh.h"
61 #include "ED_object.h"
62 #include "ED_screen.h"
63 #include "ED_view3d.h"
64
65 #include "armature_intern.h"
66
67 /* utility macros for storing a temp int in the bone (selection flag) */
68 #define PBONE_PREV_FLAG_GET(pchan) ((void)0, (GET_INT_FROM_POINTER((pchan)->temp)))
69 #define PBONE_PREV_FLAG_SET(pchan, val) ((pchan)->temp = SET_INT_IN_POINTER(val))
70
71
72 /* ***************** Pose Select Utilities ********************* */
73
74 /* Note: SEL_TOGGLE is assumed to have already been handled! */
75 static void pose_do_bone_select(bPoseChannel *pchan, const int select_mode)
76 {
77         /* select pchan only if selectable, but deselect works always */
78         switch (select_mode) {
79                 case SEL_SELECT:
80                         if (!(pchan->bone->flag & BONE_UNSELECTABLE))
81                                 pchan->bone->flag |= BONE_SELECTED;
82                         break;
83                 case SEL_DESELECT:
84                         pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
85                         break;
86                 case SEL_INVERT:
87                         if (pchan->bone->flag & BONE_SELECTED) {
88                                 pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
89                         }
90                         else if (!(pchan->bone->flag & BONE_UNSELECTABLE)) {
91                                 pchan->bone->flag |= BONE_SELECTED;
92                         }
93                         break;
94         }
95 }
96
97 /* Utility method for changing the selection status of a bone */
98 void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
99 {
100         bArmature *arm;
101
102         /* sanity checks */
103         // XXX: actually, we can probably still get away with no object - at most we have no updates
104         if (ELEM(NULL, ob, ob->pose, pchan, pchan->bone))
105                 return;
106
107         arm = ob->data;
108
109         /* can only change selection state if bone can be modified */
110         if (PBONE_SELECTABLE(arm, pchan->bone)) {
111                 /* change selection state - activate too if selected */
112                 if (select) {
113                         pchan->bone->flag |= BONE_SELECTED;
114                         arm->act_bone = pchan->bone;
115                 }
116                 else {
117                         pchan->bone->flag &= ~BONE_SELECTED;
118                         arm->act_bone = NULL;
119                 }
120
121                 // TODO: select and activate corresponding vgroup?
122
123                 /* tag necessary depsgraph updates
124                  * (see rna_Bone_select_update() in rna_armature.c for details)
125                  */
126                 if (arm->flag & ARM_HAS_VIZ_DEPS) {
127                         DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
128                 }
129
130                 /* send necessary notifiers */
131                 WM_main_add_notifier(NC_GEOM | ND_DATA, ob);
132
133                 /* tag armature for copy-on-write update (since act_bone is in armature not object) */
134                 DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
135         }
136 }
137
138 /* called from editview.c, for mode-less pose selection */
139 /* assumes scene obact and basact is still on old situation */
140 bool ED_armature_pose_select_pick_with_buffer(
141         ViewLayer *view_layer, Base *base, const unsigned int *buffer, short hits,
142         bool extend, bool deselect, bool toggle, bool do_nearest)
143 {
144         Object *ob = base->object;
145         Bone *nearBone;
146
147         if (!ob || !ob->pose) return 0;
148
149         Object *ob_act = OBACT(view_layer);
150         Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
151
152         /* Callers happen to already get the active base */
153         Base *base_dummy = NULL;
154         nearBone = get_bone_from_selectbuffer(&base, 1, obedit != NULL, buffer, hits, 1, do_nearest, &base_dummy);
155
156         /* if the bone cannot be affected, don't do anything */
157         if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
158                 bArmature *arm = ob->data;
159
160                 /* since we do unified select, we don't shift+select a bone if the
161                  * armature object was not active yet.
162                  * note, special exception for armature mode so we can do multi-select
163                  * we could check for multi-select explicitly but think its fine to
164                  * always give predictable behavior in weight paint mode - campbell */
165                 if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) {
166                         /* when we are entering into posemode via toggle-select,
167                          * from another active object - always select the bone. */
168                         if (!extend && !deselect && toggle) {
169                                 /* re-select below */
170                                 nearBone->flag &= ~BONE_SELECTED;
171                         }
172                 }
173
174                 if (!extend && !deselect && !toggle) {
175                         {
176                                 uint objects_len = 0;
177                                 Object **objects = BKE_object_pose_array_get_unique(view_layer, &objects_len);
178                                 ED_pose_deselect_all_multi(objects, objects_len, SEL_DESELECT, true);
179                                 MEM_freeN(objects);
180                         }
181                         nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
182                         arm->act_bone = nearBone;
183                 }
184                 else {
185                         if (extend) {
186                                 nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
187                                 arm->act_bone = nearBone;
188                         }
189                         else if (deselect) {
190                                 nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
191                         }
192                         else if (toggle) {
193                                 if (nearBone->flag & BONE_SELECTED) {
194                                         /* if not active, we make it active */
195                                         if (nearBone != arm->act_bone) {
196                                                 arm->act_bone = nearBone;
197                                         }
198                                         else {
199                                                 nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
200                                         }
201                                 }
202                                 else {
203                                         nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
204                                         arm->act_bone = nearBone;
205                                 }
206                         }
207                 }
208
209                 if (ob_act) {
210                         /* in weightpaint we select the associated vertex group too */
211                         if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
212                                 if (nearBone == arm->act_bone) {
213                                         ED_vgroup_select_by_name(ob_act, nearBone->name);
214                                         DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
215                                 }
216                         }
217                         /* if there are some dependencies for visualizing armature state
218                          * (e.g. Mask Modifier in 'Armature' mode), force update
219                          */
220                         else if (arm->flag & ARM_HAS_VIZ_DEPS) {
221                                 /* NOTE: ob not ob_act here is intentional - it's the source of the
222                                  *       bones being selected  [T37247]
223                                  */
224                                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
225                         }
226
227                         /* tag armature for copy-on-write update (since act_bone is in armature not object) */
228                         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
229                 }
230         }
231
232         return nearBone != NULL;
233 }
234
235 /* 'select_mode' is usual SEL_SELECT/SEL_DESELECT/SEL_TOGGLE/SEL_INVERT.
236  * When true, 'ignore_visibility' makes this func also affect invisible bones (hidden or on hidden layers). */
237 void ED_pose_deselect_all(Object *ob, int select_mode, const bool ignore_visibility)
238 {
239         bArmature *arm = ob->data;
240         bPoseChannel *pchan;
241
242         /* we call this from outliner too */
243         if (ob->pose == NULL) {
244                 return;
245         }
246
247         /* Determine if we're selecting or deselecting */
248         if (select_mode == SEL_TOGGLE) {
249                 select_mode = SEL_SELECT;
250                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
251                         if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) {
252                                 if (pchan->bone->flag & BONE_SELECTED) {
253                                         select_mode = SEL_DESELECT;
254                                         break;
255                                 }
256                         }
257                 }
258         }
259
260         /* Set the flags accordingly */
261         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
262                 /* ignore the pchan if it isn't visible or if its selection cannot be changed */
263                 if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) {
264                         pose_do_bone_select(pchan, select_mode);
265                 }
266         }
267 }
268
269 static bool ed_pose_is_any_selected(Object *ob, bool ignore_visibility)
270 {
271         bArmature *arm = ob->data;
272         for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
273                 if (ignore_visibility || PBONE_VISIBLE(arm, pchan->bone)) {
274                         if (pchan->bone->flag & BONE_SELECTED) {
275                                 return true;
276                         }
277                 }
278         }
279         return false;
280 }
281
282 static bool ed_pose_is_any_selected_multi(Object **objects, uint objects_len, bool ignore_visibility)
283 {
284         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
285                 Object *ob_iter = objects[ob_index];
286                 if (ed_pose_is_any_selected(ob_iter, ignore_visibility)) {
287                         return true;
288                 }
289         }
290         return false;
291 }
292
293 void ED_pose_deselect_all_multi(Object **objects, uint objects_len, int select_mode, const bool ignore_visibility)
294 {
295         if (select_mode == SEL_TOGGLE) {
296                 select_mode = ed_pose_is_any_selected_multi(
297                         objects, objects_len, ignore_visibility) ? SEL_DESELECT : SEL_SELECT;
298         }
299
300         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
301                 Object *ob_iter = objects[ob_index];
302                 bArmature *arm = ob_iter->data;
303
304                 ED_pose_deselect_all(ob_iter, select_mode, ignore_visibility);
305
306                 /* if there are some dependencies for visualizing armature state
307                  * (e.g. Mask Modifier in 'Armature' mode), force update
308                  */
309                 if (arm->flag & ARM_HAS_VIZ_DEPS) {
310                         /* NOTE: ob not ob_act here is intentional - it's the source of the
311                          *       bones being selected  [T37247]
312                          */
313                         DEG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
314                 }
315
316                 /* need to tag armature for cow updates, or else selection doesn't update */
317                 DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
318         }
319 }
320
321 /* ***************** Selections ********************** */
322
323 static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
324 {
325         Bone *curBone;
326
327         /* stop when unconnected child is encountered, or when unselectable bone is encountered */
328         if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE))
329                 return;
330
331         if (extend)
332                 bone->flag &= ~BONE_SELECTED;
333         else
334                 bone->flag |= BONE_SELECTED;
335
336         for (curBone = bone->childbase.first; curBone; curBone = curBone->next)
337                 selectconnected_posebonechildren(ob, curBone, extend);
338 }
339
340 /* within active object context */
341 /* previously known as "selectconnected_posearmature" */
342 static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
343 {
344         Bone *bone, *curBone, *next = NULL;
345         const bool extend = RNA_boolean_get(op->ptr, "extend");
346
347         view3d_operator_needs_opengl(C);
348
349         Base *base = NULL;
350         bone = get_nearest_bone(C, event->mval, !extend, &base);
351
352         if (!bone)
353                 return OPERATOR_CANCELLED;
354
355         bArmature *arm = base->object->data;
356
357         /* Select parents */
358         for (curBone = bone; curBone; curBone = next) {
359                 /* ignore bone if cannot be selected */
360                 if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
361                         if (extend)
362                                 curBone->flag &= ~BONE_SELECTED;
363                         else
364                                 curBone->flag |= BONE_SELECTED;
365
366                         if (curBone->flag & BONE_CONNECTED)
367                                 next = curBone->parent;
368                         else
369                                 next = NULL;
370                 }
371                 else
372                         next = NULL;
373         }
374
375         /* Select children */
376         for (curBone = bone->childbase.first; curBone; curBone = next)
377                 selectconnected_posebonechildren(base->object, curBone, extend);
378
379         /* updates */
380         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object);
381
382         if (arm->flag & ARM_HAS_VIZ_DEPS) {
383                 /* mask modifier ('armature' mode), etc. */
384                 DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
385         }
386
387         /* need to tag armature for cow updates, or else selection doesn't update */
388         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
389
390         return OPERATOR_FINISHED;
391 }
392
393 static int pose_select_linked_poll(bContext *C)
394 {
395         return (ED_operator_view3d_active(C) && ED_operator_posemode(C));
396 }
397
398 void POSE_OT_select_linked(wmOperatorType *ot)
399 {
400         /* identifiers */
401         ot->name = "Select Connected";
402         ot->idname = "POSE_OT_select_linked";
403         ot->description = "Select bones related to selected ones by parent/child relationships";
404
405         /* callbacks */
406         /* leave 'exec' unset */
407         ot->invoke = pose_select_connected_invoke;
408         ot->poll = pose_select_linked_poll;
409
410         /* flags */
411         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
412
413         /* props */
414         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
415 }
416
417 /* -------------------------------------- */
418
419 static int pose_de_select_all_exec(bContext *C, wmOperator *op)
420 {
421         int action = RNA_enum_get(op->ptr, "action");
422
423         Scene *scene = CTX_data_scene(C);
424         int multipaint = scene->toolsettings->multipaint;
425
426         if (action == SEL_TOGGLE) {
427                 action = CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT;
428         }
429
430         Object *ob_prev = NULL;
431
432         /*      Set the flags */
433         CTX_DATA_BEGIN_WITH_ID(C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob)
434         {
435                 bArmature *arm = ob->data;
436                 pose_do_bone_select(pchan, action);
437
438                 if (ob_prev != ob) {
439                         /* weightpaint or mask modifiers need depsgraph updates */
440                         if (multipaint || (arm->flag & ARM_HAS_VIZ_DEPS)) {
441                                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
442                         }
443                         /* need to tag armature for cow updates, or else selection doesn't update */
444                         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
445                         ob_prev = ob;
446                 }
447         }
448         CTX_DATA_END;
449
450         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL);
451
452         return OPERATOR_FINISHED;
453 }
454
455 void POSE_OT_select_all(wmOperatorType *ot)
456 {
457         /* identifiers */
458         ot->name = "(De)select All";
459         ot->idname = "POSE_OT_select_all";
460         ot->description = "Toggle selection status of all bones";
461
462         /* api callbacks */
463         ot->exec = pose_de_select_all_exec;
464         ot->poll = ED_operator_posemode;
465
466         /* flags */
467         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
468
469         WM_operator_properties_select_all(ot);
470 }
471
472 /* -------------------------------------- */
473
474 static int pose_select_parent_exec(bContext *C, wmOperator *UNUSED(op))
475 {
476         /* only clear relevant transforms for selected bones */
477         ViewLayer *view_layer = CTX_data_view_layer(C);
478         FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter)
479         {
480                 Object *ob = ob_iter;
481                 bArmature *arm = (bArmature *)ob->data;
482
483                 FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan)
484                 {
485                         if (pchan) {
486                                 bPoseChannel *parent = pchan->parent;
487                                 if ((parent) && !(parent->bone->flag & (BONE_HIDDEN_P | BONE_UNSELECTABLE))) {
488                                         parent->bone->flag |= BONE_SELECTED;
489                                         arm->act_bone = parent->bone;
490                                 }
491                                 else {
492                                         continue;
493                                 }
494                         }
495                         else {
496                                 continue;
497                         }
498
499                         /* updates */
500                         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
501
502                         if (arm->flag & ARM_HAS_VIZ_DEPS) {
503                                 /* mask modifier ('armature' mode), etc. */
504                                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
505                         }
506
507                         /* tag armature for copy-on-write update (since act_bone is in armature not object) */
508                         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
509
510                 }
511                 FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
512         }
513         FOREACH_OBJECT_IN_MODE_END;
514
515         return OPERATOR_FINISHED;
516 }
517
518 void POSE_OT_select_parent(wmOperatorType *ot)
519 {
520         /* identifiers */
521         ot->name = "Select Parent Bone";
522         ot->idname = "POSE_OT_select_parent";
523         ot->description = "Select bones that are parents of the currently selected bones";
524
525         /* api callbacks */
526         ot->exec = pose_select_parent_exec;
527         ot->poll = ED_operator_posemode;
528
529         /* flags */
530         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
531 }
532
533 /* -------------------------------------- */
534
535 static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op))
536 {
537         bConstraint *con;
538         int found = 0;
539         Object *ob_prev = NULL;
540
541         CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob)
542         {
543                 bArmature *arm = ob->data;
544                 if (pchan->bone->flag & BONE_SELECTED) {
545                         for (con = pchan->constraints.first; con; con = con->next) {
546                                 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
547                                 ListBase targets = {NULL, NULL};
548                                 bConstraintTarget *ct;
549
550                                 if (cti && cti->get_constraint_targets) {
551                                         cti->get_constraint_targets(con, &targets);
552
553                                         for (ct = targets.first; ct; ct = ct->next) {
554                                                 if ((ct->tar == ob) && (ct->subtarget[0])) {
555                                                         bPoseChannel *pchanc = BKE_pose_channel_find_name(ob->pose, ct->subtarget);
556                                                         if ((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) {
557                                                                 pchanc->bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL;
558                                                                 found = 1;
559
560                                                                 if (ob != ob_prev) {
561                                                                         /* updates */
562                                                                         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
563                                                                         if (arm->flag & ARM_HAS_VIZ_DEPS) {
564                                                                                 /* mask modifier ('armature' mode), etc. */
565                                                                                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
566                                                                         }
567                                                                         /* tag armature for copy on write, since selection status is armature data */
568                                                                         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
569                                                                         ob_prev = ob;
570                                                                 }
571                                                         }
572                                                 }
573                                         }
574
575                                         if (cti->flush_constraint_targets)
576                                                 cti->flush_constraint_targets(con, &targets, 1);
577                                 }
578                         }
579                 }
580         }
581         CTX_DATA_END;
582
583         if (!found)
584                 return OPERATOR_CANCELLED;
585
586         return OPERATOR_FINISHED;
587 }
588
589 void POSE_OT_select_constraint_target(wmOperatorType *ot)
590 {
591         /* identifiers */
592         ot->name = "Select Constraint Target";
593         ot->idname = "POSE_OT_select_constraint_target";
594         ot->description = "Select bones used as targets for the currently selected bones";
595
596         /* api callbacks */
597         ot->exec = pose_select_constraint_target_exec;
598         ot->poll = ED_operator_posemode;
599
600         /* flags */
601         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
602 }
603
604 /* -------------------------------------- */
605
606 static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
607 {
608         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
609         bArmature *arm = ob->data;
610         bPoseChannel *pchan_act;
611         int direction = RNA_enum_get(op->ptr, "direction");
612         const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
613         bool changed = false;
614
615         pchan_act = BKE_pose_channel_active(ob);
616         if (pchan_act == NULL) {
617                 return OPERATOR_CANCELLED;
618         }
619
620         if (direction == BONE_SELECT_PARENT) {
621                 if (pchan_act->parent) {
622                         Bone *bone_parent;
623                         bone_parent = pchan_act->parent->bone;
624
625                         if (PBONE_SELECTABLE(arm, bone_parent)) {
626                                 if (!add_to_sel) {
627                                         pchan_act->bone->flag &= ~BONE_SELECTED;
628                                 }
629                                 bone_parent->flag |= BONE_SELECTED;
630                                 arm->act_bone = bone_parent;
631
632                                 changed = true;
633                         }
634                 }
635         }
636         else { /* direction == BONE_SELECT_CHILD */
637                 bPoseChannel *pchan_iter;
638                 Bone *bone_child = NULL;
639                 int pass;
640
641                 /* first pass, only connected bones (the logical direct child) */
642                 for (pass = 0; pass < 2 && (bone_child == NULL); pass++) {
643                         for (pchan_iter = ob->pose->chanbase.first; pchan_iter; pchan_iter = pchan_iter->next) {
644                                 /* possible we have multiple children, some invisible */
645                                 if (PBONE_SELECTABLE(arm, pchan_iter->bone)) {
646                                         if (pchan_iter->parent == pchan_act) {
647                                                 if ((pass == 1) || (pchan_iter->bone->flag & BONE_CONNECTED)) {
648                                                         bone_child = pchan_iter->bone;
649                                                         break;
650                                                 }
651                                         }
652                                 }
653                         }
654                 }
655
656                 if (bone_child) {
657                         arm->act_bone = bone_child;
658
659                         if (!add_to_sel) {
660                                 pchan_act->bone->flag &= ~BONE_SELECTED;
661                         }
662                         bone_child->flag |= BONE_SELECTED;
663
664                         changed = true;
665                 }
666         }
667
668         if (changed == false) {
669                 return OPERATOR_CANCELLED;
670         }
671
672         /* updates */
673         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
674
675         if (arm->flag & ARM_HAS_VIZ_DEPS) {
676                 /* mask modifier ('armature' mode), etc. */
677                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
678         }
679
680         /* tag armature for copy-on-write update (since act_bone is in armature not object) */
681         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
682
683         return OPERATOR_FINISHED;
684 }
685
686 void POSE_OT_select_hierarchy(wmOperatorType *ot)
687 {
688         static const EnumPropertyItem direction_items[] = {
689                 {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
690                 {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
691                 {0, NULL, 0, NULL, NULL}
692         };
693
694         /* identifiers */
695         ot->name = "Select Hierarchy";
696         ot->idname = "POSE_OT_select_hierarchy";
697         ot->description = "Select immediate parent/children of selected bones";
698
699         /* api callbacks */
700         ot->exec = pose_select_hierarchy_exec;
701         ot->poll = ED_operator_posemode;
702
703         /* flags */
704         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
705
706         /* props */
707         ot->prop = RNA_def_enum(ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
708         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
709 }
710
711 /* -------------------------------------- */
712
713 /* modes for select same */
714 typedef enum ePose_SelectSame_Mode {
715         POSE_SEL_SAME_LAYER      = 0,
716         POSE_SEL_SAME_GROUP      = 1,
717         POSE_SEL_SAME_KEYINGSET  = 2,
718 } ePose_SelectSame_Mode;
719
720 static bool pose_select_same_group(bContext *C, Object *ob, bool extend)
721 {
722         bArmature *arm = (ob) ? ob->data : NULL;
723         bPose *pose = (ob) ? ob->pose : NULL;
724         char *group_flags;
725         int numGroups = 0;
726         bool changed = false, tagged = false;
727
728         /* sanity checks */
729         if (ELEM(NULL, ob, pose, arm))
730                 return 0;
731
732         /* count the number of groups */
733         numGroups = BLI_listbase_count(&pose->agroups);
734         if (numGroups == 0)
735                 return 0;
736
737         /* alloc a small array to keep track of the groups to use
738          *  - each cell stores on/off state for whether group should be used
739          *      - size is (numGroups + 1), since (index = 0) is used for no-group
740          */
741         group_flags = MEM_callocN(numGroups + 1, "pose_select_same_group");
742
743         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
744         {
745                 /* keep track of group as group to use later? */
746                 if (pchan->bone->flag & BONE_SELECTED) {
747                         group_flags[pchan->agrp_index] = 1;
748                         tagged = true;
749                 }
750
751                 /* deselect all bones before selecting new ones? */
752                 if ((extend == false) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0)
753                         pchan->bone->flag &= ~BONE_SELECTED;
754         }
755         CTX_DATA_END;
756
757         /* small optimization: only loop through bones a second time if there are any groups tagged */
758         if (tagged) {
759                 /* only if group matches (and is not selected or current bone) */
760                 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
761                 {
762                         if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
763                                 /* check if the group used by this bone is counted */
764                                 if (group_flags[pchan->agrp_index]) {
765                                         pchan->bone->flag |= BONE_SELECTED;
766                                         changed = true;
767                                 }
768                         }
769                 }
770                 CTX_DATA_END;
771         }
772
773         /* free temp info */
774         MEM_freeN(group_flags);
775
776         return changed;
777 }
778
779 static bool pose_select_same_layer(bContext *C, Object *ob, bool extend)
780 {
781         bPose *pose = (ob) ? ob->pose : NULL;
782         bArmature *arm = (ob) ? ob->data : NULL;
783         bool changed = false;
784         int layers = 0;
785
786         if (ELEM(NULL, ob, pose, arm))
787                 return 0;
788
789         /* figure out what bones are selected */
790         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
791         {
792                 /* keep track of layers to use later? */
793                 if (pchan->bone->flag & BONE_SELECTED)
794                         layers |= pchan->bone->layer;
795
796                 /* deselect all bones before selecting new ones? */
797                 if ((extend == false) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0)
798                         pchan->bone->flag &= ~BONE_SELECTED;
799         }
800         CTX_DATA_END;
801         if (layers == 0)
802                 return 0;
803
804         /* select bones that are on same layers as layers flag */
805         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
806         {
807                 /* if bone is on a suitable layer, and the bone can have its selection changed, select it */
808                 if ((layers & pchan->bone->layer) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
809                         pchan->bone->flag |= BONE_SELECTED;
810                         changed = true;
811                 }
812         }
813         CTX_DATA_END;
814
815         return changed;
816 }
817
818 static bool pose_select_same_keyingset(bContext *C, ReportList *reports, Object *ob, bool extend)
819 {
820         KeyingSet *ks = ANIM_scene_get_active_keyingset(CTX_data_scene(C));
821         KS_Path *ksp;
822
823         bArmature *arm = (ob) ? ob->data : NULL;
824         bPose *pose = (ob) ? ob->pose : NULL;
825         bool changed = false;
826
827         /* sanity checks: validate Keying Set and object */
828         if (ks == NULL) {
829                 BKE_report(reports, RPT_ERROR, "No active Keying Set to use");
830                 return false;
831         }
832         else if (ANIM_validate_keyingset(C, NULL, ks) != 0) {
833                 if (ks->paths.first == NULL) {
834                         if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
835                                 BKE_report(reports, RPT_ERROR,
836                                            "Use another Keying Set, as the active one depends on the currently "
837                                            "selected items or cannot find any targets due to unsuitable context");
838                         }
839                         else {
840                                 BKE_report(reports, RPT_ERROR, "Keying Set does not contain any paths");
841                         }
842                 }
843                 return false;
844         }
845
846         if (ELEM(NULL, ob, pose, arm))
847                 return false;
848
849         /* if not extending selection, deselect all selected first */
850         if (extend == false) {
851                 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
852                 {
853                         if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0)
854                                 pchan->bone->flag &= ~BONE_SELECTED;
855                 }
856                 CTX_DATA_END;
857         }
858
859         /* iterate over elements in the Keying Set, setting selection depending on whether
860          * that bone is visible or not...
861          */
862         for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
863                 /* only items related to this object will be relevant */
864                 if ((ksp->id == &ob->id) && (ksp->rna_path != NULL)) {
865                         if (strstr(ksp->rna_path, "bones")) {
866                                 char *boneName = BLI_str_quoted_substrN(ksp->rna_path, "bones[");
867
868                                 if (boneName) {
869                                         bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName);
870
871                                         if (pchan) {
872                                                 /* select if bone is visible and can be affected */
873                                                 if (PBONE_SELECTABLE(arm, pchan->bone)) {
874                                                         pchan->bone->flag |= BONE_SELECTED;
875                                                         changed = true;
876                                                 }
877                                         }
878
879                                         /* free temp memory */
880                                         MEM_freeN(boneName);
881                                 }
882                         }
883                 }
884         }
885
886         return changed;
887 }
888
889 static int pose_select_grouped_exec(bContext *C, wmOperator *op)
890 {
891         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
892         bArmature *arm = (bArmature *)ob->data;
893         const ePose_SelectSame_Mode type = RNA_enum_get(op->ptr, "type");
894         const bool extend = RNA_boolean_get(op->ptr, "extend");
895         bool changed = false;
896
897         /* sanity check */
898         if (ob->pose == NULL)
899                 return OPERATOR_CANCELLED;
900
901         /* selection types */
902         switch (type) {
903                 case POSE_SEL_SAME_LAYER: /* layer */
904                         changed = pose_select_same_layer(C, ob, extend);
905                         break;
906
907                 case POSE_SEL_SAME_GROUP: /* group */
908                         changed = pose_select_same_group(C, ob, extend);
909                         break;
910
911                 case POSE_SEL_SAME_KEYINGSET: /* Keying Set */
912                         changed = pose_select_same_keyingset(C, op->reports, ob, extend);
913                         break;
914
915                 default:
916                         printf("pose_select_grouped() - Unknown selection type %u\n", type);
917                         break;
918         }
919
920         /* notifiers for updates */
921         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
922
923         if (arm->flag & ARM_HAS_VIZ_DEPS) {
924                 /* mask modifier ('armature' mode), etc. */
925                 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
926         }
927
928         /* need to tag armature for cow updates, or else selection doesn't update */
929         DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
930
931         /* report done status */
932         if (changed)
933                 return OPERATOR_FINISHED;
934         else
935                 return OPERATOR_CANCELLED;
936 }
937
938 void POSE_OT_select_grouped(wmOperatorType *ot)
939 {
940         static const EnumPropertyItem prop_select_grouped_types[] = {
941                 {POSE_SEL_SAME_LAYER, "LAYER", 0, "Layer", "Shared layers"},
942                 {POSE_SEL_SAME_GROUP, "GROUP", 0, "Group", "Shared group"},
943                 {POSE_SEL_SAME_KEYINGSET, "KEYINGSET", 0, "Keying Set", "All bones affected by active Keying Set"},
944                 {0, NULL, 0, NULL, NULL}
945         };
946
947         /* identifiers */
948         ot->name = "Select Grouped";
949         ot->description = "Select all visible bones grouped by similar properties";
950         ot->idname = "POSE_OT_select_grouped";
951
952         /* api callbacks */
953         ot->invoke = WM_menu_invoke;
954         ot->exec = pose_select_grouped_exec;
955         ot->poll = ED_operator_posemode;
956
957         /* flags */
958         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
959
960         /* properties */
961         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
962         ot->prop = RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
963 }
964
965 /* -------------------------------------- */
966
967 /**
968  * \note clone of #armature_select_mirror_exec keep in sync
969  */
970 static int pose_select_mirror_exec(bContext *C, wmOperator *op)
971 {
972         Object *ob_act = CTX_data_active_object(C);
973         ViewLayer *view_layer = CTX_data_view_layer(C);
974
975         FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, OB_MODE_POSE, ob)
976         {
977                 bArmature *arm;
978                 bPoseChannel *pchan, *pchan_mirror_act = NULL;
979                 const bool active_only = RNA_boolean_get(op->ptr, "only_active");
980                 const bool extend = RNA_boolean_get(op->ptr, "extend");
981
982                 arm = ob->data;
983
984                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
985                         const int flag = (pchan->bone->flag & BONE_SELECTED);
986                         PBONE_PREV_FLAG_SET(pchan, flag);
987                 }
988
989                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
990                         if (PBONE_SELECTABLE(arm, pchan->bone)) {
991                                 bPoseChannel *pchan_mirror;
992                                 int flag_new = extend ? PBONE_PREV_FLAG_GET(pchan) : 0;
993
994                                 if ((pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) &&
995                                     (PBONE_VISIBLE(arm, pchan_mirror->bone)))
996                                 {
997                                         const int flag_mirror = PBONE_PREV_FLAG_GET(pchan_mirror);
998                                         flag_new |= flag_mirror;
999
1000                                         if (pchan->bone == arm->act_bone) {
1001                                                 pchan_mirror_act = pchan_mirror;
1002                                         }
1003
1004                                         /* skip all but the active or its mirror */
1005                                         if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) {
1006                                                 continue;
1007                                         }
1008                                 }
1009
1010                                 pchan->bone->flag = (pchan->bone->flag & ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) | flag_new;
1011                         }
1012                 }
1013
1014                 if (pchan_mirror_act) {
1015                         arm->act_bone = pchan_mirror_act->bone;
1016
1017                         /* in weightpaint we select the associated vertex group too */
1018                         if (ob_act->mode & OB_MODE_WEIGHT_PAINT) {
1019                                 ED_vgroup_select_by_name(ob_act, pchan_mirror_act->name);
1020                                 DEG_id_tag_update(&ob_act->id, OB_RECALC_DATA);
1021                         }
1022                 }
1023
1024                 WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1025
1026                 /* need to tag armature for cow updates, or else selection doesn't update */
1027                 DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
1028         }
1029         FOREACH_OBJECT_IN_MODE_END;
1030
1031         return OPERATOR_FINISHED;
1032 }
1033
1034 void POSE_OT_select_mirror(wmOperatorType *ot)
1035 {
1036         /* identifiers */
1037         ot->name = "Flip Active/Selected Bone";
1038         ot->idname = "POSE_OT_select_mirror";
1039         ot->description = "Mirror the bone selection";
1040
1041         /* api callbacks */
1042         ot->exec = pose_select_mirror_exec;
1043         ot->poll = ED_operator_posemode;
1044
1045         /* flags */
1046         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1047
1048         /* properties */
1049         RNA_def_boolean(ot->srna, "only_active", false, "Active Only", "Only operate on the active bone");
1050         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
1051 }
1052