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