ad563e569c33a33ab6eca9b423cb2eb76cfa13b0
[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           if (normalize_v3(cursor_rel) != 0.0f) {
340             ebone->roll = ED_armature_ebone_roll_to_vector(ebone, cursor_rel, axis_only);
341             changed = true;
342           }
343         }
344       }
345     }
346     else if (ELEM(type, CALC_ROLL_TAN_POS_X, CALC_ROLL_TAN_POS_Z)) {
347       for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
348         if (ebone->parent) {
349           bool is_edit = (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone));
350           bool is_edit_parent = (EBONE_VISIBLE(arm, ebone->parent) &&
351                                  EBONE_EDITABLE(ebone->parent));
352
353           if (is_edit || is_edit_parent) {
354             EditBone *ebone_other = ebone->parent;
355             float dir_a[3];
356             float dir_b[3];
357             float vec[3];
358             bool is_vec_zero;
359
360             sub_v3_v3v3(dir_a, ebone->tail, ebone->head);
361             normalize_v3(dir_a);
362
363             /* find the first bone in the chane with a different direction */
364             do {
365               sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail);
366               normalize_v3(dir_b);
367
368               if (type == CALC_ROLL_TAN_POS_Z) {
369                 cross_v3_v3v3(vec, dir_a, dir_b);
370               }
371               else {
372                 add_v3_v3v3(vec, dir_a, dir_b);
373               }
374             } while ((is_vec_zero = (normalize_v3(vec) < 0.00001f)) &&
375                      (ebone_other = ebone_other->parent));
376
377             if (!is_vec_zero) {
378               if (axis_flip)
379                 negate_v3(vec);
380
381               if (is_edit) {
382                 ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only);
383                 changed = true;
384               }
385
386               /* parentless bones use cross product with child */
387               if (is_edit_parent) {
388                 if (ebone->parent->parent == NULL) {
389                   ebone->parent->roll = ED_armature_ebone_roll_to_vector(
390                       ebone->parent, vec, axis_only);
391                   changed = true;
392                 }
393               }
394             }
395           }
396         }
397       }
398     }
399     else {
400       float vec[3] = {0.0f, 0.0f, 0.0f};
401       if (type == CALC_ROLL_VIEW) { /* View */
402         RegionView3D *rv3d = CTX_wm_region_view3d(C);
403         if (rv3d == NULL) {
404           BKE_report(op->reports, RPT_ERROR, "No region view3d available");
405           ret = OPERATOR_CANCELLED;
406           goto cleanup;
407         }
408
409         copy_v3_v3(vec, rv3d->viewinv[2]);
410         mul_m3_v3(imat, vec);
411       }
412       else if (type == CALC_ROLL_ACTIVE) {
413         float mat[3][3];
414         bArmature *arm_active = ob_active->data;
415         ebone = (EditBone *)arm_active->act_edbone;
416         if (ebone == NULL) {
417           BKE_report(op->reports, RPT_ERROR, "No active bone set");
418           ret = OPERATOR_CANCELLED;
419           goto cleanup;
420         }
421
422         ED_armature_ebone_to_mat3(ebone, mat);
423         copy_v3_v3(vec, mat[2]);
424       }
425       else { /* Axis */
426         assert(type <= 5);
427         if (type < 3)
428           vec[type] = 1.0f;
429         else
430           vec[type - 2] = -1.0f;
431         mul_m3_v3(imat, vec);
432         normalize_v3(vec);
433       }
434
435       if (axis_flip)
436         negate_v3(vec);
437
438       for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
439         if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
440           /* roll func is a callback which assumes that all is well */
441           ebone->roll = ED_armature_ebone_roll_to_vector(ebone, vec, axis_only);
442           changed = true;
443         }
444       }
445     }
446
447     if (arm->flag & ARM_MIRROR_EDIT) {
448       for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
449         if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
450           EditBone *ebone_mirr = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
451           if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
452             ebone->roll = -ebone_mirr->roll;
453           }
454         }
455       }
456     }
457
458     if (changed) {
459       /* note, notifier might evolve */
460       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
461     }
462   }
463
464 cleanup:
465   MEM_freeN(objects);
466   return ret;
467 }
468
469 void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
470 {
471   /* identifiers */
472   ot->name = "Recalculate Roll";
473   ot->idname = "ARMATURE_OT_calculate_roll";
474   ot->description = "Automatically fix alignment of select bones' axes";
475
476   /* api callbacks */
477   ot->invoke = WM_menu_invoke;
478   ot->exec = armature_calc_roll_exec;
479   ot->poll = ED_operator_editarmature;
480
481   /* flags */
482   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
483
484   /* properties */
485   ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, CALC_ROLL_TAN_POS_X, "Type", "");
486   RNA_def_boolean(ot->srna, "axis_flip", 0, "Flip Axis", "Negate the alignment axis");
487   RNA_def_boolean(ot->srna,
488                   "axis_only",
489                   0,
490                   "Shortest Rotation",
491                   "Ignore the axis direction, use the shortest rotation to align");
492 }
493
494 static int armature_roll_clear_exec(bContext *C, wmOperator *op)
495 {
496   ViewLayer *view_layer = CTX_data_view_layer(C);
497   const float roll = RNA_float_get(op->ptr, "roll");
498
499   uint objects_len = 0;
500   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
501       view_layer, CTX_wm_view3d(C), &objects_len);
502   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
503     Object *ob = objects[ob_index];
504     bArmature *arm = ob->data;
505     bool changed = false;
506
507     for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
508       if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
509         /* Roll func is a callback which assumes that all is well. */
510         ebone->roll = roll;
511         changed = true;
512       }
513     }
514
515     if (arm->flag & ARM_MIRROR_EDIT) {
516       for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
517         if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
518           EditBone *ebone_mirr = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
519           if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
520             ebone->roll = -ebone_mirr->roll;
521             changed = true;
522           }
523         }
524       }
525     }
526
527     if (changed) {
528       /* Note, notifier might evolve. */
529       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
530     }
531   }
532   MEM_freeN(objects);
533
534   return OPERATOR_FINISHED;
535 }
536
537 void ARMATURE_OT_roll_clear(wmOperatorType *ot)
538 {
539   /* identifiers */
540   ot->name = "Clear Roll";
541   ot->idname = "ARMATURE_OT_roll_clear";
542   ot->description = "Clear roll for selected bones";
543
544   /* api callbacks */
545   ot->exec = armature_roll_clear_exec;
546   ot->poll = ED_operator_editarmature;
547
548   /* flags */
549   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
550
551   RNA_def_float_rotation(ot->srna,
552                          "roll",
553                          0,
554                          NULL,
555                          DEG2RADF(-360.0f),
556                          DEG2RADF(360.0f),
557                          "Roll",
558                          "",
559                          DEG2RADF(-360.0f),
560                          DEG2RADF(360.0f));
561 }
562
563 /* ******************************** Chain-Based Tools ********************************* */
564
565 /* temporary data-structure for merge/fill bones */
566 typedef struct EditBonePoint {
567   struct EditBonePoint *next, *prev;
568
569   EditBone *head_owner; /* EditBone which uses this point as a 'head' point */
570   EditBone *tail_owner; /* EditBone which uses this point as a 'tail' point */
571
572   float vec[3]; /* the actual location of the point in local/EditMode space */
573 } EditBonePoint;
574
575 /* find chain-tips (i.e. bones without children) */
576 static void chains_find_tips(ListBase *edbo, ListBase *list)
577 {
578   EditBone *curBone, *ebo;
579   LinkData *ld;
580
581   /* note: this is potentially very slow ... there's got to be a better way */
582   for (curBone = edbo->first; curBone; curBone = curBone->next) {
583     short stop = 0;
584
585     /* is this bone contained within any existing chain? (skip if so) */
586     for (ld = list->first; ld; ld = ld->next) {
587       for (ebo = ld->data; ebo; ebo = ebo->parent) {
588         if (ebo == curBone) {
589           stop = 1;
590           break;
591         }
592       }
593
594       if (stop)
595         break;
596     }
597     /* skip current bone if it is part of an existing chain */
598     if (stop)
599       continue;
600
601     /* is any existing chain part of the chain formed by this bone? */
602     stop = 0;
603     for (ebo = curBone->parent; ebo; ebo = ebo->parent) {
604       for (ld = list->first; ld; ld = ld->next) {
605         if (ld->data == ebo) {
606           ld->data = curBone;
607           stop = 1;
608           break;
609         }
610       }
611
612       if (stop)
613         break;
614     }
615     /* current bone has already been added to a chain? */
616     if (stop)
617       continue;
618
619     /* add current bone to a new chain */
620     ld = MEM_callocN(sizeof(LinkData), "BoneChain");
621     ld->data = curBone;
622     BLI_addtail(list, ld);
623   }
624 }
625
626 /* --------------------- */
627
628 static void fill_add_joint(EditBone *ebo, short eb_tail, ListBase *points)
629 {
630   EditBonePoint *ebp;
631   float vec[3];
632   short found = 0;
633
634   if (eb_tail) {
635     copy_v3_v3(vec, ebo->tail);
636   }
637   else {
638     copy_v3_v3(vec, ebo->head);
639   }
640
641   for (ebp = points->first; ebp; ebp = ebp->next) {
642     if (equals_v3v3(ebp->vec, vec)) {
643       if (eb_tail) {
644         if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
645           /* so this bone's tail owner is this bone */
646           ebp->tail_owner = ebo;
647           found = 1;
648           break;
649         }
650       }
651       else {
652         if ((ebp->tail_owner) && (ebo->parent == ebp->tail_owner)) {
653           /* so this bone's head owner is this bone */
654           ebp->head_owner = ebo;
655           found = 1;
656           break;
657         }
658       }
659     }
660   }
661
662   /* allocate a new point if no existing point was related */
663   if (found == 0) {
664     ebp = MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
665
666     if (eb_tail) {
667       copy_v3_v3(ebp->vec, ebo->tail);
668       ebp->tail_owner = ebo;
669     }
670     else {
671       copy_v3_v3(ebp->vec, ebo->head);
672       ebp->head_owner = ebo;
673     }
674
675     BLI_addtail(points, ebp);
676   }
677 }
678
679 /* bone adding between selected joints */
680 static int armature_fill_bones_exec(bContext *C, wmOperator *op)
681 {
682   Scene *scene = CTX_data_scene(C);
683   View3D *v3d = CTX_wm_view3d(C);
684   ListBase points = {NULL, NULL};
685   EditBone *newbone = NULL;
686   int count;
687   bool mixed_object_error = false;
688
689   /* loop over all bones, and only consider if visible */
690   bArmature *arm = NULL;
691   CTX_DATA_BEGIN_WITH_ID (C, EditBone *, ebone, visible_bones, bArmature *, arm_iter) {
692     bool check = false;
693     if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL)) {
694       fill_add_joint(ebone, 0, &points);
695       check = true;
696     }
697     if (ebone->flag & BONE_TIPSEL) {
698       fill_add_joint(ebone, 1, &points);
699       check = true;
700     }
701
702     if (check) {
703       if (arm && (arm != arm_iter)) {
704         mixed_object_error = true;
705       }
706       arm = arm_iter;
707     }
708   }
709   CTX_DATA_END;
710
711   /* the number of joints determines how we fill:
712    *  1) between joint and cursor (joint=head, cursor=tail)
713    *  2) between the two joints (order is dependent on active-bone/hierarchy)
714    *  3+) error (a smarter method involving finding chains needs to be worked out
715    */
716   count = BLI_listbase_count(&points);
717
718   if (count == 0) {
719     BKE_report(op->reports, RPT_ERROR, "No joints selected");
720     return OPERATOR_CANCELLED;
721   }
722   else if (mixed_object_error) {
723     BKE_report(op->reports, RPT_ERROR, "Bones for different objects selected");
724     BLI_freelistN(&points);
725     return OPERATOR_CANCELLED;
726   }
727
728   Object *obedit = NULL;
729   {
730     ViewLayer *view_layer = CTX_data_view_layer(C);
731     FOREACH_OBJECT_IN_EDIT_MODE_BEGIN (view_layer, v3d, ob_iter) {
732       if (ob_iter->data == arm) {
733         obedit = ob_iter;
734       }
735     }
736     FOREACH_OBJECT_IN_MODE_END;
737   }
738   BLI_assert(obedit != NULL);
739
740   if (count == 1) {
741     EditBonePoint *ebp;
742     float curs[3];
743
744     /* Get Points - selected joint */
745     ebp = points.first;
746
747     /* Get points - cursor (tail) */
748     invert_m4_m4(obedit->imat, obedit->obmat);
749     mul_v3_m4v3(curs, obedit->imat, scene->cursor.location);
750
751     /* Create a bone */
752     newbone = add_points_bone(obedit, ebp->vec, curs);
753   }
754   else if (count == 2) {
755     EditBonePoint *ebp_a, *ebp_b;
756     float head[3], tail[3];
757     short headtail = 0;
758
759     /* check that the points don't belong to the same bone */
760     ebp_a = (EditBonePoint *)points.first;
761     ebp_b = ebp_a->next;
762
763     if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) ||
764         ((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL))) {
765       BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
766       BLI_freelistN(&points);
767       return OPERATOR_CANCELLED;
768     }
769
770     /* find which one should be the 'head' */
771     if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) {
772       /* use active, nice predictable */
773       if (arm->act_edbone && ELEM(arm->act_edbone, ebp_a->head_owner, ebp_a->tail_owner)) {
774         headtail = 1;
775       }
776       else if (arm->act_edbone && ELEM(arm->act_edbone, ebp_b->head_owner, ebp_b->tail_owner)) {
777         headtail = 2;
778       }
779       else {
780         /* rule: whichever one is closer to 3d-cursor */
781         float curs[3];
782         float dist_sq_a, dist_sq_b;
783
784         /* get cursor location */
785         invert_m4_m4(obedit->imat, obedit->obmat);
786         mul_v3_m4v3(curs, obedit->imat, scene->cursor.location);
787
788         /* get distances */
789         dist_sq_a = len_squared_v3v3(ebp_a->vec, curs);
790         dist_sq_b = len_squared_v3v3(ebp_b->vec, curs);
791
792         /* compare distances - closer one therefore acts as direction for bone to go */
793         headtail = (dist_sq_a < dist_sq_b) ? 2 : 1;
794       }
795     }
796     else if (ebp_a->head_owner) {
797       headtail = 1;
798     }
799     else if (ebp_b->head_owner) {
800       headtail = 2;
801     }
802
803     /* assign head/tail combinations */
804     if (headtail == 2) {
805       copy_v3_v3(head, ebp_a->vec);
806       copy_v3_v3(tail, ebp_b->vec);
807     }
808     else if (headtail == 1) {
809       copy_v3_v3(head, ebp_b->vec);
810       copy_v3_v3(tail, ebp_a->vec);
811     }
812
813     /* add new bone and parent it to the appropriate end */
814     if (headtail) {
815       newbone = add_points_bone(obedit, head, tail);
816
817       /* do parenting (will need to set connected flag too) */
818       if (headtail == 2) {
819         /* ebp tail or head - tail gets priority */
820         if (ebp_a->tail_owner)
821           newbone->parent = ebp_a->tail_owner;
822         else
823           newbone->parent = ebp_a->head_owner;
824       }
825       else {
826         /* ebp_b tail or head - tail gets priority */
827         if (ebp_b->tail_owner)
828           newbone->parent = ebp_b->tail_owner;
829         else
830           newbone->parent = ebp_b->head_owner;
831       }
832
833       /* don't set for bone connecting two head points of bones */
834       if (ebp_a->tail_owner || ebp_b->tail_owner) {
835         newbone->flag |= BONE_CONNECTED;
836       }
837     }
838   }
839   else {
840     BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d", count);
841     BLI_freelistN(&points);
842     return OPERATOR_CANCELLED;
843   }
844
845   if (newbone) {
846     ED_armature_edit_deselect_all(obedit);
847     arm->act_edbone = newbone;
848     newbone->flag |= BONE_TIPSEL;
849   }
850
851   /* updates */
852   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
853
854   /* free points */
855   BLI_freelistN(&points);
856
857   return OPERATOR_FINISHED;
858 }
859
860 void ARMATURE_OT_fill(wmOperatorType *ot)
861 {
862   /* identifiers */
863   ot->name = "Fill Between Joints";
864   ot->idname = "ARMATURE_OT_fill";
865   ot->description = "Add bone between selected joint(s) and/or 3D-Cursor";
866
867   /* callbacks */
868   ot->exec = armature_fill_bones_exec;
869   ot->poll = ED_operator_editarmature;
870
871   /* flags */
872   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
873 }
874
875 /* --------------------- */
876
877 /* this function merges between two bones, removes them and those in-between,
878  * and adjusts the parent relationships for those in-between
879  */
880 static void bones_merge(
881     Object *obedit, EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
882 {
883   bArmature *arm = obedit->data;
884   EditBone *ebo, *ebone, *newbone;
885   LinkData *chain;
886   float head[3], tail[3];
887
888   /* check if same bone */
889   if (start == end) {
890     if (G.debug & G_DEBUG) {
891       printf("Error: same bone!\n");
892       printf("\tstart = %s, end = %s\n", start->name, end->name);
893     }
894   }
895
896   /* step 1: add a new bone
897    * - head = head/tail of start (default head)
898    * - tail = head/tail of end (default tail)
899    * - parent = parent of start
900    */
901   if ((start->flag & BONE_TIPSEL) && (start->flag & BONE_SELECTED) == 0) {
902     copy_v3_v3(head, start->tail);
903   }
904   else {
905     copy_v3_v3(head, start->head);
906   }
907   if ((end->flag & BONE_ROOTSEL) && (end->flag & BONE_SELECTED) == 0) {
908     copy_v3_v3(tail, end->head);
909   }
910   else {
911     copy_v3_v3(tail, end->tail);
912   }
913   newbone = add_points_bone(obedit, head, tail);
914   newbone->parent = start->parent;
915
916   /* TODO, copy more things to the new bone */
917   newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE |
918                                  BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE);
919
920   /* Step 2a: reparent any side chains which may be parented to any bone in the chain
921    * of bones to merge - potentially several tips for side chains leading to some tree exist.
922    */
923   for (chain = chains->first; chain; chain = chain->next) {
924     /* Traverse down chain until we hit the bottom or if we run into the tip of the chain of bones
925      * we're merging (need to stop in this case to avoid corrupting this chain too!).
926      */
927     for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) {
928       short found = 0;
929
930       /* Check if this bone is parented to one in the merging chain
931        * ! WATCHIT: must only go check until end of checking chain
932        */
933       for (ebo = end; (ebo) && (ebo != start->parent); ebo = ebo->parent) {
934         /* side-chain found? --> remap parent to new bone, then we're done with this chain :) */
935         if (ebone->parent == ebo) {
936           ebone->parent = newbone;
937           found = 1;
938           break;
939         }
940       }
941
942       /* carry on to the next tip now  */
943       if (found)
944         break;
945     }
946   }
947
948   /* step 2b: parent child of end to newbone (child from this chain) */
949   if (endchild)
950     endchild->parent = newbone;
951
952   /* step 3: delete all bones between and including start and end */
953   for (ebo = end; ebo; ebo = ebone) {
954     ebone = (ebo == start) ? (NULL) : (ebo->parent);
955     bone_free(arm, ebo);
956   }
957
958   newbone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED);
959   ED_armature_edit_sync_selection(arm->edbo);
960 }
961
962 static int armature_merge_exec(bContext *C, wmOperator *op)
963 {
964   ViewLayer *view_layer = CTX_data_view_layer(C);
965   const short type = RNA_enum_get(op->ptr, "type");
966
967   uint objects_len = 0;
968   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
969       view_layer, CTX_wm_view3d(C), &objects_len);
970
971   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
972     Object *obedit = objects[ob_index];
973     bArmature *arm = obedit->data;
974
975     /* for now, there's only really one type of merging that's performed... */
976     if (type == 1) {
977       /* go down chains, merging bones */
978       ListBase chains = {NULL, NULL};
979       LinkData *chain, *nchain;
980       EditBone *ebo;
981
982       armature_tag_select_mirrored(arm);
983
984       /* get chains (ends on chains) */
985       chains_find_tips(arm->edbo, &chains);
986       if (BLI_listbase_is_empty(&chains)) {
987         continue;
988       }
989
990       /* each 'chain' is the last bone in the chain (with no children) */
991       for (chain = chains.first; chain; chain = nchain) {
992         EditBone *bstart = NULL, *bend = NULL;
993         EditBone *bchild = NULL, *child = NULL;
994
995         /* temporarily remove chain from list of chains */
996         nchain = chain->next;
997         BLI_remlink(&chains, chain);
998
999         /* only consider bones that are visible and selected */
1000         for (ebo = chain->data; ebo; child = ebo, ebo = ebo->parent) {
1001           /* check if visible + selected */
1002           if (EBONE_VISIBLE(arm, ebo) && ((ebo->flag & BONE_CONNECTED) || (ebo->parent == NULL)) &&
1003               (ebo->flag & BONE_SELECTED)) {
1004             /* set either end or start (end gets priority, unless it is already set) */
1005             if (bend == NULL) {
1006               bend = ebo;
1007               bchild = child;
1008             }
1009             else
1010               bstart = ebo;
1011           }
1012           else {
1013             /* chain is broken... merge any continuous segments then clear */
1014             if (bstart && bend)
1015               bones_merge(obedit, bstart, bend, bchild, &chains);
1016
1017             bstart = NULL;
1018             bend = NULL;
1019             bchild = NULL;
1020           }
1021         }
1022
1023         /* merge from bstart to bend if something not merged */
1024         if (bstart && bend)
1025           bones_merge(obedit, bstart, bend, bchild, &chains);
1026
1027         /* put back link */
1028         BLI_insertlinkbefore(&chains, nchain, chain);
1029       }
1030
1031       armature_tag_unselect(arm);
1032
1033       BLI_freelistN(&chains);
1034     }
1035
1036     /* updates */
1037     ED_armature_edit_sync_selection(arm->edbo);
1038     WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
1039   }
1040   MEM_freeN(objects);
1041
1042   return OPERATOR_FINISHED;
1043 }
1044
1045 void ARMATURE_OT_merge(wmOperatorType *ot)
1046 {
1047   static const EnumPropertyItem merge_types[] = {
1048       {1, "WITHIN_CHAIN", 0, "Within Chains", ""},
1049       {0, NULL, 0, NULL, NULL},
1050   };
1051
1052   /* identifiers */
1053   ot->name = "Merge Bones";
1054   ot->idname = "ARMATURE_OT_merge";
1055   ot->description = "Merge continuous chains of selected bones";
1056
1057   /* callbacks */
1058   ot->invoke = WM_menu_invoke;
1059   ot->exec = armature_merge_exec;
1060   ot->poll = ED_operator_editarmature;
1061
1062   /* flags */
1063   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1064
1065   /* properties */
1066   ot->prop = RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
1067 }
1068
1069 /* --------------------- */
1070
1071 /* Switch Direction operator:
1072  * Currently, this does not use context loops, as context loops do not make it
1073  * easy to retrieve any hierarchical/chain relationships which are necessary for
1074  * this to be done easily.
1075  */
1076
1077 /* helper to clear BONE_TRANSFORM flags */
1078 static void armature_clear_swap_done_flags(bArmature *arm)
1079 {
1080   EditBone *ebone;
1081
1082   for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1083     ebone->flag &= ~BONE_TRANSFORM;
1084   }
1085 }
1086
1087 static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
1088 {
1089   ViewLayer *view_layer = CTX_data_view_layer(C);
1090   uint objects_len = 0;
1091   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
1092       view_layer, CTX_wm_view3d(C), &objects_len);
1093
1094   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1095     Object *ob = objects[ob_index];
1096     bArmature *arm = ob->data;
1097
1098     ListBase chains = {NULL, NULL};
1099     LinkData *chain;
1100
1101     /* get chains of bones (ends on chains) */
1102     chains_find_tips(arm->edbo, &chains);
1103     if (BLI_listbase_is_empty(&chains)) {
1104       continue;
1105     }
1106
1107     /* ensure that mirror bones will also be operated on */
1108     armature_tag_select_mirrored(arm);
1109
1110     /* clear BONE_TRANSFORM flags
1111      * - used to prevent duplicate/canceling operations from occurring [#34123]
1112      * - BONE_DONE cannot be used here as that's already used for mirroring
1113      */
1114     armature_clear_swap_done_flags(arm);
1115
1116     /* loop over chains, only considering selected and visible bones */
1117     for (chain = chains.first; chain; chain = chain->next) {
1118       EditBone *ebo, *child = NULL, *parent = NULL;
1119
1120       /* loop over bones in chain */
1121       for (ebo = chain->data; ebo; ebo = parent) {
1122         /* parent is this bone's original parent
1123          * - we store this, as the next bone that is checked is this one
1124          *   but the value of ebo->parent may change here...
1125          */
1126         parent = ebo->parent;
1127
1128         /* skip bone if already handled... [#34123] */
1129         if ((ebo->flag & BONE_TRANSFORM) == 0) {
1130           /* only if selected and editable */
1131           if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {
1132             /* swap head and tail coordinates */
1133             swap_v3_v3(ebo->head, ebo->tail);
1134
1135             /* do parent swapping:
1136              * - use 'child' as new parent
1137              * - connected flag is only set if points are coincidental
1138              */
1139             ebo->parent = child;
1140             if ((child) && equals_v3v3(ebo->head, child->tail))
1141               ebo->flag |= BONE_CONNECTED;
1142             else
1143               ebo->flag &= ~BONE_CONNECTED;
1144
1145             /* get next bones
1146              * - child will become the new parent of next bone
1147              */
1148             child = ebo;
1149           }
1150           else {
1151             /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it
1152              * as it will be facing in opposite direction
1153              */
1154             if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
1155               ebo->parent = NULL;
1156               ebo->flag &= ~BONE_CONNECTED;
1157             }
1158
1159             /* get next bones
1160              * - child will become new parent of next bone (not swapping occurred,
1161              *   so set to NULL to prevent infinite-loop)
1162              */
1163             child = NULL;
1164           }
1165
1166           /* tag as done (to prevent double-swaps) */
1167           ebo->flag |= BONE_TRANSFORM;
1168         }
1169       }
1170     }
1171
1172     /* free chains */
1173     BLI_freelistN(&chains);
1174
1175     /* clear temp flags */
1176     armature_clear_swap_done_flags(arm);
1177     armature_tag_unselect(arm);
1178
1179     /* note, notifier might evolve */
1180     WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1181   }
1182   MEM_freeN(objects);
1183
1184   return OPERATOR_FINISHED;
1185 }
1186
1187 void ARMATURE_OT_switch_direction(wmOperatorType *ot)
1188 {
1189   /* identifiers */
1190   ot->name = "Switch Direction";
1191   ot->idname = "ARMATURE_OT_switch_direction";
1192   ot->description = "Change the direction that a chain of bones points in (head <-> tail swap)";
1193
1194   /* api callbacks */
1195   ot->exec = armature_switch_direction_exec;
1196   ot->poll = ED_operator_editarmature;
1197
1198   /* flags */
1199   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1200 }
1201
1202 /* ********************************* Align ******************************* */
1203
1204 /* helper to fix a ebone position if its parent has moved due to alignment*/
1205 static void fix_connected_bone(EditBone *ebone)
1206 {
1207   float diff[3];
1208
1209   if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) ||
1210       equals_v3v3(ebone->parent->tail, ebone->head))
1211     return;
1212
1213   /* if the parent has moved we translate child's head and tail accordingly */
1214   sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
1215   add_v3_v3(ebone->head, diff);
1216   add_v3_v3(ebone->tail, diff);
1217 }
1218
1219 /* helper to recursively find chains of connected bones starting at ebone and fix their position */
1220 static void fix_editbone_connected_children(ListBase *edbo, EditBone *ebone)
1221 {
1222   EditBone *selbone;
1223
1224   for (selbone = edbo->first; selbone; selbone = selbone->next) {
1225     if ((selbone->parent) && (selbone->parent == ebone) && (selbone->flag & BONE_CONNECTED)) {
1226       fix_connected_bone(selbone);
1227       fix_editbone_connected_children(edbo, selbone);
1228     }
1229   }
1230 }
1231
1232 static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actbone)
1233 {
1234   float selboneaxis[3], actboneaxis[3], length;
1235
1236   sub_v3_v3v3(actboneaxis, actbone->tail, actbone->head);
1237   normalize_v3(actboneaxis);
1238
1239   sub_v3_v3v3(selboneaxis, selbone->tail, selbone->head);
1240   length = len_v3(selboneaxis);
1241
1242   mul_v3_fl(actboneaxis, length);
1243   add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
1244   selbone->roll = actbone->roll;
1245
1246   /* if the bone being aligned has connected descendants they must be moved
1247    * according to their parent new position, otherwise they would be left
1248    * in an inconsistent state: connected but away from the parent*/
1249   fix_editbone_connected_children(edbo, selbone);
1250 }
1251
1252 static int armature_align_bones_exec(bContext *C, wmOperator *op)
1253 {
1254   Object *ob = CTX_data_edit_object(C);
1255   bArmature *arm = (bArmature *)ob->data;
1256   EditBone *actbone = CTX_data_active_bone(C);
1257   EditBone *actmirb = NULL;
1258   int num_selected_bones;
1259
1260   /* there must be an active bone */
1261   if (actbone == NULL) {
1262     BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone");
1263     return OPERATOR_CANCELLED;
1264   }
1265   else if (arm->flag & ARM_MIRROR_EDIT) {
1266     /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
1267      * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
1268      *   (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
1269      *   This is useful for arm-chains, for example parenting lower arm to upper arm
1270      * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
1271      *   then just use actbone. Useful when doing upper arm to spine.
1272      */
1273     actmirb = ED_armature_ebone_get_mirrored(arm->edbo, actbone);
1274     if (actmirb == NULL)
1275       actmirb = actbone;
1276   }
1277
1278   /* if there is only 1 selected bone, we assume that that is the active bone,
1279    * since a user will need to have clicked on a bone (thus selecting it) to make it active
1280    */
1281   num_selected_bones = CTX_DATA_COUNT(C, selected_editable_bones);
1282   if (num_selected_bones <= 1) {
1283     /* When only the active bone is selected, and it has a parent,
1284      * align it to the parent, as that is the only possible outcome.
1285      */
1286     if (actbone->parent) {
1287       bone_align_to_bone(arm->edbo, actbone, actbone->parent);
1288
1289       if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
1290         bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
1291
1292       BKE_reportf(op->reports, RPT_INFO, "Aligned bone '%s' to parent", actbone->name);
1293     }
1294   }
1295   else {
1296     /* Align 'selected' bones to the active one
1297      * - the context iterator contains both selected bones and their mirrored copies,
1298      *   so we assume that unselected bones are mirrored copies of some selected bone
1299      * - since the active one (and/or its mirror) will also be selected, we also need
1300      *   to check that we are not trying to operate on them, since such an operation
1301      *   would cause errors
1302      */
1303
1304     /* align selected bones to the active one */
1305     CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) {
1306       if (ELEM(ebone, actbone, actmirb) == 0) {
1307         if (ebone->flag & BONE_SELECTED)
1308           bone_align_to_bone(arm->edbo, ebone, actbone);
1309         else
1310           bone_align_to_bone(arm->edbo, ebone, actmirb);
1311       }
1312     }
1313     CTX_DATA_END;
1314
1315     BKE_reportf(
1316         op->reports, RPT_INFO, "%d bones aligned to bone '%s'", num_selected_bones, actbone->name);
1317   }
1318
1319   /* note, notifier might evolve */
1320   WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1321
1322   return OPERATOR_FINISHED;
1323 }
1324
1325 void ARMATURE_OT_align(wmOperatorType *ot)
1326 {
1327   /* identifiers */
1328   ot->name = "Align Bones";
1329   ot->idname = "ARMATURE_OT_align";
1330   ot->description = "Align selected bones to the active bone (or to their parent)";
1331
1332   /* api callbacks */
1333   ot->exec = armature_align_bones_exec;
1334   ot->poll = ED_operator_editarmature;
1335
1336   /* flags */
1337   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1338 }
1339
1340 /* ********************************* Split ******************************* */
1341
1342 static int armature_split_exec(bContext *C, wmOperator *UNUSED(op))
1343 {
1344   ViewLayer *view_layer = CTX_data_view_layer(C);
1345
1346   uint objects_len = 0;
1347   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
1348       view_layer, CTX_wm_view3d(C), &objects_len);
1349   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1350     Object *ob = objects[ob_index];
1351     bArmature *arm = ob->data;
1352
1353     for (EditBone *bone = arm->edbo->first; bone; bone = bone->next) {
1354       if (bone->parent && (bone->flag & BONE_SELECTED) != (bone->parent->flag & BONE_SELECTED)) {
1355         bone->parent = NULL;
1356         bone->flag &= ~BONE_CONNECTED;
1357       }
1358     }
1359     for (EditBone *bone = arm->edbo->first; bone; bone = bone->next) {
1360       ED_armature_ebone_select_set(bone, (bone->flag & BONE_SELECTED) != 0);
1361     }
1362
1363     WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1364   }
1365
1366   MEM_freeN(objects);
1367   return OPERATOR_FINISHED;
1368 }
1369
1370 void ARMATURE_OT_split(wmOperatorType *ot)
1371 {
1372   /* identifiers */
1373   ot->name = "Split";
1374   ot->idname = "ARMATURE_OT_split";
1375   ot->description = "Split off selected bones from connected unselected bones";
1376
1377   /* api callbacks */
1378   ot->exec = armature_split_exec;
1379   ot->poll = ED_operator_editarmature;
1380
1381   /* flags */
1382   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1383 }
1384
1385 /* ********************************* Delete ******************************* */
1386
1387 static bool armature_delete_ebone_cb(const char *bone_name, void *arm_p)
1388 {
1389   bArmature *arm = arm_p;
1390   EditBone *ebone;
1391
1392   ebone = ED_armature_ebone_find_name(arm->edbo, bone_name);
1393   return (ebone && (ebone->flag & BONE_SELECTED) && (arm->layer & ebone->layer));
1394 }
1395
1396 /* previously delete_armature */
1397 /* only editmode! */
1398 static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
1399 {
1400   EditBone *curBone, *ebone_next;
1401   bool changed_multi = false;
1402
1403   /* cancel if nothing selected */
1404   if (CTX_DATA_COUNT(C, selected_bones) == 0)
1405     return OPERATOR_CANCELLED;
1406
1407   ViewLayer *view_layer = CTX_data_view_layer(C);
1408   uint objects_len = 0;
1409   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
1410       view_layer, CTX_wm_view3d(C), &objects_len);
1411   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1412     Object *obedit = objects[ob_index];
1413     bArmature *arm = obedit->data;
1414     bool changed = false;
1415
1416     armature_select_mirrored(arm);
1417
1418     BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm);
1419
1420     for (curBone = arm->edbo->first; curBone; curBone = ebone_next) {
1421       ebone_next = curBone->next;
1422       if (arm->layer & curBone->layer) {
1423         if (curBone->flag & BONE_SELECTED) {
1424           if (curBone == arm->act_edbone)
1425             arm->act_edbone = NULL;
1426           ED_armature_ebone_remove(arm, curBone);
1427           changed = true;
1428         }
1429       }
1430     }
1431
1432     if (changed) {
1433       changed_multi = true;
1434
1435       ED_armature_edit_sync_selection(arm->edbo);
1436       BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose);
1437
1438       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1439     }
1440   }
1441   MEM_freeN(objects);
1442
1443   if (!changed_multi) {
1444     return OPERATOR_CANCELLED;
1445   }
1446
1447   return OPERATOR_FINISHED;
1448 }
1449
1450 void ARMATURE_OT_delete(wmOperatorType *ot)
1451 {
1452   /* identifiers */
1453   ot->name = "Delete Selected Bone(s)";
1454   ot->idname = "ARMATURE_OT_delete";
1455   ot->description = "Remove selected bones from the armature";
1456
1457   /* api callbacks */
1458   ot->invoke = WM_operator_confirm;
1459   ot->exec = armature_delete_selected_exec;
1460   ot->poll = ED_operator_editarmature;
1461
1462   /* flags */
1463   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1464 }
1465
1466 static bool armature_dissolve_ebone_cb(const char *bone_name, void *arm_p)
1467 {
1468   bArmature *arm = arm_p;
1469   EditBone *ebone;
1470
1471   ebone = ED_armature_ebone_find_name(arm->edbo, bone_name);
1472   return (ebone && (ebone->flag & BONE_DONE));
1473 }
1474
1475 static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op))
1476 {
1477   ViewLayer *view_layer = CTX_data_view_layer(C);
1478   EditBone *ebone, *ebone_next;
1479   bool changed_multi = false;
1480
1481   uint objects_len = 0;
1482   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
1483       view_layer, CTX_wm_view3d(C), &objects_len);
1484   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1485     Object *obedit = objects[ob_index];
1486     bArmature *arm = obedit->data;
1487     bool changed = false;
1488
1489     /* store for mirror */
1490     GHash *ebone_flag_orig = NULL;
1491     int ebone_num = 0;
1492
1493     for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1494       ebone->temp.p = NULL;
1495       ebone->flag &= ~BONE_DONE;
1496       ebone_num++;
1497     }
1498
1499     if (arm->flag & ARM_MIRROR_EDIT) {
1500       GHashIterator gh_iter;
1501
1502       ebone_flag_orig = BLI_ghash_ptr_new_ex(__func__, ebone_num);
1503       for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1504         union {
1505           int flag;
1506           void *p;
1507         } val = {0};
1508         val.flag = ebone->flag;
1509         BLI_ghash_insert(ebone_flag_orig, ebone, val.p);
1510       }
1511
1512       armature_select_mirrored_ex(arm, BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
1513
1514       GHASH_ITER (gh_iter, ebone_flag_orig) {
1515         union {
1516           int flag;
1517           void *p;
1518         } *val_p = (void *)BLI_ghashIterator_getValue_p(&gh_iter);
1519         ebone = BLI_ghashIterator_getKey(&gh_iter);
1520         val_p->flag = ebone->flag & ~val_p->flag;
1521       }
1522     }
1523
1524     for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1525       if (ebone->parent && ebone->flag & BONE_CONNECTED) {
1526         if (ebone->parent->temp.ebone == ebone->parent) {
1527           /* ignore */
1528         }
1529         else if (ebone->parent->temp.ebone) {
1530           /* set ignored */
1531           ebone->parent->temp.ebone = ebone->parent;
1532         }
1533         else {
1534           /* set child */
1535           ebone->parent->temp.ebone = ebone;
1536         }
1537       }
1538     }
1539
1540     /* cleanup multiple used bones */
1541     for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1542       if (ebone->temp.ebone == ebone) {
1543         ebone->temp.ebone = NULL;
1544       }
1545     }
1546
1547     for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1548       /* break connections for unseen bones */
1549       if (((arm->layer & ebone->layer) &&
1550            ((ED_armature_ebone_selectflag_get(ebone) & (BONE_TIPSEL | BONE_SELECTED)))) == 0) {
1551         ebone->temp.ebone = NULL;
1552       }
1553
1554       if (((arm->layer & ebone->layer) &&
1555            ((ED_armature_ebone_selectflag_get(ebone) & (BONE_ROOTSEL | BONE_SELECTED)))) == 0) {
1556         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
1557           ebone->parent->temp.ebone = NULL;
1558         }
1559       }
1560     }
1561
1562     for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1563
1564       if (ebone->parent && (ebone->parent->temp.ebone == ebone)) {
1565         ebone->flag |= BONE_DONE;
1566       }
1567     }
1568
1569     BKE_pose_channels_remove(obedit, armature_dissolve_ebone_cb, arm);
1570
1571     for (ebone = arm->edbo->first; ebone; ebone = ebone_next) {
1572       ebone_next = ebone->next;
1573
1574       if (ebone->flag & BONE_DONE) {
1575         copy_v3_v3(ebone->parent->tail, ebone->tail);
1576         ebone->parent->rad_tail = ebone->rad_tail;
1577         SET_FLAG_FROM_TEST(ebone->parent->flag, ebone->flag & BONE_TIPSEL, BONE_TIPSEL);
1578
1579         ED_armature_ebone_remove_ex(arm, ebone, false);
1580         changed = true;
1581       }
1582     }
1583
1584     if (changed) {
1585       for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1586         if (ebone->parent && ebone->parent->temp.ebone && (ebone->flag & BONE_CONNECTED)) {
1587           ebone->rad_head = ebone->parent->rad_tail;
1588         }
1589       }
1590
1591       if (arm->flag & ARM_MIRROR_EDIT) {
1592         for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1593           union {
1594             int flag;
1595             void *p;
1596           } *val_p = (void *)BLI_ghash_lookup_p(ebone_flag_orig, ebone);
1597           if (val_p && val_p->flag) {
1598             ebone->flag &= ~val_p->flag;
1599           }
1600         }
1601       }
1602     }
1603
1604     if (arm->flag & ARM_MIRROR_EDIT) {
1605       BLI_ghash_free(ebone_flag_orig, NULL, NULL);
1606     }
1607
1608     if (changed) {
1609       changed_multi = true;
1610       ED_armature_edit_sync_selection(arm->edbo);
1611       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1612     }
1613   }
1614   MEM_freeN(objects);
1615
1616   if (!changed_multi) {
1617     return OPERATOR_CANCELLED;
1618   }
1619
1620   return OPERATOR_FINISHED;
1621 }
1622
1623 void ARMATURE_OT_dissolve(wmOperatorType *ot)
1624 {
1625   /* identifiers */
1626   ot->name = "Dissolve Selected Bone(s)";
1627   ot->idname = "ARMATURE_OT_dissolve";
1628   ot->description = "Dissolve selected bones from the armature";
1629
1630   /* api callbacks */
1631   ot->exec = armature_dissolve_selected_exec;
1632   ot->poll = ED_operator_editarmature;
1633
1634   /* flags */
1635   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1636 }
1637
1638 /* ********************************* Show/Hide ******************************* */
1639
1640 static int armature_hide_exec(bContext *C, wmOperator *op)
1641 {
1642   ViewLayer *view_layer = CTX_data_view_layer(C);
1643   const int invert = RNA_boolean_get(op->ptr, "unselected") ? BONE_SELECTED : 0;
1644
1645   /* cancel if nothing selected */
1646   if (CTX_DATA_COUNT(C, selected_bones) == 0)
1647     return OPERATOR_CANCELLED;
1648
1649   uint objects_len = 0;
1650   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
1651       view_layer, CTX_wm_view3d(C), &objects_len);
1652   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1653     Object *obedit = objects[ob_index];
1654     bArmature *arm = obedit->data;
1655     bool changed = false;
1656
1657     for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1658       if (EBONE_VISIBLE(arm, ebone)) {
1659         if ((ebone->flag & BONE_SELECTED) != invert) {
1660           ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
1661           ebone->flag |= BONE_HIDDEN_A;
1662           changed = true;
1663         }
1664       }
1665     }
1666
1667     if (!changed) {
1668       continue;
1669     }
1670     ED_armature_edit_validate_active(arm);
1671     ED_armature_edit_sync_selection(arm->edbo);
1672
1673     WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1674   }
1675   MEM_freeN(objects);
1676   return OPERATOR_FINISHED;
1677 }
1678
1679 void ARMATURE_OT_hide(wmOperatorType *ot)
1680 {
1681   /* identifiers */
1682   ot->name = "Hide Selected";
1683   ot->idname = "ARMATURE_OT_hide";
1684   ot->description = "Tag selected bones to not be visible in Edit Mode";
1685
1686   /* api callbacks */
1687   ot->exec = armature_hide_exec;
1688   ot->poll = ED_operator_editarmature;
1689
1690   /* flags */
1691   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1692
1693   /* props */
1694   RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
1695 }
1696
1697 static int armature_reveal_exec(bContext *C, wmOperator *op)
1698 {
1699   ViewLayer *view_layer = CTX_data_view_layer(C);
1700   const bool select = RNA_boolean_get(op->ptr, "select");
1701   uint objects_len = 0;
1702   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
1703       view_layer, CTX_wm_view3d(C), &objects_len);
1704   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1705     Object *obedit = objects[ob_index];
1706     bArmature *arm = obedit->data;
1707     bool changed = false;
1708
1709     for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1710       if (arm->layer & ebone->layer) {
1711         if (ebone->flag & BONE_HIDDEN_A) {
1712           if (!(ebone->flag & BONE_UNSELECTABLE)) {
1713             SET_FLAG_FROM_TEST(ebone->flag, select, (BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL));
1714           }
1715           ebone->flag &= ~BONE_HIDDEN_A;
1716           changed = true;
1717         }
1718       }
1719     }
1720
1721     if (changed) {
1722       ED_armature_edit_validate_active(arm);
1723       ED_armature_edit_sync_selection(arm->edbo);
1724
1725       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
1726     }
1727   }
1728   MEM_freeN(objects);
1729   return OPERATOR_FINISHED;
1730 }
1731
1732 void ARMATURE_OT_reveal(wmOperatorType *ot)
1733 {
1734   /* identifiers */
1735   ot->name = "Reveal Hidden";
1736   ot->idname = "ARMATURE_OT_reveal";
1737   ot->description = "Reveal all bones hidden in Edit Mode";
1738
1739   /* api callbacks */
1740   ot->exec = armature_reveal_exec;
1741   ot->poll = ED_operator_editarmature;
1742
1743   /* flags */
1744   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1745
1746   RNA_def_boolean(ot->srna, "select", true, "Select", "");
1747 }