Option not to select with un-hide
[blender.git] / source / blender / editors / armature / armature_edit.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  * Armature EditMode tools - transforms, chain based editing, and other settings
26  */
27
28 /** \file blender/editors/armature/armature_edit.c
29  *  \ingroup edarmature
30  */
31
32 #include <assert.h> 
33
34 #include "DNA_armature_types.h"
35 #include "DNA_constraint_types.h"
36 #include "DNA_object_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLT_translation.h"
42
43 #include "BLI_blenlib.h"
44 #include "BLI_math.h"
45 #include "BLI_ghash.h"
46
47 #include "BKE_action.h"
48 #include "BKE_armature.h"
49 #include "BKE_constraint.h"
50 #include "BKE_context.h"
51 #include "BKE_global.h"
52 #include "BKE_report.h"
53
54 #include "RNA_access.h"
55 #include "RNA_define.h"
56
57 #include "WM_api.h"
58 #include "WM_types.h"
59
60 #include "ED_armature.h"
61 #include "ED_screen.h"
62 #include "ED_view3d.h"
63
64 #include "armature_intern.h"
65
66 /* ************************** Object Tools Exports ******************************* */
67 /* NOTE: these functions are exported to the Object module to be called from the tools there */
68
69 void ED_armature_apply_transform(Object *ob, float mat[4][4], const bool do_props)
70 {
71         bArmature *arm = ob->data;
72
73         /* Put the armature into editmode */
74         ED_armature_to_edit(arm);
75
76         /* Transform the bones */
77         ED_armature_transform_bones(arm, mat, do_props);
78
79         /* Turn the list into an armature */
80         ED_armature_from_edit(arm);
81         ED_armature_edit_free(arm);
82 }
83
84 void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props)
85 {
86         EditBone *ebone;
87         float scale = mat4_to_scale(mat);   /* store the scale of the matrix here to use on envelopes */
88         float mat3[3][3];
89
90         copy_m3_m4(mat3, mat);
91         normalize_m3(mat3);
92         /* Do the rotations */
93         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
94                 float tmat[3][3];
95                 
96                 /* find the current bone's roll matrix */
97                 ED_armature_ebone_to_mat3(ebone, tmat);
98                 
99                 /* transform the roll matrix */
100                 mul_m3_m3m3(tmat, mat3, tmat);
101                 
102                 /* transform the bone */
103                 mul_m4_v3(mat, ebone->head);
104                 mul_m4_v3(mat, ebone->tail);
105
106                 /* apply the transformed roll back */
107                 mat3_to_vec_roll(tmat, NULL, &ebone->roll);
108                 
109                 if (do_props) {
110                         ebone->rad_head *= scale;
111                         ebone->rad_tail *= scale;
112                         ebone->dist     *= scale;
113
114                         /* we could be smarter and scale by the matrix along the x & z axis */
115                         ebone->xwidth   *= scale;
116                         ebone->zwidth   *= scale;
117                 }
118         }
119 }
120
121 void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props)
122 {
123         if (arm->edbo) {
124                 ED_armature_transform_bones(arm, mat, do_props);
125         }
126         else {
127                 /* Put the armature into editmode */
128                 ED_armature_to_edit(arm);
129
130                 /* Transform the bones */
131                 ED_armature_transform_bones(arm, mat, do_props);
132
133                 /* Go back to object mode*/
134                 ED_armature_from_edit(arm);
135                 ED_armature_edit_free(arm);
136         }
137 }
138
139 /* exported for use in editors/object/ */
140 /* 0 == do center, 1 == center new, 2 == center cursor */
141 void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int centermode, int around)
142 {
143         Object *obedit = scene->obedit; // XXX get from context
144         EditBone *ebone;
145         bArmature *arm = ob->data;
146         float cent[3];
147
148         /* Put the armature into editmode */
149         if (ob != obedit) {
150                 ED_armature_to_edit(arm);
151                 obedit = NULL; /* we cant use this so behave as if there is no obedit */
152         }
153
154         /* Find the centerpoint */
155         if (centermode == 2) {
156                 copy_v3_v3(cent, cursor);
157                 invert_m4_m4(ob->imat, ob->obmat);
158                 mul_m4_v3(ob->imat, cent);
159         }
160         else {
161                 if (around == V3D_AROUND_CENTER_MEAN) {
162                         int total = 0;
163                         zero_v3(cent);
164                         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
165                                 total += 2;
166                                 add_v3_v3(cent, ebone->head);
167                                 add_v3_v3(cent, ebone->tail);
168                         }
169                         if (total) {
170                                 mul_v3_fl(cent, 1.0f / (float)total);
171                         }
172                 }
173                 else {
174                         float min[3], max[3];
175                         INIT_MINMAX(min, max);
176                         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
177                                 minmax_v3v3_v3(min, max, ebone->head);
178                                 minmax_v3v3_v3(min, max, ebone->tail);
179                         }
180                         mid_v3_v3v3(cent, min, max);
181                 }
182         }
183         
184         /* Do the adjustments */
185         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
186                 sub_v3_v3(ebone->head, cent);
187                 sub_v3_v3(ebone->tail, cent);
188         }
189         
190         /* Turn the list into an armature */
191         if (obedit == NULL) {
192                 ED_armature_from_edit(arm);
193                 ED_armature_edit_free(arm);
194         }
195
196         /* Adjust object location for new centerpoint */
197         if (centermode && obedit == NULL) {
198                 mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */
199                 add_v3_v3(ob->loc, cent);
200         }
201 }
202
203 /* ********************************* Roll ******************************* */
204
205 /* adjust bone roll to align Z axis with vector
206  * vec is in local space and is normalized
207  */
208 float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const bool axis_only)
209 {
210         float mat[3][3], nor[3];
211         float vec[3], align_axis_proj[3], roll = 0.0f;
212
213         BLI_ASSERT_UNIT_V3(align_axis);
214
215         sub_v3_v3v3(nor, bone->tail, bone->head);
216
217         /* If tail == head or the bone is aligned with the axis... */
218         if (normalize_v3(nor) <= FLT_EPSILON || (fabsf(dot_v3v3(align_axis, nor)) >= (1.0f - FLT_EPSILON))) {
219                 return roll;
220         }
221
222         vec_roll_to_mat3_normalized(nor, 0.0f, mat);
223
224         /* project the new_up_axis along the normal */
225         project_v3_v3v3_normalized(vec, align_axis, nor);
226         sub_v3_v3v3(align_axis_proj, align_axis, vec);
227
228         if (axis_only) {
229                 if (angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI_2)) {
230                         negate_v3(align_axis_proj);
231                 }
232         }
233
234         roll = angle_v3v3(align_axis_proj, mat[2]);
235
236         cross_v3_v3v3(vec, mat[2], align_axis_proj);
237
238         if (dot_v3v3(vec, nor) < 0.0f) {
239                 return -roll;
240         }
241         return roll;
242 }
243
244 /* note, ranges arithmatic is used below */
245 typedef enum eCalcRollTypes {
246         /* pos */
247         CALC_ROLL_POS_X = 0,
248         CALC_ROLL_POS_Y,
249         CALC_ROLL_POS_Z,
250
251         CALC_ROLL_TAN_POS_X,
252         CALC_ROLL_TAN_POS_Z,
253
254         /* neg */
255         CALC_ROLL_NEG_X,
256         CALC_ROLL_NEG_Y,
257         CALC_ROLL_NEG_Z,
258
259         CALC_ROLL_TAN_NEG_X,
260         CALC_ROLL_TAN_NEG_Z,
261
262         /* no sign */
263         CALC_ROLL_ACTIVE,
264         CALC_ROLL_VIEW,
265         CALC_ROLL_CURSOR,
266 } eCalcRollTypes;
267
268 static const EnumPropertyItem prop_calc_roll_types[] = {
269         {0, "", 0, N_("Positive"), ""},
270         {CALC_ROLL_TAN_POS_X, "POS_X", 0, "Local +X Tangent", ""},
271         {CALC_ROLL_TAN_POS_Z, "POS_Z", 0, "Local +Z Tangent", ""},
272
273         {CALC_ROLL_POS_X, "GLOBAL_POS_X", 0, "Global +X Axis", ""},
274         {CALC_ROLL_POS_Y, "GLOBAL_POS_Y", 0, "Global +Y Axis", ""},
275         {CALC_ROLL_POS_Z, "GLOBAL_POS_Z", 0, "Global +Z Axis", ""},
276
277         {0, "", 0, N_("Negative"), ""},
278
279         {CALC_ROLL_TAN_NEG_X, "NEG_X", 0, "Local -X Tangent", ""},
280         {CALC_ROLL_TAN_NEG_Z, "NEG_Z", 0, "Local -Z Tangent", ""},
281
282         {CALC_ROLL_NEG_X, "GLOBAL_NEG_X", 0, "Global -X Axis", ""},
283         {CALC_ROLL_NEG_Y, "GLOBAL_NEG_Y", 0, "Global -Y Axis", ""},
284         {CALC_ROLL_NEG_Z, "GLOBAL_NEG_Z", 0, "Global -Z Axis", ""},
285
286         {0, "", 0, N_("Other"), ""},
287         {CALC_ROLL_ACTIVE, "ACTIVE", 0, "Active Bone", ""},
288         {CALC_ROLL_VIEW, "VIEW", 0, "View Axis", ""},
289         {CALC_ROLL_CURSOR, "CURSOR", 0, "Cursor", ""},
290         {0, NULL, 0, NULL, NULL}
291 };
292
293
294 static int armature_calc_roll_exec(bContext *C, wmOperator *op) 
295 {
296         Object *ob = CTX_data_edit_object(C);
297         eCalcRollTypes type = RNA_enum_get(op->ptr, "type");
298         const bool axis_only = RNA_boolean_get(op->ptr, "axis_only");
299         /* axis_flip when matching the active bone never makes sense */
300         bool axis_flip = ((type >= CALC_ROLL_ACTIVE) ? RNA_boolean_get(op->ptr, "axis_flip") :
301                           (type >= CALC_ROLL_TAN_NEG_X) ? true : false);
302
303         float imat[3][3];
304
305         bArmature *arm = ob->data;
306         EditBone *ebone;
307
308         if ((type >= CALC_ROLL_NEG_X) && (type <= CALC_ROLL_TAN_NEG_Z)) {
309                 type -= (CALC_ROLL_ACTIVE - CALC_ROLL_NEG_X);
310                 axis_flip = true;
311         }
312
313         copy_m3_m4(imat, ob->obmat);
314         invert_m3(imat);
315
316         if (type == CALC_ROLL_CURSOR) { /* Cursor */
317                 Scene *scene = CTX_data_scene(C);
318                 View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
319                 float cursor_local[3];
320                 const float   *cursor = ED_view3d_cursor3d_get(scene, v3d);
321                 
322                 invert_m4_m4(ob->imat, ob->obmat);
323                 copy_v3_v3(cursor_local, cursor);
324                 mul_m4_v3(ob->imat, cursor_local);
325
326                 
327                 /* cursor */
328                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
329                         if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
330                                 float cursor_rel[3];
331                                 sub_v3_v3v3(cursor_rel, cursor_local, ebone->head);
332                                 if (axis_flip) negate_v3(cursor_rel);
333                                 if (normalize_v3(cursor_rel) != 0.0f) {
334                                         ebone->roll = ED_rollBoneToVector(ebone, cursor_rel, axis_only);
335                                 }
336                         }
337                 }
338         }
339         else if (ELEM(type, CALC_ROLL_TAN_POS_X, CALC_ROLL_TAN_POS_Z)) {
340                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
341                         if (ebone->parent) {
342                                 bool is_edit        = (EBONE_VISIBLE(arm, ebone)         && EBONE_EDITABLE(ebone));
343                                 bool is_edit_parent = (EBONE_VISIBLE(arm, ebone->parent) && EBONE_EDITABLE(ebone->parent));
344
345                                 if (is_edit || is_edit_parent) {
346                                         EditBone *ebone_other = ebone->parent;
347                                         float dir_a[3];
348                                         float dir_b[3];
349                                         float vec[3];
350                                         bool is_vec_zero;
351
352                                         sub_v3_v3v3(dir_a, ebone->tail, ebone->head);
353                                         normalize_v3(dir_a);
354
355                                         /* find the first bone in the chane with a different direction */
356                                         do {
357                                                 sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail);
358                                                 normalize_v3(dir_b);
359
360                                                 if (type == CALC_ROLL_TAN_POS_Z) {
361                                                         cross_v3_v3v3(vec, dir_a, dir_b);
362                                                 }
363                                                 else {
364                                                         add_v3_v3v3(vec, dir_a, dir_b);
365                                                 }
366                                         } while ((is_vec_zero = (normalize_v3(vec) < 0.00001f)) &&
367                                                  (ebone_other = ebone_other->parent));
368
369                                         if (!is_vec_zero) {
370                                                 if (axis_flip) negate_v3(vec);
371
372                                                 if (is_edit) {
373                                                         ebone->roll = ED_rollBoneToVector(ebone, vec, axis_only);
374                                                 }
375
376                                                 /* parentless bones use cross product with child */
377                                                 if (is_edit_parent) {
378                                                         if (ebone->parent->parent == NULL) {
379                                                                 ebone->parent->roll = ED_rollBoneToVector(ebone->parent, vec, axis_only);
380                                                         }
381                                                 }
382                                         }
383                                 }
384                         }
385                 }
386         }
387         else {
388                 float vec[3] = {0.0f, 0.0f, 0.0f};
389                 if (type == CALC_ROLL_VIEW) { /* View */
390                         RegionView3D *rv3d = CTX_wm_region_view3d(C);
391                         if (rv3d == NULL) {
392                                 BKE_report(op->reports, RPT_ERROR, "No region view3d available");
393                                 return OPERATOR_CANCELLED;
394                         }
395                         
396                         copy_v3_v3(vec, rv3d->viewinv[2]);
397                         mul_m3_v3(imat, vec);
398                 }
399                 else if (type == CALC_ROLL_ACTIVE) {
400                         float mat[3][3];
401                         ebone = (EditBone *)arm->act_edbone;
402                         if (ebone == NULL) {
403                                 BKE_report(op->reports, RPT_ERROR, "No active bone set");
404                                 return OPERATOR_CANCELLED;
405                         }
406                         
407                         ED_armature_ebone_to_mat3(ebone, mat);
408                         copy_v3_v3(vec, mat[2]);
409                 }
410                 else { /* Axis */
411                         assert(type <= 5);
412                         if (type < 3) vec[type] = 1.0f;
413                         else vec[type - 2] = -1.0f;
414                         mul_m3_v3(imat, vec);
415                         normalize_v3(vec);
416                 }
417                 
418                 if (axis_flip) negate_v3(vec);
419                 
420                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
421                         if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
422                                 /* roll func is a callback which assumes that all is well */
423                                 ebone->roll = ED_rollBoneToVector(ebone, vec, axis_only);
424                         }
425                 }
426         }
427         
428         if (arm->flag & ARM_MIRROR_EDIT) {
429                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
430                         if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
431                                 EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, ebone);
432                                 if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
433                                         ebone->roll = -ebone_mirr->roll;
434                                 }
435                         }
436                 }
437         }
438         
439         /* note, notifier might evolve */
440         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
441         
442         return OPERATOR_FINISHED;
443 }
444
445 void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
446 {
447         /* identifiers */
448         ot->name = "Recalculate Roll";
449         ot->idname = "ARMATURE_OT_calculate_roll";
450         ot->description = "Automatically fix alignment of select bones' axes";
451         
452         /* api callbacks */
453         ot->invoke = WM_menu_invoke;
454         ot->exec = armature_calc_roll_exec;
455         ot->poll = ED_operator_editarmature;
456         
457         /* flags */
458         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
459
460         /* properties */
461         ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, CALC_ROLL_TAN_POS_X, "Type", "");
462         RNA_def_boolean(ot->srna, "axis_flip", 0, "Flip Axis", "Negate the alignment axis");
463         RNA_def_boolean(ot->srna, "axis_only", 0, "Shortest Rotation", "Ignore the axis direction, use the shortest rotation to align");
464 }
465
466 static int armature_roll_clear_exec(bContext *C, wmOperator *op)
467 {
468         Object *ob = CTX_data_edit_object(C);
469
470         bArmature *arm = ob->data;
471         EditBone *ebone;
472
473         const float roll = RNA_float_get(op->ptr, "roll");
474
475         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
476                 if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
477                         /* roll func is a callback which assumes that all is well */
478                         ebone->roll = roll;
479                 }
480         }
481
482         if (arm->flag & ARM_MIRROR_EDIT) {
483                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
484                         if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
485                                 EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, ebone);
486                                 if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
487                                         ebone->roll = -ebone_mirr->roll;
488                                 }
489                         }
490                 }
491         }
492
493         /* note, notifier might evolve */
494         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
495
496         return OPERATOR_FINISHED;
497 }
498
499 void ARMATURE_OT_roll_clear(wmOperatorType *ot)
500 {
501         /* identifiers */
502         ot->name = "Clear Roll";
503         ot->idname = "ARMATURE_OT_roll_clear";
504         ot->description = "Clear roll for selected bones";
505
506         /* api callbacks */
507         ot->exec = armature_roll_clear_exec;
508         ot->poll = ED_operator_editarmature;
509
510         /* flags */
511         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
512
513         RNA_def_float_rotation(
514                 ot->srna, "roll", 0, NULL, DEG2RADF(-360.0f), DEG2RADF(360.0f),
515                 "Roll", "", DEG2RADF(-360.0f), DEG2RADF(360.0f));
516 }
517
518 /* ******************************** Chain-Based Tools ********************************* */
519
520 /* temporary data-structure for merge/fill bones */
521 typedef struct EditBonePoint {
522         struct EditBonePoint *next, *prev;
523         
524         EditBone *head_owner;       /* EditBone which uses this point as a 'head' point */
525         EditBone *tail_owner;       /* EditBone which uses this point as a 'tail' point */
526         
527         float vec[3];               /* the actual location of the point in local/EditMode space */
528 } EditBonePoint;
529
530 /* find chain-tips (i.e. bones without children) */
531 static void chains_find_tips(ListBase *edbo, ListBase *list)
532 {
533         EditBone *curBone, *ebo;
534         LinkData *ld;
535         
536         /* note: this is potentially very slow ... there's got to be a better way */
537         for (curBone = edbo->first; curBone; curBone = curBone->next) {
538                 short stop = 0;
539                 
540                 /* is this bone contained within any existing chain? (skip if so) */
541                 for (ld = list->first; ld; ld = ld->next) {
542                         for (ebo = ld->data; ebo; ebo = ebo->parent) {
543                                 if (ebo == curBone) {
544                                         stop = 1;
545                                         break;
546                                 }
547                         }
548                         
549                         if (stop) break;
550                 }
551                 /* skip current bone if it is part of an existing chain */
552                 if (stop) continue;
553                 
554                 /* is any existing chain part of the chain formed by this bone? */
555                 stop = 0;
556                 for (ebo = curBone->parent; ebo; ebo = ebo->parent) {
557                         for (ld = list->first; ld; ld = ld->next) {
558                                 if (ld->data == ebo) {
559                                         ld->data = curBone;
560                                         stop = 1;
561                                         break;
562                                 }
563                         }
564                         
565                         if (stop) break;
566                 }
567                 /* current bone has already been added to a chain? */
568                 if (stop) continue;
569                 
570                 /* add current bone to a new chain */
571                 ld = MEM_callocN(sizeof(LinkData), "BoneChain");
572                 ld->data = curBone;
573                 BLI_addtail(list, ld);
574         }
575 }
576
577 /* --------------------- */
578
579 static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
580 {
581         EditBonePoint *ebp;
582         float vec[3];
583         short found = 0;
584         
585         if (eb_tail) {
586                 copy_v3_v3(vec, ebo->tail);
587         }
588         else {
589                 copy_v3_v3(vec, ebo->head);
590         }
591         
592         for (ebp = points->first; ebp; ebp = ebp->next) {
593                 if (equals_v3v3(ebp->vec, vec)) {
594                         if (eb_tail) {
595                                 if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
596                                         /* so this bone's tail owner is this bone */
597                                         ebp->tail_owner = ebo;
598                                         found = 1;
599                                         break;
600                                 }
601                         }
602                         else {
603                                 if ((ebp->tail_owner) && (ebo->parent == ebp->tail_owner)) {
604                                         /* so this bone's head owner is this bone */
605                                         ebp->head_owner = ebo;
606                                         found = 1;
607                                         break;
608                                 }
609                         }
610                 }
611         }
612         
613         /* allocate a new point if no existing point was related */
614         if (found == 0) {
615                 ebp = MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
616                 
617                 if (eb_tail) {
618                         copy_v3_v3(ebp->vec, ebo->tail);
619                         ebp->tail_owner = ebo;
620                 }
621                 else {
622                         copy_v3_v3(ebp->vec, ebo->head);
623                         ebp->head_owner = ebo;
624                 }
625                 
626                 BLI_addtail(points, ebp);
627         }
628 }
629
630 /* bone adding between selected joints */
631 static int armature_fill_bones_exec(bContext *C, wmOperator *op)
632 {
633         Object *obedit = CTX_data_edit_object(C);
634         bArmature *arm = (obedit) ? obedit->data : NULL;
635         Scene *scene = CTX_data_scene(C);
636         View3D *v3d = CTX_wm_view3d(C);
637         ListBase points = {NULL, NULL};
638         EditBone *newbone = NULL;
639         int count;
640
641         /* sanity checks */
642         if (ELEM(NULL, obedit, arm))
643                 return OPERATOR_CANCELLED;
644
645         /* loop over all bones, and only consider if visible */
646         CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones)
647         {
648                 if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL))
649                         fill_add_joint(ebone, 0, &points);
650                 if (ebone->flag & BONE_TIPSEL) 
651                         fill_add_joint(ebone, 1, &points);
652         }
653         CTX_DATA_END;
654         
655         /* the number of joints determines how we fill:
656          *  1) between joint and cursor (joint=head, cursor=tail)
657          *  2) between the two joints (order is dependent on active-bone/hierarchy)
658          *  3+) error (a smarter method involving finding chains needs to be worked out
659          */
660         count = BLI_listbase_count(&points);
661         
662         if (count == 0) {
663                 BKE_report(op->reports, RPT_ERROR, "No joints selected");
664                 return OPERATOR_CANCELLED;
665         }
666         else if (count == 1) {
667                 EditBonePoint *ebp;
668                 float curs[3];
669                 
670                 /* Get Points - selected joint */
671                 ebp = points.first;
672                 
673                 /* Get points - cursor (tail) */
674                 invert_m4_m4(obedit->imat, obedit->obmat);
675                 mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
676                 
677                 /* Create a bone */
678                 newbone = add_points_bone(obedit, ebp->vec, curs);
679         }
680         else if (count == 2) {
681                 EditBonePoint *ebp_a, *ebp_b;
682                 float head[3], tail[3];
683                 short headtail = 0;
684                 
685                 /* check that the points don't belong to the same bone */
686                 ebp_a = (EditBonePoint *)points.first;
687                 ebp_b = ebp_a->next;
688                 
689                 if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) ||
690                     ((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL)))
691                 {
692                         BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
693                         BLI_freelistN(&points);
694                         return OPERATOR_CANCELLED;
695                 }
696                 
697                 /* find which one should be the 'head' */
698                 if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) {
699                         /* use active, nice predictable */
700                         if (arm->act_edbone && ELEM(arm->act_edbone, ebp_a->head_owner, ebp_a->tail_owner)) {
701                                 headtail = 1;
702                         }
703                         else if (arm->act_edbone && ELEM(arm->act_edbone, ebp_b->head_owner, ebp_b->tail_owner)) {
704                                 headtail = 2;
705                         }
706                         else {
707                                 /* rule: whichever one is closer to 3d-cursor */
708                                 float curs[3];
709                                 float dist_sq_a, dist_sq_b;
710
711                                 /* get cursor location */
712                                 invert_m4_m4(obedit->imat, obedit->obmat);
713                                 mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
714
715                                 /* get distances */
716                                 dist_sq_a = len_squared_v3v3(ebp_a->vec, curs);
717                                 dist_sq_b = len_squared_v3v3(ebp_b->vec, curs);
718
719                                 /* compare distances - closer one therefore acts as direction for bone to go */
720                                 headtail = (dist_sq_a < dist_sq_b) ? 2 : 1;
721                         }
722                 }
723                 else if (ebp_a->head_owner) {
724                         headtail = 1;
725                 }
726                 else if (ebp_b->head_owner) {
727                         headtail = 2;
728                 }
729                 
730                 /* assign head/tail combinations */
731                 if (headtail == 2) {
732                         copy_v3_v3(head, ebp_a->vec);
733                         copy_v3_v3(tail, ebp_b->vec);
734                 }
735                 else if (headtail == 1) {
736                         copy_v3_v3(head, ebp_b->vec);
737                         copy_v3_v3(tail, ebp_a->vec);
738                 }
739                 
740                 /* add new bone and parent it to the appropriate end */
741                 if (headtail) {
742                         newbone = add_points_bone(obedit, head, tail);
743                         
744                         /* do parenting (will need to set connected flag too) */
745                         if (headtail == 2) {
746                                 /* ebp tail or head - tail gets priority */
747                                 if (ebp_a->tail_owner)
748                                         newbone->parent = ebp_a->tail_owner;
749                                 else
750                                         newbone->parent = ebp_a->head_owner;
751                         }
752                         else {
753                                 /* ebp_b tail or head - tail gets priority */
754                                 if (ebp_b->tail_owner)
755                                         newbone->parent = ebp_b->tail_owner;
756                                 else
757                                         newbone->parent = ebp_b->head_owner;
758                         }
759
760                         /* don't set for bone connecting two head points of bones */
761                         if (ebp_a->tail_owner || ebp_b->tail_owner) {
762                                 newbone->flag |= BONE_CONNECTED;
763                         }
764                 }
765         }
766         else {
767                 /* FIXME.. figure out a method for multiple bones */
768                 BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d", count);
769                 BLI_freelistN(&points);
770                 return OPERATOR_CANCELLED;
771         }
772
773         if (newbone) {
774                 ED_armature_deselect_all(obedit);
775                 arm->act_edbone = newbone;
776                 newbone->flag |= BONE_TIPSEL;
777         }
778         
779         /* updates */
780         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
781         
782         /* free points */
783         BLI_freelistN(&points);
784         
785         return OPERATOR_FINISHED;
786 }
787
788 void ARMATURE_OT_fill(wmOperatorType *ot)
789 {
790         /* identifiers */
791         ot->name = "Fill Between Joints";
792         ot->idname = "ARMATURE_OT_fill";
793         ot->description = "Add bone between selected joint(s) and/or 3D-Cursor";
794         
795         /* callbacks */
796         ot->exec = armature_fill_bones_exec;
797         ot->poll = ED_operator_editarmature;
798         
799         /* flags */
800         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
801 }
802
803 /* --------------------- */
804
805 /* this function merges between two bones, removes them and those in-between, 
806  * and adjusts the parent relationships for those in-between
807  */
808 static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
809 {
810         bArmature *arm = obedit->data;
811         EditBone *ebo, *ebone, *newbone;
812         LinkData *chain;
813         float head[3], tail[3];
814         
815         /* check if same bone */
816         if (start == end) {
817                 if (G.debug & G_DEBUG) {
818                         printf("Error: same bone!\n");
819                         printf("\tstart = %s, end = %s\n", start->name, end->name);
820                 }
821         }
822         
823         /* step 1: add a new bone
824          *      - head = head/tail of start (default head)
825          *      - tail = head/tail of end (default tail)
826          *      - parent = parent of start
827          */
828         if ((start->flag & BONE_TIPSEL) && (start->flag & BONE_SELECTED) == 0) {
829                 copy_v3_v3(head, start->tail);
830         }
831         else {
832                 copy_v3_v3(head, start->head);
833         }
834         if ((end->flag & BONE_ROOTSEL) && (end->flag & BONE_SELECTED) == 0) {
835                 copy_v3_v3(tail, end->head);
836         }
837         else {
838                 copy_v3_v3(tail, end->tail);
839         }
840         newbone = add_points_bone(obedit, head, tail);
841         newbone->parent = start->parent;
842
843         /* TODO, copy more things to the new bone */
844         newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE |
845                                        BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE);
846         
847         /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge 
848          *      - potentially several tips for side chains leading to some tree exist...
849          */
850         for (chain = chains->first; chain; chain = chain->next) {
851                 /* traverse down chain until we hit the bottom or if we run into the tip of the chain of bones we're 
852                  * merging (need to stop in this case to avoid corrupting this chain too!) 
853                  */
854                 for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) {
855                         short found = 0;
856                         
857                         /* check if this bone is parented to one in the merging chain
858                          * ! WATCHIT: must only go check until end of checking chain
859                          */
860                         for (ebo = end; (ebo) && (ebo != start->parent); ebo = ebo->parent) {
861                                 /* side-chain found? --> remap parent to new bone, then we're done with this chain :) */
862                                 if (ebone->parent == ebo) {
863                                         ebone->parent = newbone;
864                                         found = 1;
865                                         break;
866                                 }
867                         }
868                         
869                         /* carry on to the next tip now  */
870                         if (found) 
871                                 break;
872                 }
873         }
874         
875         /* step 2b: parent child of end to newbone (child from this chain) */
876         if (endchild)
877                 endchild->parent = newbone;
878         
879         /* step 3: delete all bones between and including start and end */
880         for (ebo = end; ebo; ebo = ebone) {
881                 ebone = (ebo == start) ? (NULL) : (ebo->parent);
882                 bone_free(arm, ebo);
883         }
884         
885         newbone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
886         ED_armature_sync_selection(arm->edbo);
887 }
888
889
890 static int armature_merge_exec(bContext *C, wmOperator *op)
891 {
892         Object *obedit = CTX_data_edit_object(C);
893         bArmature *arm = (obedit) ? obedit->data : NULL;
894         short type = RNA_enum_get(op->ptr, "type");
895         
896         /* sanity checks */
897         if (ELEM(NULL, obedit, arm))
898                 return OPERATOR_CANCELLED;
899         
900         /* for now, there's only really one type of merging that's performed... */
901         if (type == 1) {
902                 /* go down chains, merging bones */
903                 ListBase chains = {NULL, NULL};
904                 LinkData *chain, *nchain;
905                 EditBone *ebo;
906                 
907                 armature_tag_select_mirrored(arm);
908                 
909                 /* get chains (ends on chains) */
910                 chains_find_tips(arm->edbo, &chains);
911                 if (BLI_listbase_is_empty(&chains)) return OPERATOR_CANCELLED;
912                 
913                 /* each 'chain' is the last bone in the chain (with no children) */
914                 for (chain = chains.first; chain; chain = nchain) {
915                         EditBone *bstart = NULL, *bend = NULL;
916                         EditBone *bchild = NULL, *child = NULL;
917                         
918                         /* temporarily remove chain from list of chains */
919                         nchain = chain->next;
920                         BLI_remlink(&chains, chain);
921                         
922                         /* only consider bones that are visible and selected */
923                         for (ebo = chain->data; ebo; child = ebo, ebo = ebo->parent) {
924                                 /* check if visible + selected */
925                                 if (EBONE_VISIBLE(arm, ebo) &&
926                                     ((ebo->flag & BONE_CONNECTED) || (ebo->parent == NULL)) &&
927                                     (ebo->flag & BONE_SELECTED) )
928                                 {
929                                         /* set either end or start (end gets priority, unless it is already set) */
930                                         if (bend == NULL) {
931                                                 bend = ebo;
932                                                 bchild = child;
933                                         }
934                                         else 
935                                                 bstart = ebo;
936                                 }
937                                 else {
938                                         /* chain is broken... merge any continous segments then clear */
939                                         if (bstart && bend)
940                                                 bones_merge(obedit, bstart, bend, bchild, &chains);
941                                         
942                                         bstart = NULL;
943                                         bend = NULL;
944                                         bchild = NULL;
945                                 }
946                         }
947                         
948                         /* merge from bstart to bend if something not merged */
949                         if (bstart && bend)
950                                 bones_merge(obedit, bstart, bend, bchild, &chains);
951                         
952                         /* put back link */
953                         BLI_insertlinkbefore(&chains, nchain, chain);
954                 }
955                 
956                 armature_tag_unselect(arm);
957                 
958                 BLI_freelistN(&chains);
959         }
960         
961         /* updates */
962         ED_armature_sync_selection(arm->edbo);
963         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
964         
965         return OPERATOR_FINISHED;
966 }
967
968 void ARMATURE_OT_merge(wmOperatorType *ot)
969 {
970         static const EnumPropertyItem merge_types[] = {
971                 {1, "WITHIN_CHAIN", 0, "Within Chains", ""},
972                 {0, NULL, 0, NULL, NULL}
973         };
974
975         /* identifiers */
976         ot->name = "Merge Bones";
977         ot->idname = "ARMATURE_OT_merge";
978         ot->description = "Merge continuous chains of selected bones";
979         
980         /* callbacks */
981         ot->invoke = WM_menu_invoke;
982         ot->exec = armature_merge_exec;
983         ot->poll = ED_operator_editarmature;
984         
985         /* flags */
986         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
987         
988         /* properties */
989         ot->prop = RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
990 }
991
992 /* --------------------- */
993
994 /* Switch Direction operator:
995  * Currently, this does not use context loops, as context loops do not make it
996  * easy to retrieve any hierarchical/chain relationships which are necessary for
997  * this to be done easily.
998  */
999  
1000 /* helper to clear BONE_TRANSFORM flags */
1001 static void armature_clear_swap_done_flags(bArmature *arm)
1002 {
1003         EditBone *ebone;
1004         
1005         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1006                 ebone->flag &= ~BONE_TRANSFORM;
1007         }
1008 }
1009
1010 static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) 
1011 {
1012         Object *ob = CTX_data_edit_object(C);
1013         bArmature *arm = (bArmature *)ob->data;
1014         ListBase chains = {NULL, NULL};
1015         LinkData *chain;
1016         
1017         /* get chains of bones (ends on chains) */
1018         chains_find_tips(arm->edbo, &chains);
1019         if (BLI_listbase_is_empty(&chains)) return OPERATOR_CANCELLED;
1020         
1021         /* ensure that mirror bones will also be operated on */
1022         armature_tag_select_mirrored(arm);
1023         
1024         /* clear BONE_TRANSFORM flags 
1025          * - used to prevent duplicate/canceling operations from occurring [#34123]
1026          * - BONE_DONE cannot be used here as that's already used for mirroring
1027          */
1028         armature_clear_swap_done_flags(arm);
1029         
1030         /* loop over chains, only considering selected and visible bones */
1031         for (chain = chains.first; chain; chain = chain->next) {
1032                 EditBone *ebo, *child = NULL, *parent = NULL;
1033                 
1034                 /* loop over bones in chain */
1035                 for (ebo = chain->data; ebo; ebo = parent) {
1036                         /* parent is this bone's original parent
1037                          *      - we store this, as the next bone that is checked is this one
1038                          *        but the value of ebo->parent may change here...
1039                          */
1040                         parent = ebo->parent;
1041                         
1042                         /* skip bone if already handled... [#34123] */
1043                         if ((ebo->flag & BONE_TRANSFORM) == 0) {
1044                                 /* only if selected and editable */
1045                                 if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
1046                                         /* swap head and tail coordinates */
1047                                         swap_v3_v3(ebo->head, ebo->tail);
1048                                         
1049                                         /* do parent swapping:
1050                                          *      - use 'child' as new parent
1051                                          *      - connected flag is only set if points are coincidental
1052                                          */
1053                                         ebo->parent = child;
1054                                         if ((child) && equals_v3v3(ebo->head, child->tail))
1055                                                 ebo->flag |= BONE_CONNECTED;
1056                                         else
1057                                                 ebo->flag &= ~BONE_CONNECTED;
1058                                         
1059                                         /* get next bones 
1060                                          *      - child will become the new parent of next bone
1061                                          */
1062                                         child = ebo;
1063                                 }
1064                                 else {
1065                                         /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it 
1066                                          * as it will be facing in opposite direction
1067                                          */
1068                                         if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
1069                                                 ebo->parent = NULL;
1070                                                 ebo->flag &= ~BONE_CONNECTED;
1071                                         }
1072                                         
1073                                         /* get next bones
1074                                          *      - child will become new parent of next bone (not swapping occurred, 
1075                                          *        so set to NULL to prevent infinite-loop)
1076                                          */
1077                                         child = NULL;
1078                                 }
1079                                 
1080                                 /* tag as done (to prevent double-swaps) */
1081                                 ebo->flag |= BONE_TRANSFORM;
1082                         }
1083                 }
1084         }
1085         
1086         /* free chains */
1087         BLI_freelistN(&chains);
1088         
1089         /* clear temp flags */
1090         armature_clear_swap_done_flags(arm);
1091         armature_tag_unselect(arm);
1092         
1093         /* note, notifier might evolve */
1094         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1095         
1096         return OPERATOR_FINISHED;
1097 }
1098
1099 void ARMATURE_OT_switch_direction(wmOperatorType *ot)
1100 {
1101         /* identifiers */
1102         ot->name = "Switch Direction";
1103         ot->idname = "ARMATURE_OT_switch_direction";
1104         ot->description = "Change the direction that a chain of bones points in (head <-> tail swap)";
1105         
1106         /* api callbacks */
1107         ot->exec = armature_switch_direction_exec;
1108         ot->poll = ED_operator_editarmature;
1109         
1110         /* flags */
1111         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1112 }
1113
1114 /* ********************************* Align ******************************* */
1115
1116 /* helper to fix a ebone position if its parent has moved due to alignment*/
1117 static void fix_connected_bone(EditBone *ebone)
1118 {
1119         float diff[3];
1120         
1121         if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) || equals_v3v3(ebone->parent->tail, ebone->head))
1122                 return;
1123         
1124         /* if the parent has moved we translate child's head and tail accordingly */
1125         sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
1126         add_v3_v3(ebone->head, diff);
1127         add_v3_v3(ebone->tail, diff);
1128 }
1129
1130 /* helper to recursively find chains of connected bones starting at ebone and fix their position */
1131 static void fix_editbone_connected_children(ListBase *edbo, EditBone *ebone)
1132 {
1133         EditBone *selbone;
1134         
1135         for (selbone = edbo->first; selbone; selbone = selbone->next) {
1136                 if ((selbone->parent) && (selbone->parent == ebone) && (selbone->flag & BONE_CONNECTED)) {
1137                         fix_connected_bone(selbone);
1138                         fix_editbone_connected_children(edbo, selbone);
1139                 }
1140         }
1141 }                       
1142
1143 static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actbone)
1144 {
1145         float selboneaxis[3], actboneaxis[3], length;
1146
1147         sub_v3_v3v3(actboneaxis, actbone->tail, actbone->head);
1148         normalize_v3(actboneaxis);
1149
1150         sub_v3_v3v3(selboneaxis, selbone->tail, selbone->head);
1151         length =  len_v3(selboneaxis);
1152
1153         mul_v3_fl(actboneaxis, length);
1154         add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
1155         selbone->roll = actbone->roll;
1156         
1157         /* if the bone being aligned has connected descendants they must be moved
1158          * according to their parent new position, otherwise they would be left
1159          * in an inconsistent state: connected but away from the parent*/
1160         fix_editbone_connected_children(edbo, selbone);
1161 }
1162
1163 static int armature_align_bones_exec(bContext *C, wmOperator *op) 
1164 {
1165         Object *ob = CTX_data_edit_object(C);
1166         bArmature *arm = (bArmature *)ob->data;
1167         EditBone *actbone = CTX_data_active_bone(C);
1168         EditBone *actmirb = NULL;
1169         int num_selected_bones;
1170         
1171         /* there must be an active bone */
1172         if (actbone == NULL) {
1173                 BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
1174                 return OPERATOR_CANCELLED;
1175         }
1176         else if (arm->flag & ARM_MIRROR_EDIT) {
1177                 /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
1178                  * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
1179                  *   (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
1180                  *   This is useful for arm-chains, for example parenting lower arm to upper arm
1181                  * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
1182                  *   then just use actbone. Useful when doing upper arm to spine.
1183                  */
1184                 actmirb = ED_armature_bone_get_mirrored(arm->edbo, actbone);
1185                 if (actmirb == NULL) 
1186                         actmirb = actbone;
1187         }
1188         
1189         /* if there is only 1 selected bone, we assume that that is the active bone, 
1190          * since a user will need to have clicked on a bone (thus selecting it) to make it active
1191          */
1192         num_selected_bones = CTX_DATA_COUNT(C, selected_editable_bones);
1193         if (num_selected_bones <= 1) {
1194                 /* When only the active bone is selected, and it has a parent,
1195                  * align it to the parent, as that is the only possible outcome. 
1196                  */
1197                 if (actbone->parent) {
1198                         bone_align_to_bone(arm->edbo, actbone, actbone->parent);
1199                         
1200                         if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
1201                                 bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
1202
1203                         BKE_reportf(op->reports, RPT_INFO, "Aligned bone '%s' to parent", actbone->name);
1204                 }
1205         }
1206         else {
1207                 /* Align 'selected' bones to the active one
1208                  * - the context iterator contains both selected bones and their mirrored copies,
1209                  *   so we assume that unselected bones are mirrored copies of some selected bone
1210                  * - since the active one (and/or its mirror) will also be selected, we also need 
1211                  *   to check that we are not trying to operate on them, since such an operation
1212                  *   would cause errors
1213                  */
1214                 
1215                 /* align selected bones to the active one */
1216                 CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
1217                 {
1218                         if (ELEM(ebone, actbone, actmirb) == 0) {
1219                                 if (ebone->flag & BONE_SELECTED)
1220                                         bone_align_to_bone(arm->edbo, ebone, actbone);
1221                                 else
1222                                         bone_align_to_bone(arm->edbo, ebone, actmirb);
1223                         }
1224                 }
1225                 CTX_DATA_END;
1226
1227                 BKE_reportf(op->reports, RPT_INFO, "%d bones aligned to bone '%s'", num_selected_bones, actbone->name);
1228         }
1229
1230         /* note, notifier might evolve */
1231         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1232         
1233         return OPERATOR_FINISHED;
1234 }
1235
1236 void ARMATURE_OT_align(wmOperatorType *ot)
1237 {
1238         /* identifiers */
1239         ot->name = "Align Bones";
1240         ot->idname = "ARMATURE_OT_align";
1241         ot->description = "Align selected bones to the active bone (or to their parent)";
1242         
1243         /* api callbacks */
1244         ot->exec = armature_align_bones_exec;
1245         ot->poll = ED_operator_editarmature;
1246         
1247         /* flags */
1248         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1249 }
1250
1251 /* ********************************* Split ******************************* */
1252
1253 static int armature_split_exec(bContext *C, wmOperator *UNUSED(op))
1254 {
1255         Object *ob = CTX_data_edit_object(C);
1256         bArmature *arm = (bArmature *)ob->data;
1257         EditBone *bone;
1258
1259         for (bone = arm->edbo->first; bone; bone = bone->next) {
1260                 if (bone->parent && (bone->flag & BONE_SELECTED) != (bone->parent->flag & BONE_SELECTED)) {
1261                         bone->parent = NULL;
1262                         bone->flag &= ~BONE_CONNECTED;
1263                 }
1264         }
1265         for (bone = arm->edbo->first; bone; bone = bone->next) {
1266                 ED_armature_ebone_select_set(bone, (bone->flag & BONE_SELECTED) != 0);
1267         }
1268
1269         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1270
1271         return OPERATOR_FINISHED;
1272 }
1273
1274 void ARMATURE_OT_split(wmOperatorType *ot)
1275 {
1276         /* identifiers */
1277         ot->name = "Split";
1278         ot->idname = "ARMATURE_OT_split";
1279         ot->description = "Split off selected bones from connected unselected bones";
1280
1281         /* api callbacks */
1282         ot->exec = armature_split_exec;
1283         ot->poll = ED_operator_editarmature;
1284
1285         /* flags */
1286         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1287 }
1288
1289 /* ********************************* Delete ******************************* */
1290
1291 static bool armature_delete_ebone_cb(const char *bone_name, void *arm_p)
1292 {
1293         bArmature *arm = arm_p;
1294         EditBone *ebone;
1295
1296         ebone = ED_armature_bone_find_name(arm->edbo, bone_name);
1297         return (ebone && (ebone->flag & BONE_SELECTED) && (arm->layer & ebone->layer));
1298 }
1299
1300 /* previously delete_armature */
1301 /* only editmode! */
1302 static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
1303 {
1304         bArmature *arm;
1305         EditBone *curBone, *ebone_next;
1306         Object *obedit = CTX_data_edit_object(C); // XXX get from context
1307         bool changed = false;
1308         arm = obedit->data;
1309
1310         /* cancel if nothing selected */
1311         if (CTX_DATA_COUNT(C, selected_bones) == 0)
1312                 return OPERATOR_CANCELLED;
1313         
1314         armature_select_mirrored(arm);
1315         
1316         BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm);
1317
1318         for (curBone = arm->edbo->first; curBone; curBone = ebone_next) {
1319                 ebone_next = curBone->next;
1320                 if (arm->layer & curBone->layer) {
1321                         if (curBone->flag & BONE_SELECTED) {
1322                                 if (curBone == arm->act_edbone) arm->act_edbone = NULL;
1323                                 ED_armature_edit_bone_remove(arm, curBone);
1324                                 changed = true;
1325                         }
1326                 }
1327         }
1328         
1329         if (!changed)
1330                 return OPERATOR_CANCELLED;
1331         
1332         ED_armature_sync_selection(arm->edbo);
1333         BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose);
1334
1335         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1336
1337         return OPERATOR_FINISHED;
1338 }
1339
1340 void ARMATURE_OT_delete(wmOperatorType *ot)
1341 {
1342         /* identifiers */
1343         ot->name = "Delete Selected Bone(s)";
1344         ot->idname = "ARMATURE_OT_delete";
1345         ot->description = "Remove selected bones from the armature";
1346         
1347         /* api callbacks */
1348         ot->invoke = WM_operator_confirm;
1349         ot->exec = armature_delete_selected_exec;
1350         ot->poll = ED_operator_editarmature;
1351         
1352         /* flags */
1353         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1354 }
1355
1356 static bool armature_dissolve_ebone_cb(const char *bone_name, void *arm_p)
1357 {
1358         bArmature *arm = arm_p;
1359         EditBone *ebone;
1360
1361         ebone = ED_armature_bone_find_name(arm->edbo, bone_name);
1362         return (ebone && (ebone->flag & BONE_DONE));
1363 }
1364
1365 static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op))
1366 {
1367         bArmature *arm;
1368         EditBone *ebone, *ebone_next;
1369         Object *obedit = CTX_data_edit_object(C);
1370         bool changed = false;
1371
1372         /* store for mirror */
1373         GHash *ebone_flag_orig = NULL;
1374         int ebone_num = 0;
1375
1376         arm = obedit->data;
1377
1378         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1379                 ebone->temp.p = NULL;
1380                 ebone->flag &= ~BONE_DONE;
1381                 ebone_num++;
1382         }
1383
1384         if (arm->flag & ARM_MIRROR_EDIT) {
1385                 GHashIterator gh_iter;
1386
1387                 ebone_flag_orig = BLI_ghash_ptr_new_ex(__func__, ebone_num);
1388                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1389                         union { int flag; void *p; } val = {0};
1390                         val.flag = ebone->flag;
1391                         BLI_ghash_insert(ebone_flag_orig, ebone, val.p);
1392                 }
1393
1394                 armature_select_mirrored_ex(arm, BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
1395
1396                 GHASH_ITER (gh_iter, ebone_flag_orig) {
1397                         union { int flag; void *p; } *val_p = (void *)BLI_ghashIterator_getValue_p(&gh_iter);
1398                         ebone = BLI_ghashIterator_getKey(&gh_iter);
1399                         val_p->flag = ebone->flag & ~val_p->flag;
1400                 }
1401         }
1402
1403         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1404                 if (ebone->parent && ebone->flag & BONE_CONNECTED) {
1405                         if (ebone->parent->temp.ebone == ebone->parent) {
1406                                 /* ignore */
1407                         }
1408                         else if (ebone->parent->temp.ebone) {
1409                                 /* set ignored */
1410                                 ebone->parent->temp.ebone = ebone->parent;
1411                         }
1412                         else {
1413                                 /* set child */
1414                                 ebone->parent->temp.ebone = ebone;
1415                         }
1416                 }
1417         }
1418
1419         /* cleanup multiple used bones */
1420         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1421                 if (ebone->temp.ebone == ebone) {
1422                         ebone->temp.ebone = NULL;
1423                 }
1424         }
1425
1426         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1427                 /* break connections for unseen bones */
1428                 if (((arm->layer & ebone->layer) &&
1429                      ((ED_armature_ebone_selectflag_get(ebone) & (BONE_TIPSEL | BONE_SELECTED)))) == 0)
1430                 {
1431                         ebone->temp.ebone = NULL;
1432                 }
1433
1434                 if (((arm->layer & ebone->layer) &&
1435                     ((ED_armature_ebone_selectflag_get(ebone) & (BONE_ROOTSEL | BONE_SELECTED)))) == 0)
1436                 {
1437                         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
1438                                 ebone->parent->temp.ebone = NULL;
1439                         }
1440
1441                 }
1442         }
1443
1444         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1445
1446                 if (ebone->parent &&
1447                     (ebone->parent->temp.ebone == ebone))
1448                 {
1449                         ebone->flag |= BONE_DONE;
1450                 }
1451         }
1452
1453         BKE_pose_channels_remove(obedit, armature_dissolve_ebone_cb, arm);
1454
1455         for (ebone = arm->edbo->first; ebone; ebone = ebone_next) {
1456                 ebone_next = ebone->next;
1457
1458                 if (ebone->flag & BONE_DONE) {
1459                         copy_v3_v3(ebone->parent->tail, ebone->tail);
1460                         ebone->parent->rad_tail = ebone->rad_tail;
1461
1462                         ED_armature_edit_bone_remove(arm, ebone);
1463                         changed = true;
1464                 }
1465         }
1466
1467         if (changed) {
1468                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1469                         if (ebone->parent &&
1470                             ebone->parent->temp.ebone &&
1471                             (ebone->flag & BONE_CONNECTED) == 0)
1472                         {
1473                                 ebone->flag |= BONE_CONNECTED;
1474                                 ebone->rad_head = ebone->parent->rad_head;
1475                         }
1476                 }
1477
1478                 if (arm->flag & ARM_MIRROR_EDIT) {
1479                         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1480                                 union { int flag; void *p; } *val_p = (void *)BLI_ghash_lookup_p(ebone_flag_orig, ebone);
1481                                 if (val_p && val_p->flag) {
1482                                         ebone->flag &= ~val_p->flag;
1483                                 }
1484                         }
1485                 }
1486         }
1487
1488         if (arm->flag & ARM_MIRROR_EDIT) {
1489                 BLI_ghash_free(ebone_flag_orig, NULL, NULL);
1490         }
1491
1492         if (!changed) {
1493                 return OPERATOR_CANCELLED;
1494         }
1495
1496         ED_armature_sync_selection(arm->edbo);
1497
1498         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1499
1500         return OPERATOR_FINISHED;
1501 }
1502
1503 void ARMATURE_OT_dissolve(wmOperatorType *ot)
1504 {
1505         /* identifiers */
1506         ot->name = "Dissolve Selected Bone(s)";
1507         ot->idname = "ARMATURE_OT_dissolve";
1508         ot->description = "Dissolve selected bones from the armature";
1509
1510         /* api callbacks */
1511         ot->exec = armature_dissolve_selected_exec;
1512         ot->poll = ED_operator_editarmature;
1513
1514         /* flags */
1515         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1516 }
1517
1518
1519
1520 /* ********************************* Show/Hide ******************************* */
1521
1522 static int armature_hide_exec(bContext *C, wmOperator *op)
1523 {
1524         Object *obedit = CTX_data_edit_object(C);
1525         bArmature *arm = obedit->data;
1526         EditBone *ebone;
1527         const int invert = RNA_boolean_get(op->ptr, "unselected") ? BONE_SELECTED : 0;
1528
1529         /* cancel if nothing selected */
1530         if (CTX_DATA_COUNT(C, selected_bones) == 0)
1531                 return OPERATOR_CANCELLED;
1532
1533         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1534                 if (EBONE_VISIBLE(arm, ebone)) {
1535                         if ((ebone->flag & BONE_SELECTED) != invert) {
1536                                 ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
1537                                 ebone->flag |= BONE_HIDDEN_A;
1538                         }
1539                 }
1540         }
1541         ED_armature_validate_active(arm);
1542         ED_armature_sync_selection(arm->edbo);
1543
1544         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1545
1546         return OPERATOR_FINISHED;
1547 }
1548
1549 void ARMATURE_OT_hide(wmOperatorType *ot)
1550 {
1551         /* identifiers */
1552         ot->name = "Hide Selected Bones";
1553         ot->idname = "ARMATURE_OT_hide";
1554         ot->description = "Tag selected bones to not be visible in Edit Mode";
1555         
1556         /* api callbacks */
1557         ot->exec = armature_hide_exec;
1558         ot->poll = ED_operator_editarmature;
1559         
1560         /* flags */
1561         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1562
1563         /* props */
1564         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
1565 }
1566
1567 static int armature_reveal_exec(bContext *C, wmOperator *op)
1568 {
1569         Object *obedit = CTX_data_edit_object(C);
1570         bArmature *arm = obedit->data;
1571         EditBone *ebone;
1572         const bool select = RNA_boolean_get(op->ptr, "select");
1573         
1574         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1575                 if (arm->layer & ebone->layer) {
1576                         if (ebone->flag & BONE_HIDDEN_A) {
1577                                 if (!(ebone->flag & BONE_UNSELECTABLE)) {
1578                                         SET_FLAG_FROM_TEST(ebone->flag, select, (BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL));
1579                                 }
1580                                 ebone->flag &= ~BONE_HIDDEN_A;
1581                         }
1582                 }
1583         }
1584         ED_armature_validate_active(arm);
1585         ED_armature_sync_selection(arm->edbo);
1586
1587         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1588
1589         return OPERATOR_FINISHED;
1590 }
1591
1592 void ARMATURE_OT_reveal(wmOperatorType *ot)
1593 {
1594         /* identifiers */
1595         ot->name = "Reveal Bones";
1596         ot->idname = "ARMATURE_OT_reveal";
1597         ot->description = "Reveal all bones hidden in Edit Mode";
1598         
1599         /* api callbacks */
1600         ot->exec = armature_reveal_exec;
1601         ot->poll = ED_operator_editarmature;
1602         
1603         /* flags */
1604         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1605
1606         RNA_def_boolean(ot->srna, "select", true, "Select", "");
1607 }