Blender  V2.93
armature_add.c
Go to the documentation of this file.
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  * Operators and API's for creating bones
19  */
20 
25 #include "DNA_anim_types.h"
26 #include "DNA_armature_types.h"
27 #include "DNA_constraint_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_blenlib.h"
34 #include "BLI_ghash.h"
35 #include "BLI_math.h"
36 #include "BLI_string_utils.h"
37 
38 #include "BKE_action.h"
39 #include "BKE_armature.h"
40 #include "BKE_constraint.h"
41 #include "BKE_context.h"
42 #include "BKE_deform.h"
43 #include "BKE_fcurve.h"
44 #include "BKE_idprop.h"
45 #include "BKE_layer.h"
46 #include "BKE_lib_id.h"
47 #include "BKE_library.h"
48 #include "BKE_main.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_outliner.h"
58 #include "ED_screen.h"
59 #include "ED_view3d.h"
60 
61 #include "DEG_depsgraph.h"
62 
63 #include "armature_intern.h"
64 
65 /* *************** Adding stuff in editmode *************** */
66 
67 /* default bone add, returns it selected, but without tail set */
68 /* XXX should be used everywhere, now it mallocs bones still locally in functions */
69 EditBone *ED_armature_ebone_add(bArmature *arm, const char *name)
70 {
71  EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
72 
73  BLI_strncpy(bone->name, name, sizeof(bone->name));
75 
76  BLI_addtail(arm->edbo, bone);
77 
78  bone->flag |= BONE_TIPSEL;
79  bone->weight = 1.0f;
80  bone->dist = 0.25f;
81  bone->xwidth = 0.1f;
82  bone->zwidth = 0.1f;
83  bone->rad_head = 0.10f;
84  bone->rad_tail = 0.05f;
85  bone->segments = 1;
86  bone->layer = arm->layer;
87 
88  /* Bendy-Bone parameters */
89  bone->roll1 = 0.0f;
90  bone->roll2 = 0.0f;
91  bone->curve_in_x = 0.0f;
92  bone->curve_in_y = 0.0f;
93  bone->curve_out_x = 0.0f;
94  bone->curve_out_y = 0.0f;
95  bone->ease1 = 1.0f;
96  bone->ease2 = 1.0f;
97  bone->scale_in_x = 1.0f;
98  bone->scale_in_y = 1.0f;
99  bone->scale_out_x = 1.0f;
100  bone->scale_out_y = 1.0f;
101 
102  return bone;
103 }
104 
105 EditBone *ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool view_aligned)
106 {
107  bArmature *arm = obedit_arm->data;
108  EditBone *bone;
109 
110  ED_armature_edit_deselect_all(obedit_arm);
111 
112  /* Create a bone */
113  bone = ED_armature_ebone_add(arm, "Bone");
114 
115  arm->act_edbone = bone;
116 
117  zero_v3(bone->head);
118  zero_v3(bone->tail);
119 
120  bone->tail[view_aligned ? 1 : 2] = length;
121 
122  return bone;
123 }
124 
134 {
135  bArmature *arm;
136  EditBone *ebone, *newbone, *flipbone;
137  float mat[3][3], imat[3][3];
138  int a, to_root = 0;
139  Object *obedit;
140  Scene *scene;
141 
143  obedit = CTX_data_edit_object(C);
144  arm = obedit->data;
145 
146  /* find the active or selected bone */
147  for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
148  if (EBONE_VISIBLE(arm, ebone)) {
149  if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone) {
150  break;
151  }
152  }
153  }
154 
155  if (ebone == NULL) {
156  for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
157  if (EBONE_VISIBLE(arm, ebone)) {
158  if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone) {
159  break;
160  }
161  }
162  }
163  if (ebone == NULL) {
164  return OPERATOR_CANCELLED;
165  }
166 
167  to_root = 1;
168  }
169 
171 
172  /* we re-use code for mirror editing... */
173  flipbone = NULL;
174  if (arm->flag & ARM_MIRROR_EDIT) {
175  flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
176  }
177 
178  for (a = 0; a < 2; a++) {
179  if (a == 1) {
180  if (flipbone == NULL) {
181  break;
182  }
183  SWAP(EditBone *, flipbone, ebone);
184  }
185 
186  newbone = ED_armature_ebone_add(arm, ebone->name);
187  arm->act_edbone = newbone;
188 
189  if (to_root) {
190  copy_v3_v3(newbone->head, ebone->head);
191  newbone->rad_head = ebone->rad_tail;
192  newbone->parent = ebone->parent;
193  }
194  else {
195  copy_v3_v3(newbone->head, ebone->tail);
196  newbone->rad_head = ebone->rad_tail;
197  newbone->parent = ebone;
198  newbone->flag |= BONE_CONNECTED;
199  }
200 
201  const View3DCursor *curs = &scene->cursor;
202  copy_v3_v3(newbone->tail, curs->location);
203  sub_v3_v3v3(newbone->tail, newbone->tail, obedit->obmat[3]);
204 
205  if (a == 1) {
206  newbone->tail[0] = -newbone->tail[0];
207  }
208 
209  copy_m3_m4(mat, obedit->obmat);
210  invert_m3_m3(imat, mat);
211  mul_m3_v3(imat, newbone->tail);
212 
213  newbone->length = len_v3v3(newbone->head, newbone->tail);
214  newbone->rad_tail = newbone->length * 0.05f;
215  newbone->dist = newbone->length * 0.25f;
216  }
217 
219 
223 
224  return OPERATOR_FINISHED;
225 }
226 
228 {
229  /* TODO most of this code is copied from set3dcursor_invoke,
230  * it would be better to reuse code in set3dcursor_invoke */
231 
232  /* temporarily change 3d cursor position */
233  Scene *scene;
234  ARegion *region;
235  View3D *v3d;
236  float tvec[3], oldcurs[3], mval_f[2];
237  int retv;
238 
240  region = CTX_wm_region(C);
241  v3d = CTX_wm_view3d(C);
242 
243  View3DCursor *cursor = &scene->cursor;
244 
245  copy_v3_v3(oldcurs, cursor->location);
246 
247  copy_v2fl_v2i(mval_f, event->mval);
248  ED_view3d_win_to_3d(v3d, region, cursor->location, mval_f, tvec);
249  copy_v3_v3(cursor->location, tvec);
250 
251  /* extrude to the where new cursor is and store the operation result */
252  retv = armature_click_extrude_exec(C, op);
253 
254  /* restore previous 3d cursor position */
255  copy_v3_v3(cursor->location, oldcurs);
256 
257  return retv;
258 }
259 
261 {
262  /* identifiers */
263  ot->name = "Click-Extrude";
264  ot->idname = "ARMATURE_OT_click_extrude";
265  ot->description = "Create a new bone going from the last selected joint to the mouse position";
266 
267  /* api callbacks */
271 
272  /* flags */
274 
275  /* props */
276 }
277 
278 /* adds an EditBone between the nominated locations (should be in the right space) */
279 EditBone *add_points_bone(Object *obedit, float head[3], float tail[3])
280 {
281  EditBone *ebo;
282 
283  ebo = ED_armature_ebone_add(obedit->data, "Bone");
284 
285  copy_v3_v3(ebo->head, head);
286  copy_v3_v3(ebo->tail, tail);
287 
288  return ebo;
289 }
290 
291 static EditBone *get_named_editbone(ListBase *edbo, const char *name)
292 {
293  EditBone *eBone;
294 
295  if (name) {
296  for (eBone = edbo->first; eBone; eBone = eBone->next) {
297  if (STREQ(name, eBone->name)) {
298  return eBone;
299  }
300  }
301  }
302 
303  return NULL;
304 }
305 
306 /* Call this before doing any duplications. */
308 {
309  /* clear temp */
311 }
312 
318  GHash *name_map,
319  bPoseChannel *pchan_src)
320 {
321  bPoseChannel *pchan_dst = NULL;
322  const char *name_src = pchan_src->name;
323  const char *name_dst = BLI_ghash_lookup(name_map, name_src);
324  if (name_dst) {
325  pchan_dst = BKE_pose_channel_find_name(pose, name_dst);
326  }
327 
328  if (pchan_dst == NULL) {
329  pchan_dst = pchan_src;
330  }
331 
332  return pchan_dst;
333 }
334 
335 void postEditBoneDuplicate(struct ListBase *editbones, Object *ob)
336 {
337  if (ob->pose == NULL) {
338  return;
339  }
340 
343 
344  GHash *name_map = BLI_ghash_str_new(__func__);
345 
346  LISTBASE_FOREACH (EditBone *, ebone_src, editbones) {
347  EditBone *ebone_dst = ebone_src->temp.ebone;
348  if (!ebone_dst) {
349  ebone_dst = ED_armature_ebone_get_mirrored(editbones, ebone_src);
350  }
351  if (ebone_dst) {
352  BLI_ghash_insert(name_map, ebone_src->name, ebone_dst->name);
353  }
354  }
355 
356  LISTBASE_FOREACH (EditBone *, ebone_src, editbones) {
357  EditBone *ebone_dst = ebone_src->temp.ebone;
358  if (ebone_dst) {
359  bPoseChannel *pchan_src = BKE_pose_channel_find_name(ob->pose, ebone_src->name);
360  if (pchan_src) {
361  bPoseChannel *pchan_dst = BKE_pose_channel_find_name(ob->pose, ebone_dst->name);
362  if (pchan_dst) {
363  if (pchan_src->custom_tx) {
364  pchan_dst->custom_tx = pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx);
365  }
366  if (pchan_src->bbone_prev) {
367  pchan_dst->bbone_prev = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_prev);
368  }
369  if (pchan_src->bbone_next) {
370  pchan_dst->bbone_next = pchan_duplicate_map(ob->pose, name_map, pchan_src->bbone_next);
371  }
372  }
373  }
374  }
375  }
376 
377  BLI_ghash_free(name_map, NULL, NULL);
378 }
379 
380 static void updateDuplicateSubtarget(EditBone *dup_bone,
381  ListBase *editbones,
382  Object *ob,
383  bool lookup_mirror_subtarget)
384 {
385  /* If an edit bone has been duplicated, lets update its constraints if the
386  * subtarget they point to has also been duplicated.
387  */
388  EditBone *oldtarget, *newtarget;
389  bPoseChannel *pchan;
390  bConstraint *curcon;
391  ListBase *conlist;
392 
393  if ((pchan = BKE_pose_channel_verify(ob->pose, dup_bone->name))) {
394  if ((conlist = &pchan->constraints)) {
395  for (curcon = conlist->first; curcon; curcon = curcon->next) {
396  /* does this constraint have a subtarget in
397  * this armature?
398  */
400  ListBase targets = {NULL, NULL};
401  bConstraintTarget *ct;
402 
403  if (cti && cti->get_constraint_targets) {
404  cti->get_constraint_targets(curcon, &targets);
405 
406  for (ct = targets.first; ct; ct = ct->next) {
407  if ((ct->tar == ob) && (ct->subtarget[0])) {
408  oldtarget = get_named_editbone(editbones, ct->subtarget);
409  if (oldtarget) {
410  /* was the subtarget bone duplicated too? If
411  * so, update the constraint to point at the
412  * duplicate of the old subtarget.
413  */
414  if (oldtarget->temp.ebone) {
415  newtarget = oldtarget->temp.ebone;
416  BLI_strncpy(ct->subtarget, newtarget->name, sizeof(ct->subtarget));
417  }
418  else if (lookup_mirror_subtarget) {
419  /* The subtarget was not selected for duplication, try to see if a mirror bone of
420  * the current target exists */
421  char name_flip[MAXBONENAME];
422 
423  BLI_string_flip_side_name(name_flip, oldtarget->name, false, sizeof(name_flip));
424  newtarget = get_named_editbone(editbones, name_flip);
425  if (newtarget) {
426  BLI_strncpy(ct->subtarget, newtarget->name, sizeof(ct->subtarget));
427  }
428  }
429  }
430  }
431  }
432 
433  if (cti->flush_constraint_targets) {
434  cti->flush_constraint_targets(curcon, &targets, 0);
435  }
436  }
437  }
438  }
439  }
440 }
441 
443  EditBone *orig_bone,
444  Object *ob,
445  bConstraint *curcon)
446 {
447  bActionConstraint *act_con = (bActionConstraint *)curcon->data;
448  bAction *act = (bAction *)act_con->act;
449 
450  float mat[4][4];
451 
452  bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = NULL};
454 
455  unit_m4(mat);
456  bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, act_con->subtarget);
458  ob, target_pchan, &cob, mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
459 
460  float max_axis_val = 0;
461  int max_axis = 0;
462  /* Which axis represents X now. IE, which axis defines the mirror plane. */
463  for (int i = 0; i < 3; i++) {
464  float cur_val = fabsf(mat[0][i]);
465  if (cur_val > max_axis_val) {
466  max_axis = i;
467  max_axis_val = cur_val;
468  }
469  }
470 
471  /* data->type is mapped as follows for backwards compatibility:
472  * 00,01,02 - rotation (it used to be like this)
473  * 10,11,12 - scaling
474  * 20,21,22 - location
475  */
476  /* Mirror the target range */
477  if (act_con->type < 10 && act_con->type != max_axis) {
478  /* Y or Z rotation */
479  act_con->min = -act_con->min;
480  act_con->max = -act_con->max;
481  }
482  else if (act_con->type == max_axis + 10) {
483  /* X scaling */
484  }
485  else if (act_con->type == max_axis + 20) {
486  /* X location */
487  float imat[4][4];
488 
489  invert_m4_m4(imat, mat);
490 
491  float min_vec[3], max_vec[3];
492 
493  zero_v3(min_vec);
494  zero_v3(max_vec);
495 
496  min_vec[0] = act_con->min;
497  max_vec[0] = act_con->max;
498 
499  /* convert values into local object space */
500  mul_m4_v3(mat, min_vec);
501  mul_m4_v3(mat, max_vec);
502 
503  min_vec[0] *= -1;
504  max_vec[0] *= -1;
505 
506  /* convert back to the settings space */
507  mul_m4_v3(imat, min_vec);
508  mul_m4_v3(imat, max_vec);
509 
510  act_con->min = min_vec[0];
511  act_con->max = max_vec[0];
512  }
513 
514  /* See if there is any channels that uses this bone */
515  ListBase ani_curves;
516  BLI_listbase_clear(&ani_curves);
517  if ((act != NULL) &&
518  BKE_fcurves_filter(&ani_curves, &act->curves, "pose.bones[", orig_bone->name)) {
519  /* Create a copy and mirror the animation */
520  for (LinkData *ld = ani_curves.first; ld; ld = ld->next) {
521  FCurve *old_curve = ld->data;
522  FCurve *new_curve = BKE_fcurve_copy(old_curve);
523  bActionGroup *agrp;
524 
525  char *old_path = new_curve->rna_path;
526 
527  new_curve->rna_path = BLI_str_replaceN(old_path, orig_bone->name, dup_bone->name);
528  MEM_freeN(old_path);
529 
530  /* Flip the animation */
531  int i;
532  BezTriple *bezt;
533  for (i = 0, bezt = new_curve->bezt; i < new_curve->totvert; i++, bezt++) {
534  const size_t slength = strlen(new_curve->rna_path);
535  bool flip = false;
536  if (BLI_strn_endswith(new_curve->rna_path, "location", slength) &&
537  new_curve->array_index == 0) {
538  flip = true;
539  }
540  else if (BLI_strn_endswith(new_curve->rna_path, "rotation_quaternion", slength) &&
541  ELEM(new_curve->array_index, 2, 3)) {
542  flip = true;
543  }
544  else if (BLI_strn_endswith(new_curve->rna_path, "rotation_euler", slength) &&
545  ELEM(new_curve->array_index, 1, 2)) {
546  flip = true;
547  }
548  else if (BLI_strn_endswith(new_curve->rna_path, "rotation_axis_angle", slength) &&
549  ELEM(new_curve->array_index, 2, 3)) {
550  flip = true;
551  }
552 
553  if (flip) {
554  bezt->vec[0][1] *= -1;
555  bezt->vec[1][1] *= -1;
556  bezt->vec[2][1] *= -1;
557  }
558  }
559 
560  /* Make sure that a action group name for the new bone exists */
561  agrp = BKE_action_group_find_name(act, dup_bone->name);
562 
563  if (agrp == NULL) {
564  agrp = action_groups_add_new(act, dup_bone->name);
565  }
566  BLI_assert(agrp != NULL);
567  action_groups_add_channel(act, agrp, new_curve);
568  }
569  }
570  BLI_freelistN(&ani_curves);
571 
572  /* Make deps graph aware of our changes */
574 }
575 
577 {
578  /* IK constraint */
580  ik->poleangle = -M_PI - ik->poleangle;
581  /* Wrap the angle to the +/-180.0f range (default soft limit of the input boxes). */
583 }
584 
586  bPoseChannel *pchan,
587  bConstraint *curcon)
588 {
589  /* This code assumes that bRotLimitConstraint and bLocLimitConstraint have the same fields in
590  * the same memory locations. */
592 
593  bRotLimitConstraint *limit = (bRotLimitConstraint *)curcon->data;
594  float local_mat[4][4], imat[4][4];
595 
596  float min_vec[3], max_vec[3];
597 
598  min_vec[0] = limit->xmin;
599  min_vec[1] = limit->ymin;
600  min_vec[2] = limit->zmin;
601 
602  max_vec[0] = limit->xmax;
603  max_vec[1] = limit->ymax;
604  max_vec[2] = limit->zmax;
605 
606  unit_m4(local_mat);
607 
608  bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
610 
612  ob, pchan, &cob, local_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
613 
614  if (curcon->type == CONSTRAINT_TYPE_ROTLIMIT) {
615  /* Zero out any location translation */
616  local_mat[3][0] = local_mat[3][1] = local_mat[3][2] = 0;
617  }
618 
619  invert_m4_m4(imat, local_mat);
620  /* convert values into local object space */
621  mul_m4_v3(local_mat, min_vec);
622  mul_m4_v3(local_mat, max_vec);
623 
624  if (curcon->type == CONSTRAINT_TYPE_ROTLIMIT) {
625  float min_copy[3];
626 
627  copy_v3_v3(min_copy, min_vec);
628 
629  min_vec[1] = max_vec[1] * -1;
630  min_vec[2] = max_vec[2] * -1;
631 
632  max_vec[1] = min_copy[1] * -1;
633  max_vec[2] = min_copy[2] * -1;
634  }
635  else {
636  float min_x_copy = min_vec[0];
637 
638  min_vec[0] = max_vec[0] * -1;
639  max_vec[0] = min_x_copy * -1;
640  }
641 
642  /* convert back to the settings space */
643  mul_m4_v3(imat, min_vec);
644  mul_m4_v3(imat, max_vec);
645 
646  limit->xmin = min_vec[0];
647  limit->ymin = min_vec[1];
648  limit->zmin = min_vec[2];
649 
650  limit->xmax = max_vec[0];
651  limit->ymax = max_vec[1];
652  limit->zmax = max_vec[2];
653 }
654 
656  bPoseChannel *pchan,
657  bConstraint *curcon)
658 {
659  bTransformConstraint *trans = (bTransformConstraint *)curcon->data;
660 
661  float target_mat[4][4], own_mat[4][4], imat[4][4];
662 
663  bConstraintOb cob = {.depsgraph = NULL, .scene = NULL, .ob = ob, .pchan = pchan};
664  BKE_constraint_custom_object_space_get(cob.space_obj_world_matrix, curcon);
665 
666  unit_m4(own_mat);
668  ob, pchan, &cob, own_mat, curcon->ownspace, CONSTRAINT_SPACE_LOCAL, false);
669 
670  /* ###Source map mirroring### */
671  float old_min, old_max;
672 
673  /* Source location */
674  invert_m4_m4(imat, own_mat);
675 
676  /* convert values into local object space */
677  mul_m4_v3(own_mat, trans->from_min);
678  mul_m4_v3(own_mat, trans->from_max);
679 
680  old_min = trans->from_min[0];
681  old_max = trans->from_max[0];
682 
683  trans->from_min[0] = -old_max;
684  trans->from_max[0] = -old_min;
685 
686  /* convert back to the settings space */
687  mul_m4_v3(imat, trans->from_min);
688  mul_m4_v3(imat, trans->from_max);
689 
690  /* Source rotation */
691 
692  /* Zero out any location translation */
693  own_mat[3][0] = own_mat[3][1] = own_mat[3][2] = 0;
694 
695  invert_m4_m4(imat, own_mat);
696 
697  /* convert values into local object space */
698  mul_m4_v3(own_mat, trans->from_min_rot);
699  mul_m4_v3(own_mat, trans->from_max_rot);
700 
701  old_min = trans->from_min_rot[1];
702  old_max = trans->from_max_rot[1];
703 
704  trans->from_min_rot[1] = old_max * -1;
705  trans->from_max_rot[1] = old_min * -1;
706 
707  old_min = trans->from_min_rot[2];
708  old_max = trans->from_max_rot[2];
709 
710  trans->from_min_rot[2] = old_max * -1;
711  trans->from_max_rot[2] = old_min * -1;
712 
713  /* convert back to the settings space */
714  mul_m4_v3(imat, trans->from_min_rot);
715  mul_m4_v3(imat, trans->from_max_rot);
716 
717  /* Source scale does not require any mirroring */
718 
719  /* ###Destination map mirroring### */
720  float temp_vec[3];
721  float imat_rot[4][4];
722 
723  bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, trans->subtarget);
724  unit_m4(target_mat);
726  ob, target_pchan, &cob, target_mat, curcon->tarspace, CONSTRAINT_SPACE_LOCAL, false);
727 
728  invert_m4_m4(imat, target_mat);
729  /* convert values into local object space */
730  mul_m4_v3(target_mat, trans->to_min);
731  mul_m4_v3(target_mat, trans->to_max);
732  mul_m4_v3(target_mat, trans->to_min_scale);
733  mul_m4_v3(target_mat, trans->to_max_scale);
734 
735  /* Zero out any location translation */
736  target_mat[3][0] = target_mat[3][1] = target_mat[3][2] = 0;
737  invert_m4_m4(imat_rot, target_mat);
738 
739  mul_m4_v3(target_mat, trans->to_min_rot);
740  mul_m4_v3(target_mat, trans->to_max_rot);
741 
742  /* TODO(sebpa): This does not support euler order, but doing so will make this way more complex.
743  * For now we have decided to not support all corner cases and advanced setups. */
744 
745  /* Helper variables to denote the axis in trans->map */
746  const char X = 0;
747  const char Y = 1;
748  const char Z = 2;
749 
750  switch (trans->to) {
751  case TRANS_SCALE:
752  copy_v3_v3(temp_vec, trans->to_max_scale);
753 
754  for (int i = 0; i < 3; i++) {
755  if ((trans->from == TRANS_LOCATION && trans->map[i] == X) ||
756  (trans->from == TRANS_ROTATION && trans->map[i] != X)) {
757  /* X Loc to X/Y/Z Scale: Min/Max Flipped */
758  /* Y Rot to X/Y/Z Scale: Min/Max Flipped */
759  /* Z Rot to X/Y/Z Scale: Min/Max Flipped */
760  trans->to_max_scale[i] = trans->to_min_scale[i];
761  trans->to_min_scale[i] = temp_vec[i];
762  }
763  }
764  break;
765  case TRANS_LOCATION:
766  /* Invert the X location */
767  trans->to_min[0] *= -1;
768  trans->to_max[0] *= -1;
769 
770  copy_v3_v3(temp_vec, trans->to_max);
771 
772  for (int i = 0; i < 3; i++) {
773  if ((trans->from == TRANS_LOCATION && trans->map[i] == X) ||
774  (trans->from == TRANS_ROTATION && trans->map[i] != X)) {
775  /* X Loc to X/Y/Z Loc: Min/Max Flipped (and Inverted)
776  * Y Rot to X/Y/Z Loc: Min/Max Flipped
777  * Z Rot to X/Y/Z Loc: Min/Max Flipped */
778  trans->to_max[i] = trans->to_min[i];
779  trans->to_min[i] = temp_vec[i];
780  }
781  }
782  break;
783  case TRANS_ROTATION:
784  /* Invert the Z rotation */
785  trans->to_min_rot[2] *= -1;
786  trans->to_max_rot[2] *= -1;
787 
788  if ((trans->from == TRANS_LOCATION && trans->map[1] != X) ||
789  (trans->from == TRANS_ROTATION && trans->map[1] != Y) || trans->from == TRANS_SCALE) {
790  /* Invert the Y rotation */
791  trans->to_min_rot[1] *= -1;
792  trans->to_max_rot[1] *= -1;
793  }
794 
795  copy_v3_v3(temp_vec, trans->to_max_rot);
796 
797  for (int i = 0; i < 3; i++) {
798  if ((trans->from == TRANS_LOCATION && trans->map[i] == X && i != 1) ||
799  (trans->from == TRANS_ROTATION && trans->map[i] == Y && i != 1) ||
800  (trans->from == TRANS_ROTATION && trans->map[i] == Z)) {
801  /* X Loc to X/Z Rot: Flipped
802  * Y Rot to X/Z Rot: Flipped
803  * Z Rot to X/Y/Z rot: Flipped */
804  trans->to_max_rot[i] = trans->to_min_rot[i];
805  trans->to_min_rot[i] = temp_vec[i];
806  }
807  }
808  break;
809  }
810  /* convert back to the settings space */
811  mul_m4_v3(imat, trans->to_min);
812  mul_m4_v3(imat, trans->to_max);
813  mul_m4_v3(imat_rot, trans->to_min_rot);
814  mul_m4_v3(imat_rot, trans->to_max_rot);
815  mul_m4_v3(imat, trans->to_min_scale);
816  mul_m4_v3(imat, trans->to_max_scale);
817 }
818 
819 static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig_bone, Object *ob)
820 {
821  /* If an edit bone has been duplicated, lets update its constraints if the
822  * subtarget they point to has also been duplicated.
823  */
824  bPoseChannel *pchan;
825  bConstraint *curcon;
826  ListBase *conlist;
827 
828  if ((pchan = BKE_pose_channel_verify(ob->pose, dup_bone->name)) == NULL ||
829  (conlist = &pchan->constraints) == NULL) {
830  return;
831  }
832 
833  for (curcon = conlist->first; curcon; curcon = curcon->next) {
834  switch (curcon->type) {
836  updateDuplicateActionConstraintSettings(dup_bone, orig_bone, ob, curcon);
837  break;
840  break;
843  updateDuplicateLocRotConstraintSettings(ob, pchan, curcon);
844  break;
847  break;
848  }
849  }
850 }
851 
853 {
854  if (ob->pose == NULL) {
855  return;
856  }
857  bPoseChannel *pchan;
858  pchan = BKE_pose_channel_verify(ob->pose, dup_bone->name);
859 
860  if (pchan->custom != NULL) {
861  Main *bmain = CTX_data_main(C);
862  char name_flip[MAX_ID_NAME - 2];
863 
864  /* Skip the first two chars in the object name as those are used to store object type */
865  BLI_string_flip_side_name(name_flip, pchan->custom->id.name + 2, false, sizeof(name_flip));
866  Object *shape_ob = (Object *)BKE_libblock_find_name(bmain, ID_OB, name_flip);
867 
868  if (shape_ob != NULL) {
869  /* A flipped shape object exists, use it! */
870  pchan->custom = shape_ob;
871  }
872  }
873 }
874 
875 static void copy_pchan(EditBone *src_bone, EditBone *dst_bone, Object *src_ob, Object *dst_ob)
876 {
877  /* copy the ID property */
878  if (src_bone->prop) {
879  dst_bone->prop = IDP_CopyProperty(src_bone->prop);
880  }
881 
882  /* Lets duplicate the list of constraints that the
883  * current bone has.
884  */
885  if (src_ob->pose) {
886  bPoseChannel *chanold, *channew;
887 
888  chanold = BKE_pose_channel_verify(src_ob->pose, src_bone->name);
889  if (chanold) {
890  /* WARNING: this creates a new posechannel, but there will not be an attached bone
891  * yet as the new bones created here are still 'EditBones' not 'Bones'.
892  */
893  channew = BKE_pose_channel_verify(dst_ob->pose, dst_bone->name);
894 
895  if (channew) {
896  BKE_pose_channel_copy_data(channew, chanold);
897  }
898  }
899  }
900 }
901 
903  EditBone *cur_bone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
904 {
905  EditBone *e_bone = MEM_mallocN(sizeof(EditBone), "addup_editbone");
906 
907  /* Copy data from old bone to new bone */
908  memcpy(e_bone, cur_bone, sizeof(EditBone));
909 
910  cur_bone->temp.ebone = e_bone;
911  e_bone->temp.ebone = cur_bone;
912 
913  if (name != NULL) {
914  BLI_strncpy(e_bone->name, name, sizeof(e_bone->name));
915  }
916 
917  ED_armature_ebone_unique_name(editbones, e_bone->name, NULL);
918  BLI_addtail(editbones, e_bone);
919 
920  copy_pchan(cur_bone, e_bone, src_ob, dst_ob);
921 
922  return e_bone;
923 }
924 
925 EditBone *duplicateEditBone(EditBone *cur_bone, const char *name, ListBase *editbones, Object *ob)
926 {
927  return duplicateEditBoneObjects(cur_bone, name, editbones, ob, ob);
928 }
929 
931 {
932  ViewLayer *view_layer = CTX_data_view_layer(C);
933  const bool do_flip_names = RNA_boolean_get(op->ptr, "do_flip_names");
934 
935  /* cancel if nothing selected */
936  if (CTX_DATA_COUNT(C, selected_bones) == 0) {
937  return OPERATOR_CANCELLED;
938  }
939 
940  uint objects_len = 0;
942  view_layer, CTX_wm_view3d(C), &objects_len);
943  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
944  EditBone *ebone_iter;
945  /* The beginning of the duplicated bones in the edbo list */
946  EditBone *ebone_first_dupe = NULL;
947 
948  Object *ob = objects[ob_index];
949  bArmature *arm = ob->data;
950 
951  ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
952 
954 
955  /* Select mirrored bones */
956  if (arm->flag & ARM_MIRROR_EDIT) {
957  for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
958  if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) {
959  EditBone *ebone;
960 
961  ebone = ED_armature_ebone_get_mirrored(arm->edbo, ebone_iter);
962  if (ebone) {
963  ebone->flag |= BONE_SELECTED;
964  }
965  }
966  }
967  }
968 
969  /* Find the selected bones and duplicate them as needed */
970  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
971  ebone_iter = ebone_iter->next) {
972  if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) {
973  EditBone *ebone;
974  char new_bone_name_buff[MAXBONENAME];
975  char *new_bone_name = ebone_iter->name;
976 
977  if (do_flip_names) {
979  new_bone_name_buff, ebone_iter->name, false, sizeof(new_bone_name_buff));
980 
981  /* Only use flipped name if not yet in use. Otherwise we'd get again inconsistent
982  * namings (different numbers), better keep default behavior in this case. */
983  if (ED_armature_ebone_find_name(arm->edbo, new_bone_name_buff) == NULL) {
984  new_bone_name = new_bone_name_buff;
985  }
986  }
987 
988  ebone = duplicateEditBone(ebone_iter, new_bone_name, arm->edbo, ob);
989 
990  if (!ebone_first_dupe) {
991  ebone_first_dupe = ebone;
992  }
993  }
994  }
995 
996  /* Run though the list and fix the pointers */
997  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
998  ebone_iter = ebone_iter->next) {
999  if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) {
1000  EditBone *ebone = ebone_iter->temp.ebone;
1001 
1002  if (!ebone_iter->parent) {
1003  /* If this bone has no parent,
1004  * Set the duplicate->parent to NULL
1005  */
1006  ebone->parent = NULL;
1007  }
1008  else if (ebone_iter->parent->temp.ebone) {
1009  /* If this bone has a parent that was duplicated,
1010  * Set the duplicate->parent to the cur_bone->parent->temp
1011  */
1012  ebone->parent = ebone_iter->parent->temp.ebone;
1013  }
1014  else {
1015  /* If this bone has a parent that IS not selected,
1016  * Set the duplicate->parent to the cur_bone->parent
1017  */
1018  ebone->parent = (EditBone *)ebone_iter->parent;
1019  ebone->flag &= ~BONE_CONNECTED;
1020  }
1021 
1022  /* Update custom handle links. */
1023  if (ebone_iter->bbone_prev && ebone_iter->bbone_prev->temp.ebone) {
1024  ebone->bbone_prev = ebone_iter->bbone_prev->temp.ebone;
1025  }
1026  if (ebone_iter->bbone_next && ebone_iter->bbone_next->temp.ebone) {
1027  ebone->bbone_next = ebone_iter->bbone_next->temp.ebone;
1028  }
1029 
1030  /* Lets try to fix any constraint subtargets that might
1031  * have been duplicated
1032  */
1033  updateDuplicateSubtarget(ebone, arm->edbo, ob, false);
1034  }
1035  }
1036 
1037  /* correct the active bone */
1038  if (arm->act_edbone && arm->act_edbone->temp.ebone) {
1039  arm->act_edbone = arm->act_edbone->temp.ebone;
1040  }
1041 
1042  /* Deselect the old bones and select the new ones */
1043  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
1044  ebone_iter = ebone_iter->next) {
1045  if (EBONE_VISIBLE(arm, ebone_iter)) {
1046  ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1047  }
1048  }
1049 
1050  postEditBoneDuplicate(arm->edbo, ob);
1051 
1053 
1056  }
1057  MEM_freeN(objects);
1058 
1060 
1061  return OPERATOR_FINISHED;
1062 }
1063 
1065 {
1066  /* identifiers */
1067  ot->name = "Duplicate Selected Bone(s)";
1068  ot->idname = "ARMATURE_OT_duplicate";
1069  ot->description = "Make copies of the selected bones within the same armature";
1070 
1071  /* api callbacks */
1074 
1075  /* flags */
1077 
1079  ot->srna,
1080  "do_flip_names",
1081  false,
1082  "Flip Names",
1083  "Try to flip names of the bones, if possible, instead of adding a number extension");
1084 }
1085 
1086 /* Get the duplicated or existing mirrored copy of the bone. */
1088 {
1089  if (bone == NULL) {
1090  return NULL;
1091  }
1092  if (bone->temp.ebone != NULL) {
1093  return bone->temp.ebone;
1094  }
1095 
1096  EditBone *mirror = ED_armature_ebone_get_mirrored(arm->edbo, bone);
1097  return (mirror != NULL) ? mirror : bone;
1098 }
1099 
1105 {
1106  ViewLayer *view_layer = CTX_data_view_layer(C);
1107  const int direction = RNA_enum_get(op->ptr, "direction");
1108  const int axis = 0;
1109 
1110  /* cancel if nothing selected */
1111  if (CTX_DATA_COUNT(C, selected_bones) == 0) {
1112  return OPERATOR_CANCELLED;
1113  }
1114 
1115  uint objects_len = 0;
1117  view_layer, CTX_wm_view3d(C), &objects_len);
1118  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1119  Object *obedit = objects[ob_index];
1120  bArmature *arm = obedit->data;
1121 
1122  EditBone *ebone_iter;
1123  /* The beginning of the duplicated mirrored bones in the edbo list */
1124  EditBone *ebone_first_dupe = NULL;
1125 
1126  ED_armature_edit_sync_selection(arm->edbo); /* XXX why is this needed? */
1127 
1128  preEditBoneDuplicate(arm->edbo);
1129 
1130  /* Select mirrored bones */
1131  for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
1132  if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) {
1133  char name_flip[MAXBONENAME];
1134 
1135  BLI_string_flip_side_name(name_flip, ebone_iter->name, false, sizeof(name_flip));
1136 
1137  if (STREQ(name_flip, ebone_iter->name)) {
1138  /* if the name matches, we don't have the potential to be mirrored, just skip */
1139  ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1140  }
1141  else {
1142  EditBone *ebone = ED_armature_ebone_find_name(arm->edbo, name_flip);
1143 
1144  if (ebone) {
1145  if ((ebone->flag & BONE_SELECTED) == 0) {
1146  /* simple case, we're selected, the other bone isn't! */
1147  ebone_iter->temp.ebone = ebone;
1148  }
1149  else {
1150  /* complicated - choose which direction to copy */
1151  float axis_delta;
1152 
1153  axis_delta = ebone->head[axis] - ebone_iter->head[axis];
1154  if (axis_delta == 0.0f) {
1155  axis_delta = ebone->tail[axis] - ebone_iter->tail[axis];
1156  }
1157 
1158  if (axis_delta == 0.0f) {
1159  /* both mirrored bones exist and point to eachother and overlap exactly.
1160  *
1161  * in this case there's no well defined solution, so de-select both and skip.
1162  */
1163  ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1164  ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1165  }
1166  else {
1167  EditBone *ebone_src, *ebone_dst;
1168  if (((axis_delta < 0.0f) ? -1 : 1) == direction) {
1169  ebone_src = ebone;
1170  ebone_dst = ebone_iter;
1171  }
1172  else {
1173  ebone_src = ebone_iter;
1174  ebone_dst = ebone;
1175  }
1176 
1177  ebone_src->temp.ebone = ebone_dst;
1178  ebone_dst->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1179  }
1180  }
1181  }
1182  }
1183  }
1184  }
1185 
1186  /* Find the selected bones and duplicate them as needed, with mirrored name. */
1187  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
1188  ebone_iter = ebone_iter->next) {
1189  if (EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED)) {
1190  if (ebone_iter->temp.ebone != NULL) {
1191  /* This will be set if the mirror bone already exists (no need to make a new one)
1192  * but we do need to make sure that the 'pchan' settings (constraints etc)
1193  * is synchronized. */
1194  bPoseChannel *pchan;
1195  /* Make sure we clean up the old data before overwriting it */
1196  pchan = BKE_pose_channel_verify(obedit->pose, ebone_iter->temp.ebone->name);
1197  BKE_pose_channel_free(pchan);
1198  /* Sync pchan data */
1199  copy_pchan(ebone_iter, ebone_iter->temp.ebone, obedit, obedit);
1200  /* Sync scale mode */
1201  ebone_iter->temp.ebone->inherit_scale_mode = ebone_iter->inherit_scale_mode;
1202  continue;
1203  }
1204  char name_flip[MAXBONENAME];
1205 
1206  BLI_string_flip_side_name(name_flip, ebone_iter->name, false, sizeof(name_flip));
1207 
1208  /* bones must have a side-suffix */
1209  if (!STREQ(name_flip, ebone_iter->name)) {
1210  EditBone *ebone;
1211 
1212  ebone = duplicateEditBone(ebone_iter, name_flip, arm->edbo, obedit);
1213 
1214  if (!ebone_first_dupe) {
1215  ebone_first_dupe = ebone;
1216  }
1217  }
1218  }
1219  }
1220 
1221  /* Run through the list and fix the pointers. */
1222  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
1223  ebone_iter = ebone_iter->next) {
1224  if (ebone_iter->temp.ebone) {
1225  /* copy all flags except for ... */
1226  const int flag_copy = ((int)~0) & ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
1227 
1228  EditBone *ebone = ebone_iter->temp.ebone;
1229 
1230  /* Copy flags in case bone is pre-existing data. */
1231  ebone->flag = (ebone->flag & ~flag_copy) | (ebone_iter->flag & flag_copy);
1232 
1233  if (ebone_iter->parent == NULL) {
1234  /* If this bone has no parent,
1235  * Set the duplicate->parent to NULL
1236  */
1237  ebone->parent = NULL;
1238  ebone->flag &= ~BONE_CONNECTED;
1239  }
1240  else {
1241  /* the parent may have been duplicated, if not lookup the mirror parent */
1242  EditBone *ebone_parent = get_symmetrized_bone(arm, ebone_iter->parent);
1243 
1244  if (ebone_parent == ebone_iter->parent) {
1245  /* If the mirror lookup failed, (but the current bone has a parent)
1246  * then we can assume the parent has no L/R but is a center bone.
1247  * So just use the same parent for both.
1248  */
1249 
1250  if (ebone->head[axis] != 0.0f) {
1251  /* The mirrored bone doesn't start on the mirror axis, so assume that this one should
1252  * not be connected to the old parent */
1253  ebone->flag &= ~BONE_CONNECTED;
1254  }
1255  }
1256 
1257  ebone->parent = ebone_parent;
1258  }
1259 
1260  /* Update custom handle links. */
1261  ebone->bbone_prev = get_symmetrized_bone(arm, ebone_iter->bbone_prev);
1262  ebone->bbone_next = get_symmetrized_bone(arm, ebone_iter->bbone_next);
1263 
1264  /* Sync bbone handle types */
1265  ebone->bbone_prev_type = ebone_iter->bbone_prev_type;
1266  ebone->bbone_next_type = ebone_iter->bbone_next_type;
1267 
1268  /* Lets try to fix any constraint subtargets that might
1269  * have been duplicated
1270  */
1271  updateDuplicateSubtarget(ebone, arm->edbo, obedit, true);
1272  /* Try to update constraint options so that they are mirrored as well
1273  * (need to supply bone_iter as well in case we are working with existing bones) */
1274  updateDuplicateConstraintSettings(ebone, ebone_iter, obedit);
1275  /* Mirror bone shapes if possible */
1276  updateDuplicateCustomBoneShapes(C, ebone, obedit);
1277  }
1278  }
1279 
1281 
1282  /* Selected bones now have their 'temp' pointer set,
1283  * so we don't need this anymore */
1284 
1285  /* Deselect the old bones and select the new ones */
1286  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
1287  ebone_iter = ebone_iter->next) {
1288  if (EBONE_VISIBLE(arm, ebone_iter)) {
1289  ebone_iter->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1290  }
1291  }
1292 
1293  /* New bones will be selected, but some of the bones may already exist */
1294  for (ebone_iter = arm->edbo->first; ebone_iter && ebone_iter != ebone_first_dupe;
1295  ebone_iter = ebone_iter->next) {
1296  EditBone *ebone = ebone_iter->temp.ebone;
1297  if (ebone && EBONE_SELECTABLE(arm, ebone)) {
1298  ED_armature_ebone_select_set(ebone, true);
1299  }
1300  }
1301 
1302  /* correct the active bone */
1303  if (arm->act_edbone && arm->act_edbone->temp.ebone) {
1304  arm->act_edbone = arm->act_edbone->temp.ebone;
1305  }
1306 
1307  postEditBoneDuplicate(arm->edbo, obedit);
1308 
1310 
1313  }
1314  MEM_freeN(objects);
1315 
1316  return OPERATOR_FINISHED;
1317 }
1318 
1319 /* following conventions from #MESH_OT_symmetrize */
1321 {
1322  /* subset of 'rna_enum_symmetrize_direction_items' */
1323  static const EnumPropertyItem arm_symmetrize_direction_items[] = {
1324  {-1, "NEGATIVE_X", 0, "-X to +X", ""},
1325  {+1, "POSITIVE_X", 0, "+X to -X", ""},
1326  {0, NULL, 0, NULL, NULL},
1327  };
1328 
1329  /* identifiers */
1330  ot->name = "Symmetrize";
1331  ot->idname = "ARMATURE_OT_symmetrize";
1332  ot->description = "Enforce symmetry, make copies of the selection or use existing";
1333 
1334  /* api callbacks */
1337 
1338  /* flags */
1340 
1341  ot->prop = RNA_def_enum(ot->srna,
1342  "direction",
1343  arm_symmetrize_direction_items,
1344  -1,
1345  "Direction",
1346  "Which sides to copy from and to (when both are selected)");
1347 }
1348 
1349 /* ------------------------------------------ */
1350 
1351 /* previously extrude_armature */
1352 /* context; editmode armature */
1353 /* if forked && mirror-edit: makes two bones with flipped names */
1355 {
1356  ViewLayer *view_layer = CTX_data_view_layer(C);
1357  const bool forked = RNA_boolean_get(op->ptr, "forked");
1358  bool changed_multi = false;
1359 
1360  uint objects_len = 0;
1362  view_layer, CTX_wm_view3d(C), &objects_len);
1363  for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1364  Object *ob = objects[ob_index];
1365  bArmature *arm = ob->data;
1366  bool forked_iter = forked;
1367 
1368  EditBone *newbone = NULL, *ebone, *flipbone, *first = NULL;
1369  int a, totbone = 0, do_extrude;
1370 
1371  /* since we allow root extrude too, we have to make sure selection is OK */
1372  for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
1373  if (EBONE_VISIBLE(arm, ebone)) {
1374  if (ebone->flag & BONE_ROOTSEL) {
1375  if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
1376  if (ebone->parent->flag & BONE_TIPSEL) {
1377  ebone->flag &= ~BONE_ROOTSEL;
1378  }
1379  }
1380  }
1381  }
1382  }
1383 
1384  /* Duplicate the necessary bones */
1385  for (ebone = arm->edbo->first; ((ebone) && (ebone != first)); ebone = ebone->next) {
1386  if (EBONE_VISIBLE(arm, ebone)) {
1387  /* we extrude per definition the tip */
1388  do_extrude = false;
1389  if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) {
1390  do_extrude = true;
1391  }
1392  else if (ebone->flag & BONE_ROOTSEL) {
1393  /* but, a bone with parent deselected we do the root... */
1394  if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) {
1395  /* pass */
1396  }
1397  else {
1398  do_extrude = 2;
1399  }
1400  }
1401 
1402  if (do_extrude) {
1403  /* we re-use code for mirror editing... */
1404  flipbone = NULL;
1405  if (arm->flag & ARM_MIRROR_EDIT) {
1406  flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
1407  if (flipbone) {
1408  forked_iter = 0; /* we extrude 2 different bones */
1409  if (flipbone->flag & (BONE_TIPSEL | BONE_ROOTSEL | BONE_SELECTED)) {
1410  /* don't want this bone to be selected... */
1411  flipbone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
1412  }
1413  }
1414  if ((flipbone == NULL) && (forked_iter)) {
1415  flipbone = ebone;
1416  }
1417  }
1418 
1419  for (a = 0; a < 2; a++) {
1420  if (a == 1) {
1421  if (flipbone == NULL) {
1422  break;
1423  }
1424  SWAP(EditBone *, flipbone, ebone);
1425  }
1426 
1427  totbone++;
1428  newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
1429 
1430  if (do_extrude == true) {
1431  copy_v3_v3(newbone->head, ebone->tail);
1432  copy_v3_v3(newbone->tail, newbone->head);
1433  newbone->parent = ebone;
1434 
1435  /* copies it, in case mirrored bone */
1436  newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING);
1437 
1438  if (newbone->parent) {
1439  newbone->flag |= BONE_CONNECTED;
1440  }
1441  }
1442  else {
1443  copy_v3_v3(newbone->head, ebone->head);
1444  copy_v3_v3(newbone->tail, ebone->head);
1445  newbone->parent = ebone->parent;
1446 
1447  newbone->flag = BONE_TIPSEL;
1448 
1449  if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
1450  newbone->flag |= BONE_CONNECTED;
1451  }
1452  }
1453 
1454  newbone->weight = ebone->weight;
1455  newbone->dist = ebone->dist;
1456  newbone->xwidth = ebone->xwidth;
1457  newbone->zwidth = ebone->zwidth;
1458  newbone->rad_head = ebone->rad_tail; /* don't copy entire bone. */
1459  newbone->rad_tail = ebone->rad_tail;
1460  newbone->segments = 1;
1461  newbone->layer = ebone->layer;
1462 
1463  /* Bendy-Bone parameters */
1464  newbone->roll1 = ebone->roll1;
1465  newbone->roll2 = ebone->roll2;
1466  newbone->curve_in_x = ebone->curve_in_x;
1467  newbone->curve_in_y = ebone->curve_in_y;
1468  newbone->curve_out_x = ebone->curve_out_x;
1469  newbone->curve_out_y = ebone->curve_out_y;
1470  newbone->ease1 = ebone->ease1;
1471  newbone->ease2 = ebone->ease2;
1472  newbone->scale_in_x = ebone->scale_in_x;
1473  newbone->scale_in_y = ebone->scale_in_y;
1474  newbone->scale_out_x = ebone->scale_out_x;
1475  newbone->scale_out_y = ebone->scale_out_y;
1476 
1477  BLI_strncpy(newbone->name, ebone->name, sizeof(newbone->name));
1478 
1479  if (flipbone && forked_iter) { /* only set if mirror edit */
1480  if (strlen(newbone->name) < (MAXBONENAME - 2)) {
1481  if (a == 0) {
1482  strcat(newbone->name, "_L");
1483  }
1484  else {
1485  strcat(newbone->name, "_R");
1486  }
1487  }
1488  }
1489  ED_armature_ebone_unique_name(arm->edbo, newbone->name, NULL);
1490 
1491  /* Add the new bone to the list */
1492  BLI_addtail(arm->edbo, newbone);
1493  if (!first) {
1494  first = newbone;
1495  }
1496 
1497  /* restore ebone if we were flipping */
1498  if (a == 1 && flipbone) {
1499  SWAP(EditBone *, flipbone, ebone);
1500  }
1501  }
1502  }
1503 
1504  /* Deselect the old bone */
1505  ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
1506  }
1507  }
1508  /* if only one bone, make this one active */
1509  if (totbone == 1 && first) {
1510  arm->act_edbone = first;
1511  }
1512  else {
1513  arm->act_edbone = newbone;
1514  }
1515 
1516  if (totbone == 0) {
1517  continue;
1518  }
1519 
1520  changed_multi = true;
1521 
1522  /* Transform the endpoints */
1524 
1527  }
1528  MEM_freeN(objects);
1529 
1530  if (!changed_multi) {
1531  return OPERATOR_CANCELLED;
1532  }
1533 
1535 
1536  return OPERATOR_FINISHED;
1537 }
1538 
1540 {
1541  /* identifiers */
1542  ot->name = "Extrude";
1543  ot->idname = "ARMATURE_OT_extrude";
1544  ot->description = "Create new bones from the selected joints";
1545 
1546  /* api callbacks */
1549 
1550  /* flags */
1552 
1553  /* props */
1554  RNA_def_boolean(ot->srna, "forked", 0, "Forked", "");
1555 }
1556 
1557 /* ********************** Bone Add *************************************/
1558 
1559 /*op makes a new bone and returns it with its tip selected */
1560 
1562 {
1564  Object *obedit = CTX_data_edit_object(C);
1565  EditBone *bone;
1566  float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
1567  char name[MAXBONENAME];
1568 
1569  RNA_string_get(op->ptr, "name", name);
1570 
1571  copy_v3_v3(curs, CTX_data_scene(C)->cursor.location);
1572 
1573  /* Get inverse point for head and orientation for tail */
1574  invert_m4_m4(obedit->imat, obedit->obmat);
1575  mul_m4_v3(obedit->imat, curs);
1576 
1577  if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) {
1578  copy_m3_m4(obmat, rv3d->viewmat);
1579  }
1580  else {
1581  unit_m3(obmat);
1582  }
1583 
1584  copy_m3_m4(viewmat, obedit->obmat);
1585  mul_m3_m3m3(totmat, obmat, viewmat);
1586  invert_m3_m3(imat, totmat);
1587 
1589 
1590  /* Create a bone. */
1591  bone = ED_armature_ebone_add(obedit->data, name);
1592 
1593  copy_v3_v3(bone->head, curs);
1594 
1595  if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) {
1596  add_v3_v3v3(bone->tail, bone->head, imat[1]); /* bone with unit length 1 */
1597  }
1598  else {
1599  add_v3_v3v3(bone->tail, bone->head, imat[2]); /* bone with unit length 1, pointing up Z */
1600  }
1601 
1603 
1604  /* note, notifier might evolve */
1608 
1609  return OPERATOR_FINISHED;
1610 }
1611 
1613 {
1614  /* identifiers */
1615  ot->name = "Add Bone";
1616  ot->idname = "ARMATURE_OT_bone_primitive_add";
1617  ot->description = "Add a new bone located at the 3D cursor";
1618 
1619  /* api callbacks */
1622 
1623  /* flags */
1625 
1626  RNA_def_string(ot->srna, "name", "Bone", MAXBONENAME, "Name", "Name of the newly created bone");
1627 }
1628 
1629 /* ********************** Subdivide *******************************/
1630 
1631 /* Subdivide Operators:
1632  * This group of operators all use the same 'exec' callback, but they are called
1633  * through several different operators - a combined menu (which just calls the exec in the
1634  * appropriate ways), and two separate ones.
1635  */
1636 
1638 {
1639  Object *obedit = CTX_data_edit_object(C);
1640  EditBone *newbone, *tbone;
1641  int cuts, i;
1642 
1643  /* there may not be a number_cuts property defined (for 'simple' subdivide) */
1644  cuts = RNA_int_get(op->ptr, "number_cuts");
1645 
1646  /* loop over all editable bones */
1647  /* XXX the old code did this in reverse order though! */
1648  CTX_DATA_BEGIN_WITH_ID (C, EditBone *, ebone, selected_editable_bones, bArmature *, arm) {
1649  for (i = cuts + 1; i > 1; i--) {
1650  /* compute cut ratio first */
1651  float cutratio = 1.0f / (float)i;
1652  float cutratioI = 1.0f - cutratio;
1653 
1654  float val1[3];
1655  float val2[3];
1656  float val3[3];
1657 
1658  newbone = MEM_mallocN(sizeof(EditBone), "ebone subdiv");
1659  *newbone = *ebone;
1660  BLI_addtail(arm->edbo, newbone);
1661 
1662  /* calculate location of newbone->head */
1663  copy_v3_v3(val1, ebone->head);
1664  copy_v3_v3(val2, ebone->tail);
1665  copy_v3_v3(val3, newbone->head);
1666 
1667  val3[0] = val1[0] * cutratio + val2[0] * cutratioI;
1668  val3[1] = val1[1] * cutratio + val2[1] * cutratioI;
1669  val3[2] = val1[2] * cutratio + val2[2] * cutratioI;
1670 
1671  copy_v3_v3(newbone->head, val3);
1672  copy_v3_v3(newbone->tail, ebone->tail);
1673  copy_v3_v3(ebone->tail, newbone->head);
1674 
1675  newbone->rad_head = ((ebone->rad_head * cutratio) + (ebone->rad_tail * cutratioI));
1676  ebone->rad_tail = newbone->rad_head;
1677 
1678  newbone->flag |= BONE_CONNECTED;
1679 
1680  newbone->prop = NULL;
1681 
1682  ED_armature_ebone_unique_name(arm->edbo, newbone->name, NULL);
1683 
1684  /* correct parent bones */
1685  for (tbone = arm->edbo->first; tbone; tbone = tbone->next) {
1686  if (tbone->parent == ebone) {
1687  tbone->parent = newbone;
1688  }
1689  }
1690  newbone->parent = ebone;
1691  }
1692  }
1693  CTX_DATA_END;
1694 
1695  /* note, notifier might evolve */
1699 
1700  return OPERATOR_FINISHED;
1701 }
1702 
1704 {
1705  PropertyRNA *prop;
1706 
1707  /* identifiers */
1708  ot->name = "Subdivide";
1709  ot->idname = "ARMATURE_OT_subdivide";
1710  ot->description = "Break selected bones into chains of smaller bones";
1711 
1712  /* api callbacks */
1715 
1716  /* flags */
1718 
1719  /* Properties */
1720  prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, 1000, "Number of Cuts", "", 1, 10);
1721  /* Avoid re-using last var because it can cause
1722  * _very_ high poly meshes and annoy users (or worse crash) */
1724 }
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bActionGroup * action_groups_add_new(struct bAction *act, const char name[])
Definition: action.c:402
void BKE_pose_channels_hash_free(struct bPose *pose)
Definition: action.c:960
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from)
void BKE_pose_channels_hash_make(struct bPose *pose)
Definition: action.c:948
void BKE_pose_channel_free(struct bPoseChannel *pchan)
Definition: action.c:1117
struct bActionGroup * BKE_action_group_find_name(struct bAction *act, const char name[])
Definition: action.c:579
struct bPoseChannel * BKE_pose_channel_verify(struct bPose *pose, const char *name)
Definition: action.c:638
void action_groups_add_channel(struct bAction *act, struct bActionGroup *agrp, struct FCurve *fcurve)
Definition: action.c:431
void BKE_constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, struct bConstraintOb *cob, float mat[4][4], short from, short to, const bool keep_scale)
Definition: constraint.c:264
void BKE_constraint_custom_object_space_get(float r_mat[4][4], struct bConstraint *con)
Definition: constraint.c:6140
const bConstraintTypeInfo * BKE_constraint_typeinfo_get(struct bConstraint *con)
Definition: constraint.c:5435
#define CTX_DATA_BEGIN_WITH_ID(C, Type, instance, member, Type_id, instance_id)
Definition: BKE_context.h:266
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct Object * CTX_data_edit_object(const bContext *C)
Definition: context.c:1296
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
#define CTX_DATA_COUNT(C, member)
Definition: BKE_context.h:272
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
#define CTX_DATA_END
Definition: BKE_context.h:260
support for deformation groups and hooks.
int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName)
Definition: fcurve.c:336
struct FCurve * BKE_fcurve_copy(const struct FCurve *fcu)
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:426
struct ID * BKE_libblock_find_name(struct Main *bmain, const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: lib_id.c:1333
#define BLI_assert(a)
Definition: BLI_assert.h:58
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
#define M_PI
Definition: BLI_math_base.h:38
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1161
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
float angle_wrap_rad(float angle)
MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t length) ATTR_NONNULL()
Definition: string.c:1017
char * BLI_str_replaceN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:470
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
Definition: string_utils.c:159
unsigned int uint
Definition: BLI_sys_types.h:83
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SELECT
Definition: DNA_ID.h:638
@ ID_RECALC_ANIMATION_NO_FLUSH
Definition: DNA_ID.h:690
#define MAX_ID_NAME
Definition: DNA_ID.h:269
@ ID_OB
Definition: DNA_ID_enums.h:59
#define MAXBONENAME
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_TIPSEL
@ BONE_CONNECTED
@ BONE_RELATIVE_PARENTING
@ ARM_MIRROR_EDIT
@ CONSTRAINT_TYPE_TRANSFORM
@ CONSTRAINT_TYPE_ROTLIMIT
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_LOCLIMIT
@ CONSTRAINT_TYPE_ACTION
@ CONSTRAINT_SPACE_LOCAL
@ TRANS_SCALE
@ TRANS_ROTATION
@ TRANS_LOCATION
Object is a sort of wrapper for general info.
@ USER_ADD_VIEWALIGNED
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
#define EBONE_VISIBLE(arm, ebone)
Definition: ED_armature.h:56
#define EBONE_SELECTABLE(arm, ebone)
Definition: ED_armature.h:61
void ED_outliner_select_sync_from_edit_bone_tag(struct bContext *C)
Definition: outliner_sync.c:62
bool ED_operator_editarmature(struct bContext *C)
Definition: screen_ops.c:437
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
#define X
Definition: GeomUtils.cpp:213
#define Z
Definition: GeomUtils.cpp:215
#define Y
Definition: GeomUtils.cpp:214
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_BONE_SELECT
Definition: WM_types.h:361
#define NC_OBJECT
Definition: WM_types.h:280
static void updateDuplicateKinematicConstraintSettings(bConstraint *curcon)
Definition: armature_add.c:576
void ARMATURE_OT_subdivide(wmOperatorType *ot)
static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
Definition: armature_add.c:930
void postEditBoneDuplicate(struct ListBase *editbones, Object *ob)
Definition: armature_add.c:335
static int armature_extrude_exec(bContext *C, wmOperator *op)
static void updateDuplicateSubtarget(EditBone *dup_bone, ListBase *editbones, Object *ob, bool lookup_mirror_subtarget)
Definition: armature_add.c:380
static void updateDuplicateActionConstraintSettings(EditBone *dup_bone, EditBone *orig_bone, Object *ob, bConstraint *curcon)
Definition: armature_add.c:442
static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
Definition: armature_add.c:133
static EditBone * get_symmetrized_bone(bArmature *arm, EditBone *bone)
static void updateDuplicateTransformConstraintSettings(Object *ob, bPoseChannel *pchan, bConstraint *curcon)
Definition: armature_add.c:655
void ARMATURE_OT_click_extrude(wmOperatorType *ot)
Definition: armature_add.c:260
static void updateDuplicateConstraintSettings(EditBone *dup_bone, EditBone *orig_bone, Object *ob)
Definition: armature_add.c:819
EditBone * ED_armature_ebone_add_primitive(Object *obedit_arm, float length, bool view_aligned)
Definition: armature_add.c:105
void ARMATURE_OT_duplicate(wmOperatorType *ot)
void ARMATURE_OT_symmetrize(wmOperatorType *ot)
void ARMATURE_OT_extrude(wmOperatorType *ot)
static int armature_symmetrize_exec(bContext *C, wmOperator *op)
static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: armature_add.c:227
static int armature_subdivide_exec(bContext *C, wmOperator *op)
EditBone * add_points_bone(Object *obedit, float head[3], float tail[3])
Definition: armature_add.c:279
EditBone * ED_armature_ebone_add(bArmature *arm, const char *name)
Definition: armature_add.c:69
void ARMATURE_OT_bone_primitive_add(wmOperatorType *ot)
static bPoseChannel * pchan_duplicate_map(const bPose *pose, GHash *name_map, bPoseChannel *pchan_src)
Definition: armature_add.c:317
static void updateDuplicateLocRotConstraintSettings(Object *ob, bPoseChannel *pchan, bConstraint *curcon)
Definition: armature_add.c:585
static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
EditBone * duplicateEditBone(EditBone *cur_bone, const char *name, ListBase *editbones, Object *ob)
Definition: armature_add.c:925
void preEditBoneDuplicate(ListBase *editbones)
Definition: armature_add.c:307
EditBone * duplicateEditBoneObjects(EditBone *cur_bone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
Definition: armature_add.c:902
static EditBone * get_named_editbone(ListBase *edbo, const char *name)
Definition: armature_add.c:291
static void updateDuplicateCustomBoneShapes(bContext *C, EditBone *dup_bone, Object *ob)
Definition: armature_add.c:852
static void copy_pchan(EditBone *src_bone, EditBone *dst_bone, Object *src_ob, Object *dst_ob)
Definition: armature_add.c:875
void ED_armature_ebone_unique_name(ListBase *ebones, char *name, EditBone *bone)
bool ED_armature_edit_deselect_all(Object *obedit)
void ED_armature_edit_transform_mirror_update(Object *obedit)
void ED_armature_ebone_listbase_temp_clear(ListBase *lb)
void ED_armature_edit_refresh_layer_used(bArmature *arm)
void ED_armature_edit_sync_selection(ListBase *edbo)
void ED_armature_ebone_select_set(EditBone *ebone, bool select)
void ED_armature_edit_validate_active(struct bArmature *arm)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
EditBone * ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo)
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
Scene scene
#define fabsf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static unsigned a[3]
Definition: RandGen.cpp:92
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3675
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
float vec[3][3]
char name[64]
Definition: BKE_armature.h:57
float ease2
Definition: BKE_armature.h:85
float weight
Definition: BKE_armature.h:75
float roll1
Definition: BKE_armature.h:82
float scale_out_y
Definition: BKE_armature.h:87
struct EditBone * next
Definition: BKE_armature.h:49
short segments
Definition: BKE_armature.h:81
float tail[3]
Definition: BKE_armature.h:66
char bbone_prev_type
Definition: BKE_armature.h:93
float roll2
Definition: BKE_armature.h:82
struct EditBone * ebone
Definition: BKE_armature.h:112
float curve_in_x
Definition: BKE_armature.h:83
float scale_out_x
Definition: BKE_armature.h:87
float zwidth
Definition: BKE_armature.h:77
struct EditBone * bbone_next
Definition: BKE_armature.h:97
float length
Definition: BKE_armature.h:77
float xwidth
Definition: BKE_armature.h:77
float dist
Definition: BKE_armature.h:75
float curve_in_y
Definition: BKE_armature.h:83
char bbone_next_type
Definition: BKE_armature.h:94
struct EditBone * parent
Definition: BKE_armature.h:55
float rad_tail
Definition: BKE_armature.h:78
union EditBone::@2 temp
struct IDProperty * prop
Definition: BKE_armature.h:51
float ease1
Definition: BKE_armature.h:85
float rad_head
Definition: BKE_armature.h:78
char inherit_scale_mode
Definition: BKE_armature.h:72
float curve_out_y
Definition: BKE_armature.h:84
float curve_out_x
Definition: BKE_armature.h:84
struct EditBone * bbone_prev
Definition: BKE_armature.h:96
float scale_in_y
Definition: BKE_armature.h:86
float head[3]
Definition: BKE_armature.h:65
float scale_in_x
Definition: BKE_armature.h:86
char * rna_path
BezTriple * bezt
int array_index
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
struct bPose * pose
float imat[4][4]
float obmat[4][4]
void * data
float viewmat[4][4]
View3DCursor cursor
struct bAction * act
struct EditBone * act_edbone
unsigned int layer
ListBase * edbo
float space_obj_world_matrix[4][4]
struct Depsgraph * depsgraph
struct bConstraintTarget * next
int(* get_constraint_targets)(struct bConstraint *con, struct ListBase *list)
void(* flush_constraint_targets)(struct bConstraint *con, struct ListBase *list, bool no_copy)
struct bConstraint * next
ListBase constraints
struct bPoseChannel * custom_tx
struct bPoseChannel * bbone_next
struct Object * custom
struct bPoseChannel * bbone_prev
int mval[2]
Definition: WM_types.h:583
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156