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