Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / armature / armature_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  * API's and Operators for selecting armature bones in EditMode
26  */
27
28 /** \file blender/editors/armature/armature_select.c
29  *  \ingroup edarmature
30  */
31
32 #include "DNA_armature_types.h"
33 #include "DNA_object_types.h"
34 #include "DNA_scene_types.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_math.h"
38 #include "BLI_string_utils.h"
39
40 #include "BKE_context.h"
41 //#include "BKE_deform.h"
42 #include "BKE_report.h"
43
44 #include "BIF_gl.h"
45
46 #include "RNA_access.h"
47 #include "RNA_define.h"
48
49 #include "WM_api.h"
50 #include "WM_types.h"
51
52 #include "ED_armature.h"
53 #include "ED_screen.h"
54 #include "ED_view3d.h"
55
56 #include "armature_intern.h"
57
58 /* utility macros for storing a temp int in the bone (selection flag) */
59 #define EBONE_PREV_FLAG_GET(ebone) ((void)0, (ebone)->temp.i)
60 #define EBONE_PREV_FLAG_SET(ebone, val) ((ebone)->temp.i = val)
61
62 /* **************** PoseMode & EditMode Selection Buffer Queries *************************** */
63
64 /* only for opengl selection indices */
65 Bone *get_indexed_bone(Object *ob, int index)
66 {
67         bPoseChannel *pchan;
68         if (ob->pose == NULL) return NULL;
69         index >>= 16;     // bone selection codes use left 2 bytes
70         
71         pchan = BLI_findlink(&ob->pose->chanbase, index);
72         return pchan ? pchan->bone : NULL;
73 }
74
75 /* See if there are any selected bones in this buffer */
76 /* only bones from base are checked on */
77 void *get_bone_from_selectbuffer(
78         Scene *scene, Base *base, const unsigned int *buffer, short hits,
79         bool findunsel, bool do_nearest)
80 {
81         Object *obedit = scene->obedit; // XXX get from context
82         Bone *bone;
83         EditBone *ebone;
84         void *firstunSel = NULL, *firstSel = NULL, *data;
85         unsigned int hitresult;
86         short i;
87         bool takeNext = false;
88         int minsel = 0xffffffff, minunsel = 0xffffffff;
89         
90         for (i = 0; i < hits; i++) {
91                 hitresult = buffer[3 + (i * 4)];
92                 
93                 if (!(hitresult & BONESEL_NOSEL)) {
94                         if (hitresult & BONESEL_ANY) {  /* to avoid including objects in selection */
95                                 bool sel;
96                                 
97                                 hitresult &= ~(BONESEL_ANY);
98                                 /* Determine what the current bone is */
99                                 if (obedit == NULL || base->object != obedit) {
100                                         /* no singular posemode, so check for correct object */
101                                         if (base->selcol == (hitresult & 0xFFFF)) {
102                                                 bone = get_indexed_bone(base->object, hitresult);
103                                                 
104                                                 if (findunsel)
105                                                         sel = (bone->flag & BONE_SELECTED);
106                                                 else
107                                                         sel = !(bone->flag & BONE_SELECTED);
108
109                                                 data = bone;
110                                         }
111                                         else {
112                                                 data = NULL;
113                                                 sel = 0;
114                                         }
115                                 }
116                                 else {
117                                         bArmature *arm = obedit->data;
118                                         
119                                         ebone = BLI_findlink(arm->edbo, hitresult);
120                                         if (findunsel)
121                                                 sel = (ebone->flag & BONE_SELECTED);
122                                         else
123                                                 sel = !(ebone->flag & BONE_SELECTED);
124                                         
125                                         data = ebone;
126                                 }
127                                 
128                                 if (data) {
129                                         if (sel) {
130                                                 if (do_nearest) {
131                                                         if (minsel > buffer[4 * i + 1]) {
132                                                                 firstSel = data;
133                                                                 minsel = buffer[4 * i + 1];
134                                                         }
135                                                 }
136                                                 else {
137                                                         if (!firstSel) firstSel = data;
138                                                         takeNext = 1;
139                                                 }
140                                         }
141                                         else {
142                                                 if (do_nearest) {
143                                                         if (minunsel > buffer[4 * i + 1]) {
144                                                                 firstunSel = data;
145                                                                 minunsel = buffer[4 * i + 1];
146                                                         }
147                                                 }
148                                                 else {
149                                                         if (!firstunSel) firstunSel = data;
150                                                         if (takeNext) return data;
151                                                 }
152                                         }
153                                 }
154                         }
155                 }
156         }
157         
158         if (firstunSel)
159                 return firstunSel;
160         else 
161                 return firstSel;
162 }
163
164 /* used by posemode as well editmode */
165 /* only checks scene->basact! */
166 /* x and y are mouse coords (area space) */
167 void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel)
168 {
169         ViewContext vc;
170         rcti rect;
171         unsigned int buffer[MAXPICKBUF];
172         short hits;
173         
174         view3d_set_viewcontext(C, &vc);
175         
176         // rect.xmin = ... mouseco!
177         rect.xmin = rect.xmax = xy[0];
178         rect.ymin = rect.ymax = xy[1];
179         
180         hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
181
182         if (hits > 0)
183                 return get_bone_from_selectbuffer(vc.scene, vc.sl->basact, buffer, hits, findunsel, true);
184         
185         return NULL;
186 }
187
188 /* **************** EditMode stuff ********************** */
189
190 /* called in space.c */
191 /* previously "selectconnected_armature" */
192 static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
193 {
194         bArmature *arm;
195         EditBone *bone, *curBone, *next;
196         const bool extend = RNA_boolean_get(op->ptr, "extend");
197         Object *obedit = CTX_data_edit_object(C);
198         arm = obedit->data;
199
200         view3d_operator_needs_opengl(C);
201
202         bone = get_nearest_bone(C, event->mval, !extend);
203
204         if (!bone)
205                 return OPERATOR_CANCELLED;
206
207         /* Select parents */
208         for (curBone = bone; curBone; curBone = next) {
209                 if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
210                         if (extend) {
211                                 curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
212                         }
213                         else {
214                                 curBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
215                         }
216                 }
217                 
218                 if (curBone->flag & BONE_CONNECTED)
219                         next = curBone->parent;
220                 else
221                         next = NULL;
222         }
223
224         /* Select children */
225         while (bone) {
226                 for (curBone = arm->edbo->first; curBone; curBone = next) {
227                         next = curBone->next;
228                         if ((curBone->parent == bone) && (curBone->flag & BONE_UNSELECTABLE) == 0) {
229                                 if (curBone->flag & BONE_CONNECTED) {
230                                         if (extend)
231                                                 curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
232                                         else
233                                                 curBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
234                                         bone = curBone;
235                                         break;
236                                 }
237                                 else {
238                                         bone = NULL;
239                                         break;
240                                 }
241                         }
242                 }
243                 if (!curBone)
244                         bone = NULL;
245         }
246         
247         ED_armature_sync_selection(arm->edbo);
248         
249         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
250         
251         return OPERATOR_FINISHED;
252 }
253
254 static int armature_select_linked_poll(bContext *C)
255 {
256         return (ED_operator_view3d_active(C) && ED_operator_editarmature(C));
257 }
258
259 void ARMATURE_OT_select_linked(wmOperatorType *ot)
260 {
261         /* identifiers */
262         ot->name = "Select Connected";
263         ot->idname = "ARMATURE_OT_select_linked";
264         ot->description = "Select bones related to selected ones by parent/child relationships";
265         
266         /* api callbacks */
267         /* leave 'exec' unset */
268         ot->invoke = armature_select_linked_invoke;
269         ot->poll = armature_select_linked_poll;
270         
271         /* flags */
272         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
273         
274         /* properties */
275         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
276 }
277
278 /* does bones and points */
279 /* note that BONE ROOT only gets drawn for root bones (or without IK) */
280 static EditBone *get_nearest_editbonepoint(
281         ViewContext *vc, const int mval[2],
282         ListBase *edbo, bool findunsel, int *r_selmask)
283 {
284         bArmature *arm = (bArmature *)vc->obedit->data;
285         EditBone *ebone_next_act = arm->act_edbone;
286
287         EditBone *ebone;
288         rcti rect;
289         unsigned int buffer[MAXPICKBUF];
290         unsigned int hitresult, besthitresult = BONESEL_NOSEL;
291         int i, mindep = 5;
292         short hits;
293
294         /* find the bone after the current active bone, so as to bump up its chances in selection.
295          * this way overlapping bones will cycle selection state as with objects. */
296         if (ebone_next_act &&
297             EBONE_VISIBLE(arm, ebone_next_act) &&
298             ebone_next_act->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL))
299         {
300                 ebone_next_act = ebone_next_act->next ? ebone_next_act->next : arm->edbo->first;
301         }
302         else {
303                 ebone_next_act = NULL;
304         }
305
306         BLI_rcti_init_pt_size(&rect, mval, 5);
307
308         hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, true);
309         if (hits == 0) {
310                 BLI_rcti_init_pt_size(&rect, mval, 12);
311                 hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, true);
312         }
313         /* See if there are any selected bones in this group */
314         if (hits > 0) {
315                 
316                 if (hits == 1) {
317                         if (!(buffer[3] & BONESEL_NOSEL))
318                                 besthitresult = buffer[3];
319                 }
320                 else {
321                         for (i = 0; i < hits; i++) {
322                                 hitresult = buffer[3 + (i * 4)];
323                                 if (!(hitresult & BONESEL_NOSEL)) {
324                                         int dep;
325                                         
326                                         ebone = BLI_findlink(edbo, hitresult & ~BONESEL_ANY);
327                                         
328                                         /* clicks on bone points get advantage */
329                                         if (hitresult & (BONESEL_ROOT | BONESEL_TIP)) {
330                                                 /* but also the unselected one */
331                                                 if (findunsel) {
332                                                         if ( (hitresult & BONESEL_ROOT) && (ebone->flag & BONE_ROOTSEL) == 0)
333                                                                 dep = 1;
334                                                         else if ( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL) == 0)
335                                                                 dep = 1;
336                                                         else 
337                                                                 dep = 2;
338                                                 }
339                                                 else {
340                                                         dep = 1;
341                                                 }
342                                         }
343                                         else {
344                                                 /* bone found */
345                                                 if (findunsel) {
346                                                         if ((ebone->flag & BONE_SELECTED) == 0)
347                                                                 dep = 3;
348                                                         else
349                                                                 dep = 4;
350                                                 }
351                                                 else {
352                                                         dep = 3;
353                                                 }
354                                         }
355
356                                         if (ebone == ebone_next_act) {
357                                                 dep -= 1;
358                                         }
359
360                                         if (dep < mindep) {
361                                                 mindep = dep;
362                                                 besthitresult = hitresult;
363                                         }
364                                 }
365                         }
366                 }
367                 
368                 if (!(besthitresult & BONESEL_NOSEL)) {
369                         
370                         ebone = BLI_findlink(edbo, besthitresult & ~BONESEL_ANY);
371                         
372                         *r_selmask = 0;
373                         if (besthitresult & BONESEL_ROOT)
374                                 *r_selmask |= BONE_ROOTSEL;
375                         if (besthitresult & BONESEL_TIP)
376                                 *r_selmask |= BONE_TIPSEL;
377                         if (besthitresult & BONESEL_BONE)
378                                 *r_selmask |= BONE_SELECTED;
379                         return ebone;
380                 }
381         }
382         *r_selmask = 0;
383         return NULL;
384 }
385
386 void ED_armature_deselect_all(Object *obedit)
387 {
388         bArmature *arm = obedit->data;
389         EditBone *ebone;
390
391         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
392                 ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
393         }
394 }
395
396 void ED_armature_deselect_all_visible(Object *obedit)
397 {
398         bArmature *arm = obedit->data;
399         EditBone    *ebone;
400
401         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
402                 /* first and foremost, bone must be visible and selected */
403                 if (EBONE_VISIBLE(arm, ebone)) {
404                         ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
405                 }
406         }
407
408         ED_armature_sync_selection(arm->edbo);
409 }
410
411 /* accounts for connected parents */
412 static int ebone_select_flag(EditBone *ebone)
413 {
414         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
415                 return ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0) | (ebone->flag & (BONE_SELECTED | BONE_TIPSEL));
416         }
417         else {
418                 return ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
419         }
420 }
421
422 /* context: editmode armature in view3d */
423 bool ED_armature_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
424 {
425         Object *obedit = CTX_data_edit_object(C);
426         bArmature *arm = obedit->data;
427         ViewContext vc;
428         EditBone *nearBone = NULL;
429         int selmask;
430
431         view3d_set_viewcontext(C, &vc);
432         
433         if (BIF_sk_selectStroke(C, mval, extend)) {
434                 return true;
435         }
436
437         nearBone = get_nearest_editbonepoint(&vc, mval, arm->edbo, true, &selmask);
438         if (nearBone) {
439
440                 if (!extend && !deselect && !toggle) {
441                         ED_armature_deselect_all(obedit);
442                 }
443                 
444                 /* by definition the non-root connected bones have no root point drawn,
445                  * so a root selection needs to be delivered to the parent tip */
446                 
447                 if (selmask & BONE_SELECTED) {
448                         if (nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
449                                 /* click in a chain */
450                                 if (extend) {
451                                         /* select this bone */
452                                         nearBone->flag |= BONE_TIPSEL;
453                                         nearBone->parent->flag |= BONE_TIPSEL;
454                                 }
455                                 else if (deselect) {
456                                         /* deselect this bone */
457                                         nearBone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
458                                         /* only deselect parent tip if it is not selected */
459                                         if (!(nearBone->parent->flag & BONE_SELECTED))
460                                                 nearBone->parent->flag &= ~BONE_TIPSEL;
461                                 }
462                                 else if (toggle) {
463                                         /* hold shift inverts this bone's selection */
464                                         if (nearBone->flag & BONE_SELECTED) {
465                                                 /* deselect this bone */
466                                                 nearBone->flag &= ~(BONE_TIPSEL | BONE_SELECTED);
467                                                 /* only deselect parent tip if it is not selected */
468                                                 if (!(nearBone->parent->flag & BONE_SELECTED))
469                                                         nearBone->parent->flag &= ~BONE_TIPSEL;
470                                         }
471                                         else {
472                                                 /* select this bone */
473                                                 nearBone->flag |= BONE_TIPSEL;
474                                                 nearBone->parent->flag |= BONE_TIPSEL;
475                                         }
476                                 }
477                                 else {
478                                         /* select this bone */
479                                         nearBone->flag |= BONE_TIPSEL;
480                                         nearBone->parent->flag |= BONE_TIPSEL;
481                                 }
482                         }
483                         else {
484                                 if (extend) {
485                                         nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
486                                 }
487                                 else if (deselect) {
488                                         nearBone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
489                                 }
490                                 else if (toggle) {
491                                         /* hold shift inverts this bone's selection */
492                                         if (nearBone->flag & BONE_SELECTED)
493                                                 nearBone->flag &= ~(BONE_TIPSEL | BONE_ROOTSEL);
494                                         else
495                                                 nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
496                                 }
497                                 else
498                                         nearBone->flag |= (BONE_TIPSEL | BONE_ROOTSEL);
499                         }
500                 }
501                 else {
502                         if (extend)
503                                 nearBone->flag |= selmask;
504                         else if (deselect)
505                                 nearBone->flag &= ~selmask;
506                         else if (toggle && (nearBone->flag & selmask))
507                                 nearBone->flag &= ~selmask;
508                         else
509                                 nearBone->flag |= selmask;
510                 }
511                 
512                 ED_armature_sync_selection(arm->edbo);
513                 
514                 if (nearBone) {
515                         /* then now check for active status */
516                         if (ebone_select_flag(nearBone)) {
517                                 arm->act_edbone = nearBone;
518                         }
519                 }
520                 
521                 WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
522                 return true;
523         }
524
525         return false;
526 }
527
528
529 /* ****************  Selections  ******************/
530
531 static int armature_de_select_all_exec(bContext *C, wmOperator *op)
532 {
533         int action = RNA_enum_get(op->ptr, "action");
534
535         if (action == SEL_TOGGLE) {
536                 /* Determine if there are any selected bones
537                  * And therefore whether we are selecting or deselecting */
538                 action = SEL_SELECT;
539                 CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones)
540                 {
541                         if (ebone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) {
542                                 action = SEL_DESELECT;
543                                 break;
544                         }
545                 }
546                 CTX_DATA_END;
547         }
548         
549         /*      Set the flags */
550         CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones)
551         {
552                 /* ignore bone if selection can't change */
553                 switch (action) {
554                         case SEL_SELECT:
555                                 if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
556                                         ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
557                                         if (ebone->parent) {
558                                                 ebone->parent->flag |= (BONE_TIPSEL);
559                                         }
560                                 }
561                                 break;
562                         case SEL_DESELECT:
563                                 ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
564                                 break;
565                         case SEL_INVERT:
566                                 if (ebone->flag & BONE_SELECTED) {
567                                         ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
568                                 }
569                                 else {
570                                         if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
571                                                 ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
572                                                 if (ebone->parent) {
573                                                         ebone->parent->flag |= (BONE_TIPSEL);
574                                                 }
575                                         }
576                                 }
577                                 break;
578                 }
579         }
580         CTX_DATA_END;
581
582         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, NULL);
583         
584         return OPERATOR_FINISHED;
585 }
586
587 void ARMATURE_OT_select_all(wmOperatorType *ot)
588 {
589         /* identifiers */
590         ot->name = "(De)select All";
591         ot->idname = "ARMATURE_OT_select_all";
592         ot->description = "Toggle selection status of all bones";
593         
594         /* api callbacks */
595         ot->exec = armature_de_select_all_exec;
596         ot->poll = ED_operator_editarmature;
597         
598         /* flags */
599         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
600         
601         WM_operator_properties_select_all(ot);
602 }
603
604 /**************** Select more/less **************/
605
606 static void armature_select_more(bArmature *arm, EditBone *ebone)
607 {
608         if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != 0) {
609                 if (EBONE_SELECTABLE(arm, ebone)) {
610                         ED_armature_ebone_select_set(ebone, true);
611                 }
612         }
613
614         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
615                 /* to parent */
616                 if ((EBONE_PREV_FLAG_GET(ebone) & BONE_ROOTSEL) != 0) {
617                         if (EBONE_SELECTABLE(arm, ebone->parent)) {
618                                 ED_armature_ebone_selectflag_enable(ebone->parent, (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL));
619                         }
620                 }
621
622                 /* from parent (difference from select less) */
623                 if ((EBONE_PREV_FLAG_GET(ebone->parent) & BONE_TIPSEL) != 0) {
624                         if (EBONE_SELECTABLE(arm, ebone)) {
625                                 ED_armature_ebone_selectflag_enable(ebone, (BONE_SELECTED | BONE_ROOTSEL));
626                         }
627                 }
628         }
629 }
630
631 static void armature_select_less(bArmature *UNUSED(arm), EditBone *ebone)
632 {
633         if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != (BONE_ROOTSEL | BONE_TIPSEL)) {
634                 ED_armature_ebone_select_set(ebone, false);
635         }
636
637         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
638                 /* to parent */
639                 if ((EBONE_PREV_FLAG_GET(ebone) & BONE_SELECTED) == 0) {
640                         ED_armature_ebone_selectflag_disable(ebone->parent, (BONE_SELECTED | BONE_TIPSEL));
641                 }
642
643                 /* from parent (difference from select more) */
644                 if ((EBONE_PREV_FLAG_GET(ebone->parent) & BONE_SELECTED) == 0) {
645                         ED_armature_ebone_selectflag_disable(ebone, (BONE_SELECTED | BONE_ROOTSEL));
646                 }
647         }
648 }
649
650 static void armature_select_more_less(Object *ob, bool more)
651 {
652         bArmature *arm = (bArmature *)ob->data;
653         EditBone *ebone;
654
655         /* XXX, eventually we shouldn't need this - campbell */
656         ED_armature_sync_selection(arm->edbo);
657
658         /* count bones & store selection state */
659         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
660                 EBONE_PREV_FLAG_SET(ebone, ED_armature_ebone_selectflag_get(ebone));
661         }
662
663         /* do selection */
664         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
665                 if (EBONE_VISIBLE(arm, ebone)) {
666                         if (more) {
667                                 armature_select_more(arm, ebone);
668                         }
669                         else {
670                                 armature_select_less(arm, ebone);
671                         }
672                 }
673         }
674
675         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
676                 if (EBONE_VISIBLE(arm, ebone)) {
677                         if (more == false) {
678                                 if (ebone->flag & BONE_SELECTED) {
679                                         ED_armature_ebone_select_set(ebone, true);
680                                 }
681                         }
682                 }
683                 ebone->temp.p = NULL;
684         }
685
686         ED_armature_sync_selection(arm->edbo);
687 }
688
689 static int armature_de_select_more_exec(bContext *C, wmOperator *UNUSED(op))
690 {
691         Object *obedit = CTX_data_edit_object(C);
692         armature_select_more_less(obedit, true);
693         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
694
695         return OPERATOR_FINISHED;
696 }
697
698 void ARMATURE_OT_select_more(wmOperatorType *ot)
699 {
700         /* identifiers */
701         ot->name = "Select More";
702         ot->idname = "ARMATURE_OT_select_more";
703         ot->description = "Select those bones connected to the initial selection";
704
705         /* api callbacks */
706         ot->exec = armature_de_select_more_exec;
707         ot->poll = ED_operator_editarmature;
708
709         /* flags */
710         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
711 }
712
713 static int armature_de_select_less_exec(bContext *C, wmOperator *UNUSED(op))
714 {
715         Object *obedit = CTX_data_edit_object(C);
716         armature_select_more_less(obedit, false);
717         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
718
719         return OPERATOR_FINISHED;
720 }
721
722 void ARMATURE_OT_select_less(wmOperatorType *ot)
723 {
724         /* identifiers */
725         ot->name = "Select Less";
726         ot->idname = "ARMATURE_OT_select_less";
727         ot->description = "Deselect those bones at the boundary of each selection region";
728
729         /* api callbacks */
730         ot->exec = armature_de_select_less_exec;
731         ot->poll = ED_operator_editarmature;
732
733         /* flags */
734         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
735 }
736
737 enum {
738         SIMEDBONE_CHILDREN = 1,
739         SIMEDBONE_CHILDREN_IMMEDIATE,
740         SIMEDBONE_SIBLINGS,
741         SIMEDBONE_LENGTH,
742         SIMEDBONE_DIRECTION,
743         SIMEDBONE_PREFIX,
744         SIMEDBONE_SUFFIX,
745         SIMEDBONE_LAYER,
746 };
747
748 static EnumPropertyItem prop_similar_types[] = {
749         {SIMEDBONE_CHILDREN, "CHILDREN", 0, "Children", ""},
750         {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate children", ""},
751         {SIMEDBONE_SIBLINGS, "SIBLINGS", 0, "Siblings", ""},
752         {SIMEDBONE_LENGTH, "LENGTH", 0, "Length", ""},
753         {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y axis)", ""},
754         {SIMEDBONE_PREFIX, "PREFIX", 0, "Prefix", ""},
755         {SIMEDBONE_SUFFIX, "SUFFIX", 0, "Suffix", ""},
756         {SIMEDBONE_LAYER, "LAYER", 0, "Layer", ""},
757         {0, NULL, 0, NULL, NULL}
758 };
759
760
761 static void select_similar_length(bArmature *arm, EditBone *ebone_act, const float thresh)
762 {
763         EditBone *ebone;
764
765         /* thresh is always relative to current length */
766         const float len_min = ebone_act->length / (1.0f + thresh);
767         const float len_max = ebone_act->length * (1.0f + thresh);
768
769         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
770                 if (EBONE_SELECTABLE(arm, ebone)) {
771                         if ((ebone->length >= len_min) &&
772                             (ebone->length <= len_max))
773                         {
774                                 ED_armature_ebone_select_set(ebone, true);
775                         }
776                 }
777         }
778 }
779
780 static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const float thresh)
781 {
782         EditBone *ebone;
783         float dir_act[3];
784         sub_v3_v3v3(dir_act, ebone_act->head, ebone_act->tail);
785
786         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
787                 if (EBONE_SELECTABLE(arm, ebone)) {
788                         float dir[3];
789                         sub_v3_v3v3(dir, ebone->head, ebone->tail);
790
791                         if (angle_v3v3(dir_act, dir) / (float)M_PI < thresh) {
792                                 ED_armature_ebone_select_set(ebone, true);
793                         }
794                 }
795         }
796 }
797
798 static void select_similar_layer(bArmature *arm, EditBone *ebone_act)
799 {
800         EditBone *ebone;
801
802         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
803                 if (EBONE_SELECTABLE(arm, ebone)) {
804                         if (ebone->layer & ebone_act->layer) {
805                                 ED_armature_ebone_select_set(ebone, true);
806                         }
807                 }
808         }
809 }
810
811 static void select_similar_prefix(bArmature *arm, EditBone *ebone_act)
812 {
813         EditBone *ebone;
814
815         char body_tmp[MAXBONENAME];
816         char prefix_act[MAXBONENAME];
817
818         BLI_string_split_prefix(ebone_act->name, prefix_act, body_tmp, sizeof(ebone_act->name));
819
820         if (prefix_act[0] == '\0')
821                 return;
822
823         /* Find matches */
824         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
825                 if (EBONE_SELECTABLE(arm, ebone)) {
826                         char prefix_other[MAXBONENAME];
827                         BLI_string_split_prefix(ebone->name, prefix_other, body_tmp, sizeof(ebone->name));
828                         if (STREQ(prefix_act, prefix_other)) {
829                                 ED_armature_ebone_select_set(ebone, true);
830                         }
831                 }
832         }
833 }
834
835 static void select_similar_suffix(bArmature *arm, EditBone *ebone_act)
836 {
837         EditBone *ebone;
838
839         char body_tmp[MAXBONENAME];
840         char suffix_act[MAXBONENAME];
841
842         BLI_string_split_suffix(ebone_act->name, body_tmp, suffix_act, sizeof(ebone_act->name));
843
844         if (suffix_act[0] == '\0')
845                 return;
846
847         /* Find matches */
848         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
849                 if (EBONE_SELECTABLE(arm, ebone)) {
850                         char suffix_other[MAXBONENAME];
851                         BLI_string_split_suffix(ebone->name, body_tmp, suffix_other, sizeof(ebone->name));
852                         if (STREQ(suffix_act, suffix_other)) {
853                                 ED_armature_ebone_select_set(ebone, true);
854                         }
855                 }
856         }
857 }
858
859 static void is_ancestor(EditBone * bone, EditBone * ancestor)
860 {
861         if (bone->temp.ebone == ancestor || bone->temp.ebone == NULL)
862                 return;
863
864         if (bone->temp.ebone->temp.ebone != NULL && bone->temp.ebone->temp.ebone != ancestor)
865                 is_ancestor(bone->temp.ebone, ancestor);
866
867         bone->temp.ebone = bone->temp.ebone->temp.ebone;
868 }
869
870 static void select_similar_children(bArmature *arm, EditBone *ebone_act)
871 {
872         EditBone *ebone_iter;
873
874         for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
875                 ebone_iter->temp.ebone = ebone_iter->parent;
876         }
877
878         for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
879                 is_ancestor(ebone_iter, ebone_act);
880
881                 if (ebone_iter->temp.ebone == ebone_act && EBONE_SELECTABLE(arm, ebone_iter))
882                         ED_armature_ebone_select_set(ebone_iter, true);
883         }
884 }
885
886 static void select_similar_children_immediate(bArmature *arm, EditBone *ebone_act)
887 {
888         EditBone *ebone_iter;
889         for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
890                 if (ebone_iter->parent == ebone_act && EBONE_SELECTABLE(arm, ebone_iter)) {
891                         ED_armature_ebone_select_set(ebone_iter, true);
892                 }
893         }
894 }
895
896 static void select_similar_siblings(bArmature *arm, EditBone *ebone_act)
897 {
898         EditBone *ebone_iter;
899
900         if (ebone_act->parent == NULL)
901                 return;
902
903         for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
904                 if (ebone_iter->parent == ebone_act->parent && EBONE_SELECTABLE(arm, ebone_iter)) {
905                         ED_armature_ebone_select_set(ebone_iter, true);
906                 }
907         }
908 }
909
910 static int armature_select_similar_exec(bContext *C, wmOperator *op)
911 {
912         Object *obedit = CTX_data_edit_object(C);
913         bArmature *arm = obedit->data;
914         EditBone *ebone_act = CTX_data_active_bone(C);
915
916         /* Get props */
917         int type = RNA_enum_get(op->ptr, "type");
918         float thresh = RNA_float_get(op->ptr, "threshold");
919
920         /* Check for active bone */
921         if (ebone_act == NULL) {
922                 BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
923                 return OPERATOR_CANCELLED;
924         }
925
926         switch (type) {
927                 case SIMEDBONE_CHILDREN:
928                         select_similar_children(arm, ebone_act);
929                         break;
930                 case SIMEDBONE_CHILDREN_IMMEDIATE:
931                         select_similar_children_immediate(arm, ebone_act);
932                         break;
933                 case SIMEDBONE_SIBLINGS:
934                         select_similar_siblings(arm, ebone_act);
935                         break;
936                 case SIMEDBONE_LENGTH:
937                         select_similar_length(arm, ebone_act, thresh);
938                         break;
939                 case SIMEDBONE_DIRECTION:
940                         select_similar_direction(arm, ebone_act, thresh);
941                         break;
942                 case SIMEDBONE_PREFIX:
943                         select_similar_prefix(arm, ebone_act);
944                         break;
945                 case SIMEDBONE_SUFFIX:
946                         select_similar_suffix(arm, ebone_act);
947                         break;
948                 case SIMEDBONE_LAYER:
949                         select_similar_layer(arm, ebone_act);
950                         break;
951         }
952
953         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
954
955         return OPERATOR_FINISHED;
956 }
957
958 void ARMATURE_OT_select_similar(wmOperatorType *ot)
959 {
960         /* identifiers */
961         ot->name = "Select Similar";
962         ot->idname = "ARMATURE_OT_select_similar";
963
964         /* callback functions */
965         ot->invoke = WM_menu_invoke;
966         ot->exec = armature_select_similar_exec;
967         ot->poll = ED_operator_editarmature;
968         ot->description = "Select similar bones by property types";
969
970         /* flags */
971         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
972
973         /* properties */
974         ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, SIMEDBONE_LENGTH, "Type", "");
975         RNA_def_float(ot->srna, "threshold", 0.1f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f);
976 }
977
978 /* ********************* select hierarchy operator ************** */
979
980 static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
981 {
982         Object *obedit = CTX_data_edit_object(C);
983         Object *ob;
984         bArmature *arm;
985         EditBone *ebone_active;
986         int direction = RNA_enum_get(op->ptr, "direction");
987         const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
988         bool changed = false;
989         
990         ob = obedit;
991         arm = (bArmature *)ob->data;
992
993         ebone_active = arm->act_edbone;
994         if (ebone_active == NULL) {
995                 return OPERATOR_CANCELLED;
996         }
997
998         if (direction == BONE_SELECT_PARENT) {
999                 if (ebone_active->parent) {
1000                         EditBone *ebone_parent;
1001
1002                         ebone_parent = ebone_active->parent;
1003
1004                         if (EBONE_SELECTABLE(arm, ebone_parent)) {
1005                                 arm->act_edbone = ebone_parent;
1006
1007                                 if (!add_to_sel) {
1008                                         ED_armature_ebone_select_set(ebone_active, false);
1009                                 }
1010                                 ED_armature_ebone_select_set(ebone_parent, true);
1011
1012                                 changed = true;
1013                         }
1014                 }
1015
1016         }
1017         else {  /* BONE_SELECT_CHILD */
1018                 EditBone *ebone_iter, *ebone_child = NULL;
1019                 int pass;
1020
1021                 /* first pass, only connected bones (the logical direct child) */
1022                 for (pass = 0; pass < 2 && (ebone_child == NULL); pass++) {
1023                         for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
1024                                 /* possible we have multiple children, some invisible */
1025                                 if (EBONE_SELECTABLE(arm, ebone_iter)) {
1026                                         if (ebone_iter->parent == ebone_active) {
1027                                                 if ((pass == 1) || (ebone_iter->flag & BONE_CONNECTED)) {
1028                                                         ebone_child = ebone_iter;
1029                                                         break;
1030                                                 }
1031                                         }
1032                                 }
1033                         }
1034                 }
1035
1036                 if (ebone_child) {
1037                         arm->act_edbone = ebone_child;
1038
1039                         if (!add_to_sel) {
1040                                 ED_armature_ebone_select_set(ebone_active, false);
1041                         }
1042                         ED_armature_ebone_select_set(ebone_child, true);
1043
1044                         changed = true;
1045                 }
1046         }
1047         
1048         if (changed == false) {
1049                 return OPERATOR_CANCELLED;
1050         }
1051
1052         ED_armature_sync_selection(arm->edbo);
1053         
1054         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1055         
1056         return OPERATOR_FINISHED;
1057 }
1058
1059 void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
1060 {
1061         static EnumPropertyItem direction_items[] = {
1062                 {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
1063                 {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
1064                 {0, NULL, 0, NULL, NULL}
1065         };
1066         
1067         /* identifiers */
1068         ot->name = "Select Hierarchy";
1069         ot->idname = "ARMATURE_OT_select_hierarchy";
1070         ot->description = "Select immediate parent/children of selected bones";
1071         
1072         /* api callbacks */
1073         ot->exec = armature_select_hierarchy_exec;
1074         ot->poll = ED_operator_editarmature;
1075         
1076         /* flags */
1077         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1078
1079         /* props */
1080         RNA_def_enum(ot->srna, "direction", direction_items,
1081                      BONE_SELECT_PARENT, "Direction", "");
1082         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
1083 }
1084
1085 /****************** Mirror Select ****************/
1086
1087 /**
1088  * \note clone of #pose_select_mirror_exec keep in sync
1089  */
1090 static int armature_select_mirror_exec(bContext *C, wmOperator *op)
1091 {
1092         Object *obedit = CTX_data_edit_object(C);
1093         bArmature *arm = obedit->data;
1094         EditBone *ebone, *ebone_mirror_act = NULL;
1095         const bool active_only = RNA_boolean_get(op->ptr, "only_active");
1096         const bool extend = RNA_boolean_get(op->ptr, "extend");
1097
1098         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1099                 const int flag = ED_armature_ebone_selectflag_get(ebone);
1100                 EBONE_PREV_FLAG_SET(ebone, flag);
1101         }
1102
1103         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1104                 if (EBONE_SELECTABLE(arm, ebone)) {
1105                         EditBone *ebone_mirror;
1106                         int flag_new = extend ? EBONE_PREV_FLAG_GET(ebone) : 0;
1107
1108                         if ((ebone_mirror = ED_armature_bone_get_mirrored(arm->edbo, ebone)) &&
1109                             (EBONE_VISIBLE(arm, ebone_mirror)))
1110                         {
1111                                 const int flag_mirror = EBONE_PREV_FLAG_GET(ebone_mirror);
1112                                 flag_new |= flag_mirror;
1113
1114                                 if (ebone == arm->act_edbone) {
1115                                         ebone_mirror_act = ebone_mirror;
1116                                 }
1117
1118                                 /* skip all but the active or its mirror */
1119                                 if (active_only && !ELEM(arm->act_edbone, ebone, ebone_mirror)) {
1120                                         continue;
1121                                 }
1122                         }
1123
1124                         ED_armature_ebone_selectflag_set(ebone, flag_new);
1125                 }
1126         }
1127
1128         if (ebone_mirror_act) {
1129                 arm->act_edbone = ebone_mirror_act;
1130         }
1131
1132         ED_armature_sync_selection(arm->edbo);
1133
1134         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1135
1136         return OPERATOR_FINISHED;
1137 }
1138
1139 void ARMATURE_OT_select_mirror(wmOperatorType *ot)
1140 {
1141         /* identifiers */
1142         ot->name = "Flip Active/Selected Bone";
1143         ot->idname = "ARMATURE_OT_select_mirror";
1144         ot->description = "Mirror the bone selection";
1145
1146         /* api callbacks */
1147         ot->exec = armature_select_mirror_exec;
1148         ot->poll = ED_operator_editarmature;
1149
1150         /* flags */
1151         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1152
1153         /* properties */
1154         RNA_def_boolean(ot->srna, "only_active", false, "Active Only", "Only operate on the active bone");
1155         RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
1156 }
1157
1158
1159 /****************** Select Path ****************/
1160
1161 static bool armature_shortest_path_select(bArmature *arm, EditBone *ebone_parent, EditBone *ebone_child,
1162                                           bool use_parent, bool is_test)
1163 {
1164         do {
1165
1166                 if (!use_parent && (ebone_child == ebone_parent))
1167                         break;
1168
1169                 if (is_test) {
1170                         if (!EBONE_SELECTABLE(arm, ebone_child)) {
1171                                 return false;
1172                         }
1173                 }
1174                 else {
1175                         ED_armature_ebone_selectflag_set(ebone_child, (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL));
1176                 }
1177
1178                 if (ebone_child == ebone_parent)
1179                         break;
1180
1181                 ebone_child = ebone_child->parent;
1182         } while (true);
1183
1184         return true;
1185 }
1186
1187 static int armature_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1188 {
1189         Object *obedit = CTX_data_edit_object(C);
1190         bArmature *arm = obedit->data;
1191         EditBone *ebone_src, *ebone_dst;
1192         EditBone *ebone_isect_parent = NULL;
1193         EditBone *ebone_isect_child[2];
1194         bool changed;
1195
1196         view3d_operator_needs_opengl(C);
1197
1198         ebone_src = arm->act_edbone;
1199         ebone_dst = get_nearest_bone(C, event->mval, false);
1200
1201         /* fallback to object selection */
1202         if (ELEM(NULL, ebone_src, ebone_dst) || (ebone_src == ebone_dst)) {
1203                 return OPERATOR_PASS_THROUGH;
1204         }
1205
1206         ebone_isect_child[0] = ebone_src;
1207         ebone_isect_child[1] = ebone_dst;
1208
1209
1210         /* ensure 'ebone_src' is the parent of 'ebone_dst', or set 'ebone_isect_parent' */
1211         if (ED_armature_ebone_is_child_recursive(ebone_src, ebone_dst)) {
1212                 /* pass */
1213         }
1214         else if (ED_armature_ebone_is_child_recursive(ebone_dst, ebone_src)) {
1215                 SWAP(EditBone *, ebone_src, ebone_dst);
1216         }
1217         else if ((ebone_isect_parent = ED_armature_bone_find_shared_parent(ebone_isect_child, 2))) {
1218                 /* pass */
1219         }
1220         else {
1221                 /* disconnected bones */
1222                 return OPERATOR_CANCELLED;
1223         }
1224
1225
1226         if (ebone_isect_parent) {
1227                 if (armature_shortest_path_select(arm, ebone_isect_parent, ebone_src, false, true) &&
1228                     armature_shortest_path_select(arm, ebone_isect_parent, ebone_dst, false, true))
1229                 {
1230                         armature_shortest_path_select(arm, ebone_isect_parent, ebone_src, false, false);
1231                         armature_shortest_path_select(arm, ebone_isect_parent, ebone_dst, false, false);
1232                         changed = true;
1233                 }
1234                 else {
1235                         /* unselectable */
1236                         changed = false;
1237                 }
1238         }
1239         else {
1240                 if (armature_shortest_path_select(arm, ebone_src, ebone_dst, true, true)) {
1241                         armature_shortest_path_select(arm, ebone_src, ebone_dst, true, false);
1242                         changed = true;
1243                 }
1244                 else {
1245                         /* unselectable */
1246                         changed = false;
1247                 }
1248         }
1249
1250         if (changed) {
1251                 arm->act_edbone = ebone_dst;
1252                 ED_armature_sync_selection(arm->edbo);
1253                 WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1254
1255                 return OPERATOR_FINISHED;
1256         }
1257         else {
1258                 BKE_report(op->reports, RPT_WARNING, "Unselectable bone in chain");
1259                 return OPERATOR_CANCELLED;
1260         }
1261 }
1262
1263 void ARMATURE_OT_shortest_path_pick(wmOperatorType *ot)
1264 {
1265         /* identifiers */
1266         ot->name = "Pick Shortest Path";
1267         ot->idname = "ARMATURE_OT_shortest_path_pick";
1268         ot->description = "Select shortest path between two bones";
1269
1270         /* api callbacks */
1271         ot->invoke = armature_shortest_path_pick_invoke;
1272         ot->poll = ED_operator_editarmature;
1273
1274         /* flags */
1275         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1276 }