Merge branch 'master' into blender2.8
[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_layer.h"
52 #include "BKE_global.h"
53 #include "BKE_report.h"
54 #include "BKE_object.h"
55
56 #include "RNA_access.h"
57 #include "RNA_define.h"
58
59 #include "WM_api.h"
60 #include "WM_types.h"
61
62 #include "ED_armature.h"
63 #include "ED_screen.h"
64 #include "ED_view3d.h"
65
66 #include "armature_intern.h"
67
68 /* ************************** Object Tools Exports ******************************* */
69 /* NOTE: these functions are exported to the Object module to be called from the tools there */
70
71 void ED_armature_transform_apply(Object *ob, float mat[4][4], const bool do_props)
72 {
73         bArmature *arm = ob->data;
74
75         /* Put the armature into editmode */
76         ED_armature_to_edit(arm);
77
78         /* Transform the bones */
79         ED_armature_transform_bones(arm, mat, do_props);
80
81         /* Turn the list into an armature */
82         ED_armature_from_edit(arm);
83         ED_armature_edit_free(arm);
84 }
85
86 void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props)
87 {
88         EditBone *ebone;
89         float scale = mat4_to_scale(mat);   /* store the scale of the matrix here to use on envelopes */
90         float mat3[3][3];
91
92         copy_m3_m4(mat3, mat);
93         normalize_m3(mat3);
94         /* Do the rotations */
95         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
96                 float tmat[3][3];
97
98                 /* find the current bone's roll matrix */
99                 ED_armature_ebone_to_mat3(ebone, tmat);
100
101                 /* transform the roll matrix */
102                 mul_m3_m3m3(tmat, mat3, tmat);
103
104                 /* transform the bone */
105                 mul_m4_v3(mat, ebone->head);
106                 mul_m4_v3(mat, ebone->tail);
107
108                 /* apply the transformed roll back */
109                 mat3_to_vec_roll(tmat, NULL, &ebone->roll);
110
111                 if (do_props) {
112                         ebone->rad_head *= scale;
113                         ebone->rad_tail *= scale;
114                         ebone->dist     *= scale;
115
116                         /* we could be smarter and scale by the matrix along the x & z axis */
117                         ebone->xwidth   *= scale;
118                         ebone->zwidth   *= scale;
119                 }
120         }
121 }
122
123 void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props)
124 {
125         if (arm->edbo) {
126                 ED_armature_transform_bones(arm, mat, do_props);
127         }
128         else {
129                 /* Put the armature into editmode */
130                 ED_armature_to_edit(arm);
131
132                 /* Transform the bones */
133                 ED_armature_transform_bones(arm, mat, do_props);
134
135                 /* Go back to object mode*/
136                 ED_armature_from_edit(arm);
137                 ED_armature_edit_free(arm);
138         }
139 }
140
141 /* exported for use in editors/object/ */
142 /* 0 == do center, 1 == center new, 2 == center cursor */
143 void ED_armature_origin_set(Object *ob, float cursor[3], int centermode, int around)
144 {
145         const bool is_editmode = BKE_object_is_in_editmode(ob);
146         EditBone *ebone;
147         bArmature *arm = ob->data;
148         float cent[3];
149
150         /* Put the armature into editmode */
151         if (is_editmode == false) {
152                 ED_armature_to_edit(arm);
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 (is_editmode == false) {
193                 ED_armature_from_edit(arm);
194                 ED_armature_edit_free(arm);
195         }
196
197         /* Adjust object location for new centerpoint */
198         if (centermode && (is_editmode == false)) {
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 View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d);
322
323                 invert_m4_m4(ob->imat, ob->obmat);
324                 copy_v3_v3(cursor_local, cursor->location);
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_active = CTX_data_edit_object(C);
635         Scene *scene = CTX_data_scene(C);
636         View3D *v3d = CTX_wm_view3d(C);
637         ListBase points = {NULL, NULL};
638         EditBone *newbone = NULL;
639         int count;
640         bool mixed_object_error = false;
641
642         /* sanity checks */
643         if (ELEM(NULL, obedit_active, obedit_active->data)) {
644                 return OPERATOR_CANCELLED;
645         }
646
647         /* loop over all bones, and only consider if visible */
648         bArmature *arm = NULL;
649         CTX_DATA_BEGIN_WITH_ID(C, EditBone *, ebone, visible_bones, bArmature *, arm_iter)
650         {
651                 bool check = false;
652                 if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL)) {
653                         fill_add_joint(ebone, 0, &points);
654                         check = true;
655                 }
656                 if (ebone->flag & BONE_TIPSEL) {
657                         fill_add_joint(ebone, 1, &points);
658                         check = true;
659                 }
660
661                 if (check) {
662                         if (arm && (arm != arm_iter)) {
663                                 mixed_object_error = true;
664                         }
665                         arm = arm_iter;
666                 }
667         }
668         CTX_DATA_END;
669
670         /* the number of joints determines how we fill:
671          *  1) between joint and cursor (joint=head, cursor=tail)
672          *  2) between the two joints (order is dependent on active-bone/hierarchy)
673          *  3+) error (a smarter method involving finding chains needs to be worked out
674          */
675         count = BLI_listbase_count(&points);
676
677         if (count == 0) {
678                 BKE_report(op->reports, RPT_ERROR, "No joints selected");
679                 return OPERATOR_CANCELLED;
680         }
681         else if (mixed_object_error) {
682                 BKE_report(op->reports, RPT_ERROR, "Bones for different objects selected");
683                 BLI_freelistN(&points);
684                 return OPERATOR_CANCELLED;
685         }
686
687         Object *obedit = NULL;
688         {
689                 ViewLayer *view_layer = CTX_data_view_layer(C);
690                 FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_EDIT, ob_iter) {
691                         if (ob_iter->data == arm) {
692                                 obedit = ob_iter;
693                         }
694                 }
695                 FOREACH_OBJECT_IN_MODE_END;
696         }
697         BLI_assert(obedit != NULL);
698
699         if (count == 1) {
700                 EditBonePoint *ebp;
701                 float curs[3];
702
703                 /* Get Points - selected joint */
704                 ebp = points.first;
705
706                 /* Get points - cursor (tail) */
707                 invert_m4_m4(obedit->imat, obedit->obmat);
708                 mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location);
709
710                 /* Create a bone */
711                 newbone = add_points_bone(obedit, ebp->vec, curs);
712         }
713         else if (count == 2) {
714                 EditBonePoint *ebp_a, *ebp_b;
715                 float head[3], tail[3];
716                 short headtail = 0;
717
718                 /* check that the points don't belong to the same bone */
719                 ebp_a = (EditBonePoint *)points.first;
720                 ebp_b = ebp_a->next;
721
722                 if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) ||
723                     ((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL)))
724                 {
725                         BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
726                         BLI_freelistN(&points);
727                         return OPERATOR_CANCELLED;
728                 }
729
730                 /* find which one should be the 'head' */
731                 if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) {
732                         /* use active, nice predictable */
733                         if (arm->act_edbone && ELEM(arm->act_edbone, ebp_a->head_owner, ebp_a->tail_owner)) {
734                                 headtail = 1;
735                         }
736                         else if (arm->act_edbone && ELEM(arm->act_edbone, ebp_b->head_owner, ebp_b->tail_owner)) {
737                                 headtail = 2;
738                         }
739                         else {
740                                 /* rule: whichever one is closer to 3d-cursor */
741                                 float curs[3];
742                                 float dist_sq_a, dist_sq_b;
743
744                                 /* get cursor location */
745                                 invert_m4_m4(obedit->imat, obedit->obmat);
746                                 mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d)->location);
747
748                                 /* get distances */
749                                 dist_sq_a = len_squared_v3v3(ebp_a->vec, curs);
750                                 dist_sq_b = len_squared_v3v3(ebp_b->vec, curs);
751
752                                 /* compare distances - closer one therefore acts as direction for bone to go */
753                                 headtail = (dist_sq_a < dist_sq_b) ? 2 : 1;
754                         }
755                 }
756                 else if (ebp_a->head_owner) {
757                         headtail = 1;
758                 }
759                 else if (ebp_b->head_owner) {
760                         headtail = 2;
761                 }
762
763                 /* assign head/tail combinations */
764                 if (headtail == 2) {
765                         copy_v3_v3(head, ebp_a->vec);
766                         copy_v3_v3(tail, ebp_b->vec);
767                 }
768                 else if (headtail == 1) {
769                         copy_v3_v3(head, ebp_b->vec);
770                         copy_v3_v3(tail, ebp_a->vec);
771                 }
772
773                 /* add new bone and parent it to the appropriate end */
774                 if (headtail) {
775                         newbone = add_points_bone(obedit, head, tail);
776
777                         /* do parenting (will need to set connected flag too) */
778                         if (headtail == 2) {
779                                 /* ebp tail or head - tail gets priority */
780                                 if (ebp_a->tail_owner)
781                                         newbone->parent = ebp_a->tail_owner;
782                                 else
783                                         newbone->parent = ebp_a->head_owner;
784                         }
785                         else {
786                                 /* ebp_b tail or head - tail gets priority */
787                                 if (ebp_b->tail_owner)
788                                         newbone->parent = ebp_b->tail_owner;
789                                 else
790                                         newbone->parent = ebp_b->head_owner;
791                         }
792
793                         /* don't set for bone connecting two head points of bones */
794                         if (ebp_a->tail_owner || ebp_b->tail_owner) {
795                                 newbone->flag |= BONE_CONNECTED;
796                         }
797                 }
798         }
799         else {
800                 /* FIXME.. figure out a method for multiple bones */
801                 BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d", count);
802                 BLI_freelistN(&points);
803                 return OPERATOR_CANCELLED;
804         }
805
806         if (newbone) {
807                 ED_armature_edit_deselect_all(obedit);
808                 arm->act_edbone = newbone;
809                 newbone->flag |= BONE_TIPSEL;
810         }
811
812         /* updates */
813         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
814
815         /* free points */
816         BLI_freelistN(&points);
817
818         return OPERATOR_FINISHED;
819 }
820
821 void ARMATURE_OT_fill(wmOperatorType *ot)
822 {
823         /* identifiers */
824         ot->name = "Fill Between Joints";
825         ot->idname = "ARMATURE_OT_fill";
826         ot->description = "Add bone between selected joint(s) and/or 3D-Cursor";
827
828         /* callbacks */
829         ot->exec = armature_fill_bones_exec;
830         ot->poll = ED_operator_editarmature;
831
832         /* flags */
833         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
834 }
835
836 /* --------------------- */
837
838 /* this function merges between two bones, removes them and those in-between,
839  * and adjusts the parent relationships for those in-between
840  */
841 static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
842 {
843         bArmature *arm = obedit->data;
844         EditBone *ebo, *ebone, *newbone;
845         LinkData *chain;
846         float head[3], tail[3];
847
848         /* check if same bone */
849         if (start == end) {
850                 if (G.debug & G_DEBUG) {
851                         printf("Error: same bone!\n");
852                         printf("\tstart = %s, end = %s\n", start->name, end->name);
853                 }
854         }
855
856         /* step 1: add a new bone
857          *      - head = head/tail of start (default head)
858          *      - tail = head/tail of end (default tail)
859          *      - parent = parent of start
860          */
861         if ((start->flag & BONE_TIPSEL) && (start->flag & BONE_SELECTED) == 0) {
862                 copy_v3_v3(head, start->tail);
863         }
864         else {
865                 copy_v3_v3(head, start->head);
866         }
867         if ((end->flag & BONE_ROOTSEL) && (end->flag & BONE_SELECTED) == 0) {
868                 copy_v3_v3(tail, end->head);
869         }
870         else {
871                 copy_v3_v3(tail, end->tail);
872         }
873         newbone = add_points_bone(obedit, head, tail);
874         newbone->parent = start->parent;
875
876         /* TODO, copy more things to the new bone */
877         newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE |
878                                        BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE);
879
880         /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge
881          *      - potentially several tips for side chains leading to some tree exist...
882          */
883         for (chain = chains->first; chain; chain = chain->next) {
884                 /* traverse down chain until we hit the bottom or if we run into the tip of the chain of bones we're
885                  * merging (need to stop in this case to avoid corrupting this chain too!)
886                  */
887                 for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) {
888                         short found = 0;
889
890                         /* check if this bone is parented to one in the merging chain
891                          * ! WATCHIT: must only go check until end of checking chain
892                          */
893                         for (ebo = end; (ebo) && (ebo != start->parent); ebo = ebo->parent) {
894                                 /* side-chain found? --> remap parent to new bone, then we're done with this chain :) */
895                                 if (ebone->parent == ebo) {
896                                         ebone->parent = newbone;
897                                         found = 1;
898                                         break;
899                                 }
900                         }
901
902                         /* carry on to the next tip now  */
903                         if (found)
904                                 break;
905                 }
906         }
907
908         /* step 2b: parent child of end to newbone (child from this chain) */
909         if (endchild)
910                 endchild->parent = newbone;
911
912         /* step 3: delete all bones between and including start and end */
913         for (ebo = end; ebo; ebo = ebone) {
914                 ebone = (ebo == start) ? (NULL) : (ebo->parent);
915                 bone_free(arm, ebo);
916         }
917
918         newbone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
919         ED_armature_edit_sync_selection(arm->edbo);
920 }
921
922
923 static int armature_merge_exec(bContext *C, wmOperator *op)
924 {
925         Object *obedit = CTX_data_edit_object(C);
926         bArmature *arm = (obedit) ? obedit->data : NULL;
927         short type = RNA_enum_get(op->ptr, "type");
928
929         /* sanity checks */
930         if (ELEM(NULL, obedit, arm))
931                 return OPERATOR_CANCELLED;
932
933         /* for now, there's only really one type of merging that's performed... */
934         if (type == 1) {
935                 /* go down chains, merging bones */
936                 ListBase chains = {NULL, NULL};
937                 LinkData *chain, *nchain;
938                 EditBone *ebo;
939
940                 armature_tag_select_mirrored(arm);
941
942                 /* get chains (ends on chains) */
943                 chains_find_tips(arm->edbo, &chains);
944                 if (BLI_listbase_is_empty(&chains)) return OPERATOR_CANCELLED;
945
946                 /* each 'chain' is the last bone in the chain (with no children) */
947                 for (chain = chains.first; chain; chain = nchain) {
948                         EditBone *bstart = NULL, *bend = NULL;
949                         EditBone *bchild = NULL, *child = NULL;
950
951                         /* temporarily remove chain from list of chains */
952                         nchain = chain->next;
953                         BLI_remlink(&chains, chain);
954
955                         /* only consider bones that are visible and selected */
956                         for (ebo = chain->data; ebo; child = ebo, ebo = ebo->parent) {
957                                 /* check if visible + selected */
958                                 if (EBONE_VISIBLE(arm, ebo) &&
959                                     ((ebo->flag & BONE_CONNECTED) || (ebo->parent == NULL)) &&
960                                     (ebo->flag & BONE_SELECTED) )
961                                 {
962                                         /* set either end or start (end gets priority, unless it is already set) */
963                                         if (bend == NULL) {
964                                                 bend = ebo;
965                                                 bchild = child;
966                                         }
967                                         else
968                                                 bstart = ebo;
969                                 }
970                                 else {
971                                         /* chain is broken... merge any continous segments then clear */
972                                         if (bstart && bend)
973                                                 bones_merge(obedit, bstart, bend, bchild, &chains);
974
975                                         bstart = NULL;
976                                         bend = NULL;
977                                         bchild = NULL;
978                                 }
979                         }
980
981                         /* merge from bstart to bend if something not merged */
982                         if (bstart && bend)
983                                 bones_merge(obedit, bstart, bend, bchild, &chains);
984
985                         /* put back link */
986                         BLI_insertlinkbefore(&chains, nchain, chain);
987                 }
988
989                 armature_tag_unselect(arm);
990
991                 BLI_freelistN(&chains);
992         }
993
994         /* updates */
995         ED_armature_edit_sync_selection(arm->edbo);
996         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
997
998         return OPERATOR_FINISHED;
999 }
1000
1001 void ARMATURE_OT_merge(wmOperatorType *ot)
1002 {
1003         static const EnumPropertyItem merge_types[] = {
1004                 {1, "WITHIN_CHAIN", 0, "Within Chains", ""},
1005                 {0, NULL, 0, NULL, NULL}
1006         };
1007
1008         /* identifiers */
1009         ot->name = "Merge Bones";
1010         ot->idname = "ARMATURE_OT_merge";
1011         ot->description = "Merge continuous chains of selected bones";
1012
1013         /* callbacks */
1014         ot->invoke = WM_menu_invoke;
1015         ot->exec = armature_merge_exec;
1016         ot->poll = ED_operator_editarmature;
1017
1018         /* flags */
1019         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1020
1021         /* properties */
1022         ot->prop = RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
1023 }
1024
1025 /* --------------------- */
1026
1027 /* Switch Direction operator:
1028  * Currently, this does not use context loops, as context loops do not make it
1029  * easy to retrieve any hierarchical/chain relationships which are necessary for
1030  * this to be done easily.
1031  */
1032
1033 /* helper to clear BONE_TRANSFORM flags */
1034 static void armature_clear_swap_done_flags(bArmature *arm)
1035 {
1036         EditBone *ebone;
1037
1038         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1039                 ebone->flag &= ~BONE_TRANSFORM;
1040         }
1041 }
1042
1043 static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
1044 {
1045         Object *ob = CTX_data_edit_object(C);
1046         bArmature *arm = (bArmature *)ob->data;
1047         ListBase chains = {NULL, NULL};
1048         LinkData *chain;
1049
1050         /* get chains of bones (ends on chains) */
1051         chains_find_tips(arm->edbo, &chains);
1052         if (BLI_listbase_is_empty(&chains)) return OPERATOR_CANCELLED;
1053
1054         /* ensure that mirror bones will also be operated on */
1055         armature_tag_select_mirrored(arm);
1056
1057         /* clear BONE_TRANSFORM flags
1058          * - used to prevent duplicate/canceling operations from occurring [#34123]
1059          * - BONE_DONE cannot be used here as that's already used for mirroring
1060          */
1061         armature_clear_swap_done_flags(arm);
1062
1063         /* loop over chains, only considering selected and visible bones */
1064         for (chain = chains.first; chain; chain = chain->next) {
1065                 EditBone *ebo, *child = NULL, *parent = NULL;
1066
1067                 /* loop over bones in chain */
1068                 for (ebo = chain->data; ebo; ebo = parent) {
1069                         /* parent is this bone's original parent
1070                          *      - we store this, as the next bone that is checked is this one
1071                          *        but the value of ebo->parent may change here...
1072                          */
1073                         parent = ebo->parent;
1074
1075                         /* skip bone if already handled... [#34123] */
1076                         if ((ebo->flag & BONE_TRANSFORM) == 0) {
1077                                 /* only if selected and editable */
1078                                 if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
1079                                         /* swap head and tail coordinates */
1080                                         swap_v3_v3(ebo->head, ebo->tail);
1081
1082                                         /* do parent swapping:
1083                                          *      - use 'child' as new parent
1084                                          *      - connected flag is only set if points are coincidental
1085                                          */
1086                                         ebo->parent = child;
1087                                         if ((child) && equals_v3v3(ebo->head, child->tail))
1088                                                 ebo->flag |= BONE_CONNECTED;
1089                                         else
1090                                                 ebo->flag &= ~BONE_CONNECTED;
1091
1092                                         /* get next bones
1093                                          *      - child will become the new parent of next bone
1094                                          */
1095                                         child = ebo;
1096                                 }
1097                                 else {
1098                                         /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it
1099                                          * as it will be facing in opposite direction
1100                                          */
1101                                         if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
1102                                                 ebo->parent = NULL;
1103                                                 ebo->flag &= ~BONE_CONNECTED;
1104                                         }
1105
1106                                         /* get next bones
1107                                          *      - child will become new parent of next bone (not swapping occurred,
1108                                          *        so set to NULL to prevent infinite-loop)
1109                                          */
1110                                         child = NULL;
1111                                 }
1112
1113                                 /* tag as done (to prevent double-swaps) */
1114                                 ebo->flag |= BONE_TRANSFORM;
1115                         }
1116                 }
1117         }
1118
1119         /* free chains */
1120         BLI_freelistN(&chains);
1121
1122         /* clear temp flags */
1123         armature_clear_swap_done_flags(arm);
1124         armature_tag_unselect(arm);
1125
1126         /* note, notifier might evolve */
1127         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1128
1129         return OPERATOR_FINISHED;
1130 }
1131
1132 void ARMATURE_OT_switch_direction(wmOperatorType *ot)
1133 {
1134         /* identifiers */
1135         ot->name = "Switch Direction";
1136         ot->idname = "ARMATURE_OT_switch_direction";
1137         ot->description = "Change the direction that a chain of bones points in (head <-> tail swap)";
1138
1139         /* api callbacks */
1140         ot->exec = armature_switch_direction_exec;
1141         ot->poll = ED_operator_editarmature;
1142
1143         /* flags */
1144         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1145 }
1146
1147 /* ********************************* Align ******************************* */
1148
1149 /* helper to fix a ebone position if its parent has moved due to alignment*/
1150 static void fix_connected_bone(EditBone *ebone)
1151 {
1152         float diff[3];
1153
1154         if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) || equals_v3v3(ebone->parent->tail, ebone->head))
1155                 return;
1156
1157         /* if the parent has moved we translate child's head and tail accordingly */
1158         sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
1159         add_v3_v3(ebone->head, diff);
1160         add_v3_v3(ebone->tail, diff);
1161 }
1162
1163 /* helper to recursively find chains of connected bones starting at ebone and fix their position */
1164 static void fix_editbone_connected_children(ListBase *edbo, EditBone *ebone)
1165 {
1166         EditBone *selbone;
1167
1168         for (selbone = edbo->first; selbone; selbone = selbone->next) {
1169                 if ((selbone->parent) && (selbone->parent == ebone) && (selbone->flag & BONE_CONNECTED)) {
1170                         fix_connected_bone(selbone);
1171                         fix_editbone_connected_children(edbo, selbone);
1172                 }
1173         }
1174 }
1175
1176 static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actbone)
1177 {
1178         float selboneaxis[3], actboneaxis[3], length;
1179
1180         sub_v3_v3v3(actboneaxis, actbone->tail, actbone->head);
1181         normalize_v3(actboneaxis);
1182
1183         sub_v3_v3v3(selboneaxis, selbone->tail, selbone->head);
1184         length =  len_v3(selboneaxis);
1185
1186         mul_v3_fl(actboneaxis, length);
1187         add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
1188         selbone->roll = actbone->roll;
1189
1190         /* if the bone being aligned has connected descendants they must be moved
1191          * according to their parent new position, otherwise they would be left
1192          * in an inconsistent state: connected but away from the parent*/
1193         fix_editbone_connected_children(edbo, selbone);
1194 }
1195
1196 static int armature_align_bones_exec(bContext *C, wmOperator *op)
1197 {
1198         Object *ob = CTX_data_edit_object(C);
1199         bArmature *arm = (bArmature *)ob->data;
1200         EditBone *actbone = CTX_data_active_bone(C);
1201         EditBone *actmirb = NULL;
1202         int num_selected_bones;
1203
1204         /* there must be an active bone */
1205         if (actbone == NULL) {
1206                 BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
1207                 return OPERATOR_CANCELLED;
1208         }
1209         else if (arm->flag & ARM_MIRROR_EDIT) {
1210                 /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
1211                  * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
1212                  *   (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
1213                  *   This is useful for arm-chains, for example parenting lower arm to upper arm
1214                  * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
1215                  *   then just use actbone. Useful when doing upper arm to spine.
1216                  */
1217                 actmirb = ED_armature_ebone_get_mirrored(arm->edbo, actbone);
1218                 if (actmirb == NULL)
1219                         actmirb = actbone;
1220         }
1221
1222         /* if there is only 1 selected bone, we assume that that is the active bone,
1223          * since a user will need to have clicked on a bone (thus selecting it) to make it active
1224          */
1225         num_selected_bones = CTX_DATA_COUNT(C, selected_editable_bones);
1226         if (num_selected_bones <= 1) {
1227                 /* When only the active bone is selected, and it has a parent,
1228                  * align it to the parent, as that is the only possible outcome.
1229                  */
1230                 if (actbone->parent) {
1231                         bone_align_to_bone(arm->edbo, actbone, actbone->parent);
1232
1233                         if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
1234                                 bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
1235
1236                         BKE_reportf(op->reports, RPT_INFO, "Aligned bone '%s' to parent", actbone->name);
1237                 }
1238         }
1239         else {
1240                 /* Align 'selected' bones to the active one
1241                  * - the context iterator contains both selected bones and their mirrored copies,
1242                  *   so we assume that unselected bones are mirrored copies of some selected bone
1243                  * - since the active one (and/or its mirror) will also be selected, we also need
1244                  *   to check that we are not trying to operate on them, since such an operation
1245                  *   would cause errors
1246                  */
1247
1248                 /* align selected bones to the active one */
1249                 CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
1250                 {
1251                         if (ELEM(ebone, actbone, actmirb) == 0) {
1252                                 if (ebone->flag & BONE_SELECTED)
1253                                         bone_align_to_bone(arm->edbo, ebone, actbone);
1254                                 else
1255                                         bone_align_to_bone(arm->edbo, ebone, actmirb);
1256                         }
1257                 }
1258                 CTX_DATA_END;
1259
1260                 BKE_reportf(op->reports, RPT_INFO, "%d bones aligned to bone '%s'", num_selected_bones, actbone->name);
1261         }
1262
1263         /* note, notifier might evolve */
1264         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1265
1266         return OPERATOR_FINISHED;
1267 }
1268
1269 void ARMATURE_OT_align(wmOperatorType *ot)
1270 {
1271         /* identifiers */
1272         ot->name = "Align Bones";
1273         ot->idname = "ARMATURE_OT_align";
1274         ot->description = "Align selected bones to the active bone (or to their parent)";
1275
1276         /* api callbacks */
1277         ot->exec = armature_align_bones_exec;
1278         ot->poll = ED_operator_editarmature;
1279
1280         /* flags */
1281         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1282 }
1283
1284 /* ********************************* Split ******************************* */
1285
1286 static int armature_split_exec(bContext *C, wmOperator *UNUSED(op))
1287 {
1288         Object *ob = CTX_data_edit_object(C);
1289         bArmature *arm = (bArmature *)ob->data;
1290         EditBone *bone;
1291
1292         for (bone = arm->edbo->first; bone; bone = bone->next) {
1293                 if (bone->parent && (bone->flag & BONE_SELECTED) != (bone->parent->flag & BONE_SELECTED)) {
1294                         bone->parent = NULL;
1295                         bone->flag &= ~BONE_CONNECTED;
1296                 }
1297         }
1298         for (bone = arm->edbo->first; bone; bone = bone->next) {
1299                 ED_armature_ebone_select_set(bone, (bone->flag & BONE_SELECTED) != 0);
1300         }
1301
1302         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1303
1304         return OPERATOR_FINISHED;
1305 }
1306
1307 void ARMATURE_OT_split(wmOperatorType *ot)
1308 {
1309         /* identifiers */
1310         ot->name = "Split";
1311         ot->idname = "ARMATURE_OT_split";
1312         ot->description = "Split off selected bones from connected unselected bones";
1313
1314         /* api callbacks */
1315         ot->exec = armature_split_exec;
1316         ot->poll = ED_operator_editarmature;
1317
1318         /* flags */
1319         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1320 }
1321
1322 /* ********************************* Delete ******************************* */
1323
1324 static bool armature_delete_ebone_cb(const char *bone_name, void *arm_p)
1325 {
1326         bArmature *arm = arm_p;
1327         EditBone *ebone;
1328
1329         ebone = ED_armature_ebone_find_name(arm->edbo, bone_name);
1330         return (ebone && (ebone->flag & BONE_SELECTED) && (arm->layer & ebone->layer));
1331 }
1332
1333 /* previously delete_armature */
1334 /* only editmode! */
1335 static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
1336 {
1337         EditBone *curBone, *ebone_next;
1338         bool changed_multi = false;
1339
1340         /* cancel if nothing selected */
1341         if (CTX_DATA_COUNT(C, selected_bones) == 0)
1342                 return OPERATOR_CANCELLED;
1343
1344         ViewLayer *view_layer = CTX_data_view_layer(C);
1345         uint objects_len = 0;
1346         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
1347         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1348                 Object *obedit = objects[ob_index];
1349                 bArmature *arm = obedit->data;
1350                 bool changed = false;
1351
1352                 armature_select_mirrored(arm);
1353
1354                 BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm);
1355
1356                 for (curBone = arm->edbo->first; curBone; curBone = ebone_next) {
1357                         ebone_next = curBone->next;
1358                         if (arm->layer & curBone->layer) {
1359                                 if (curBone->flag & BONE_SELECTED) {
1360                                         if (curBone == arm->act_edbone) arm->act_edbone = NULL;
1361                                         ED_armature_ebone_remove(arm, curBone);
1362                                         changed = true;
1363                                 }
1364                         }
1365                 }
1366
1367                 if (changed) {
1368                         changed_multi = true;
1369
1370                         ED_armature_edit_sync_selection(arm->edbo);
1371                         BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose);
1372
1373                         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1374                 }
1375         }
1376         MEM_freeN(objects);
1377
1378         if (!changed_multi) {
1379                 return OPERATOR_CANCELLED;
1380         }
1381
1382         return OPERATOR_FINISHED;
1383 }
1384
1385 void ARMATURE_OT_delete(wmOperatorType *ot)
1386 {
1387         /* identifiers */
1388         ot->name = "Delete Selected Bone(s)";
1389         ot->idname = "ARMATURE_OT_delete";
1390         ot->description = "Remove selected bones from the armature";
1391
1392         /* api callbacks */
1393         ot->invoke = WM_operator_confirm;
1394         ot->exec = armature_delete_selected_exec;
1395         ot->poll = ED_operator_editarmature;
1396
1397         /* flags */
1398         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1399 }
1400
1401 static bool armature_dissolve_ebone_cb(const char *bone_name, void *arm_p)
1402 {
1403         bArmature *arm = arm_p;
1404         EditBone *ebone;
1405
1406         ebone = ED_armature_ebone_find_name(arm->edbo, bone_name);
1407         return (ebone && (ebone->flag & BONE_DONE));
1408 }
1409
1410 static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op))
1411 {
1412         bArmature *arm;
1413         EditBone *ebone, *ebone_next;
1414         Object *obedit = CTX_data_edit_object(C);
1415         bool changed = false;
1416
1417         /* store for mirror */
1418         GHash *ebone_flag_orig = NULL;
1419         int ebone_num = 0;
1420
1421         arm = obedit->data;
1422
1423         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1424                 ebone->temp.p = NULL;
1425                 ebone->flag &= ~BONE_DONE;
1426                 ebone_num++;
1427         }
1428
1429         if (arm->flag & ARM_MIRROR_EDIT) {
1430                 GHashIterator gh_iter;
1431
1432                 ebone_flag_orig = BLI_ghash_ptr_new_ex(__func__, ebone_num);
1433                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1434                         union { int flag; void *p; } val = {0};
1435                         val.flag = ebone->flag;
1436                         BLI_ghash_insert(ebone_flag_orig, ebone, val.p);
1437                 }
1438
1439                 armature_select_mirrored_ex(arm, BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
1440
1441                 GHASH_ITER (gh_iter, ebone_flag_orig) {
1442                         union { int flag; void *p; } *val_p = (void *)BLI_ghashIterator_getValue_p(&gh_iter);
1443                         ebone = BLI_ghashIterator_getKey(&gh_iter);
1444                         val_p->flag = ebone->flag & ~val_p->flag;
1445                 }
1446         }
1447
1448         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1449                 if (ebone->parent && ebone->flag & BONE_CONNECTED) {
1450                         if (ebone->parent->temp.ebone == ebone->parent) {
1451                                 /* ignore */
1452                         }
1453                         else if (ebone->parent->temp.ebone) {
1454                                 /* set ignored */
1455                                 ebone->parent->temp.ebone = ebone->parent;
1456                         }
1457                         else {
1458                                 /* set child */
1459                                 ebone->parent->temp.ebone = ebone;
1460                         }
1461                 }
1462         }
1463
1464         /* cleanup multiple used bones */
1465         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1466                 if (ebone->temp.ebone == ebone) {
1467                         ebone->temp.ebone = NULL;
1468                 }
1469         }
1470
1471         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1472                 /* break connections for unseen bones */
1473                 if (((arm->layer & ebone->layer) &&
1474                      ((ED_armature_ebone_selectflag_get(ebone) & (BONE_TIPSEL | BONE_SELECTED)))) == 0)
1475                 {
1476                         ebone->temp.ebone = NULL;
1477                 }
1478
1479                 if (((arm->layer & ebone->layer) &&
1480                     ((ED_armature_ebone_selectflag_get(ebone) & (BONE_ROOTSEL | BONE_SELECTED)))) == 0)
1481                 {
1482                         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
1483                                 ebone->parent->temp.ebone = NULL;
1484                         }
1485
1486                 }
1487         }
1488
1489         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1490
1491                 if (ebone->parent &&
1492                     (ebone->parent->temp.ebone == ebone))
1493                 {
1494                         ebone->flag |= BONE_DONE;
1495                 }
1496         }
1497
1498         BKE_pose_channels_remove(obedit, armature_dissolve_ebone_cb, arm);
1499
1500         for (ebone = arm->edbo->first; ebone; ebone = ebone_next) {
1501                 ebone_next = ebone->next;
1502
1503                 if (ebone->flag & BONE_DONE) {
1504                         copy_v3_v3(ebone->parent->tail, ebone->tail);
1505                         ebone->parent->rad_tail = ebone->rad_tail;
1506                         SET_FLAG_FROM_TEST(ebone->parent->flag, ebone->flag & BONE_TIPSEL, BONE_TIPSEL);
1507
1508                         ED_armature_ebone_remove_ex(arm, ebone, false);
1509                         changed = true;
1510                 }
1511         }
1512
1513         if (changed) {
1514                 for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1515                         if (ebone->parent &&
1516                             ebone->parent->temp.ebone &&
1517                             (ebone->flag & BONE_CONNECTED))
1518                         {
1519                                 ebone->rad_head = ebone->parent->rad_tail;
1520                         }
1521                 }
1522
1523                 if (arm->flag & ARM_MIRROR_EDIT) {
1524                         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1525                                 union { int flag; void *p; } *val_p = (void *)BLI_ghash_lookup_p(ebone_flag_orig, ebone);
1526                                 if (val_p && val_p->flag) {
1527                                         ebone->flag &= ~val_p->flag;
1528                                 }
1529                         }
1530                 }
1531         }
1532
1533         if (arm->flag & ARM_MIRROR_EDIT) {
1534                 BLI_ghash_free(ebone_flag_orig, NULL, NULL);
1535         }
1536
1537         if (!changed) {
1538                 return OPERATOR_CANCELLED;
1539         }
1540
1541         ED_armature_edit_sync_selection(arm->edbo);
1542
1543         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1544
1545         return OPERATOR_FINISHED;
1546 }
1547
1548 void ARMATURE_OT_dissolve(wmOperatorType *ot)
1549 {
1550         /* identifiers */
1551         ot->name = "Dissolve Selected Bone(s)";
1552         ot->idname = "ARMATURE_OT_dissolve";
1553         ot->description = "Dissolve selected bones from the armature";
1554
1555         /* api callbacks */
1556         ot->exec = armature_dissolve_selected_exec;
1557         ot->poll = ED_operator_editarmature;
1558
1559         /* flags */
1560         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1561 }
1562
1563
1564
1565 /* ********************************* Show/Hide ******************************* */
1566
1567 static int armature_hide_exec(bContext *C, wmOperator *op)
1568 {
1569         Object *obedit = CTX_data_edit_object(C);
1570         bArmature *arm = obedit->data;
1571         EditBone *ebone;
1572         const int invert = RNA_boolean_get(op->ptr, "unselected") ? BONE_SELECTED : 0;
1573
1574         /* cancel if nothing selected */
1575         if (CTX_DATA_COUNT(C, selected_bones) == 0)
1576                 return OPERATOR_CANCELLED;
1577
1578         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1579                 if (EBONE_VISIBLE(arm, ebone)) {
1580                         if ((ebone->flag & BONE_SELECTED) != invert) {
1581                                 ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
1582                                 ebone->flag |= BONE_HIDDEN_A;
1583                         }
1584                 }
1585         }
1586         ED_armature_edit_validate_active(arm);
1587         ED_armature_edit_sync_selection(arm->edbo);
1588
1589         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1590
1591         return OPERATOR_FINISHED;
1592 }
1593
1594 void ARMATURE_OT_hide(wmOperatorType *ot)
1595 {
1596         /* identifiers */
1597         ot->name = "Hide Selected Bones";
1598         ot->idname = "ARMATURE_OT_hide";
1599         ot->description = "Tag selected bones to not be visible in Edit Mode";
1600
1601         /* api callbacks */
1602         ot->exec = armature_hide_exec;
1603         ot->poll = ED_operator_editarmature;
1604
1605         /* flags */
1606         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1607
1608         /* props */
1609         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
1610 }
1611
1612 static int armature_reveal_exec(bContext *C, wmOperator *op)
1613 {
1614         Object *obedit = CTX_data_edit_object(C);
1615         bArmature *arm = obedit->data;
1616         EditBone *ebone;
1617         const bool select = RNA_boolean_get(op->ptr, "select");
1618
1619         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1620                 if (arm->layer & ebone->layer) {
1621                         if (ebone->flag & BONE_HIDDEN_A) {
1622                                 if (!(ebone->flag & BONE_UNSELECTABLE)) {
1623                                         SET_FLAG_FROM_TEST(ebone->flag, select, (BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL));
1624                                 }
1625                                 ebone->flag &= ~BONE_HIDDEN_A;
1626                         }
1627                 }
1628         }
1629         ED_armature_edit_validate_active(arm);
1630         ED_armature_edit_sync_selection(arm->edbo);
1631
1632         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1633
1634         return OPERATOR_FINISHED;
1635 }
1636
1637 void ARMATURE_OT_reveal(wmOperatorType *ot)
1638 {
1639         /* identifiers */
1640         ot->name = "Reveal Bones";
1641         ot->idname = "ARMATURE_OT_reveal";
1642         ot->description = "Reveal all bones hidden in Edit Mode";
1643
1644         /* api callbacks */
1645         ot->exec = armature_reveal_exec;
1646         ot->poll = ED_operator_editarmature;
1647
1648         /* flags */
1649         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1650
1651         RNA_def_boolean(ot->srna, "select", true, "Select", "");
1652 }