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