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