Blender  V3.3
transform_convert_armature.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "DNA_armature_types.h"
9 #include "DNA_constraint_types.h"
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_ghash.h"
14 #include "BLI_listbase.h"
15 #include "BLI_math.h"
16 #include "BLI_string.h"
17 
18 #include "BKE_action.h"
19 #include "BKE_animsys.h"
20 #include "BKE_armature.h"
21 #include "BKE_constraint.h"
22 #include "BKE_context.h"
23 #include "BKE_main.h"
24 #include "BKE_report.h"
25 
26 #include "BIK_api.h"
27 
28 #include "ED_armature.h"
29 #include "ED_keyframing.h"
30 
31 #include "DEG_depsgraph.h"
32 #include "DEG_depsgraph_query.h"
33 
34 #include "RNA_access.h"
35 #include "RNA_prototypes.h"
36 
37 #include "transform.h"
38 #include "transform_snap.h"
39 
40 /* Own include. */
41 #include "transform_convert.h"
42 
43 typedef struct BoneInitData {
44  struct EditBone *bone;
45  float tail[3];
46  float rad_head;
47  float rad_tail;
48  float roll;
49  float head[3];
50  float dist;
51  float xwidth;
52  float zwidth;
54 
55 /* Return if we need to update motion paths, only if they already exist,
56  * and we will insert a keyframe at the end of transform. */
58 {
59  if (autokeyframe_cfra_can_key(scene, &ob->id)) {
60  return (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
61  }
62 
63  return false;
64 }
65 
76 static void autokeyframe_pose(
77  bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
78 {
79  Main *bmain = CTX_data_main(C);
80  ID *id = &ob->id;
81  AnimData *adt = ob->adt;
82  bAction *act = (adt) ? adt->action : NULL;
83  bPose *pose = ob->pose;
84  bPoseChannel *pchan;
85  FCurve *fcu;
86 
88  return;
89  }
90 
91  ReportList *reports = CTX_wm_reports(C);
94  ListBase nla_cache = {NULL, NULL};
97  depsgraph, (float)scene->r.cfra);
99 
100  /* flag is initialized from UserPref keyframing settings
101  * - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
102  * visual keyframes even if flag not set, as it's not that useful otherwise
103  * (for quick animation recording)
104  */
106 
107  if (targetless_ik) {
109  }
110 
111  for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
112  if ((pchan->bone->flag & BONE_TRANSFORM) == 0 &&
113  !((pose->flag & POSE_MIRROR_EDIT) && (pchan->bone->flag & BONE_TRANSFORM_MIRROR))) {
114  continue;
115  }
116 
117  ListBase dsources = {NULL, NULL};
118 
119  /* Add data-source override for the camera object. */
120  ANIM_relative_keyingset_add_source(&dsources, id, &RNA_PoseBone, pchan);
121 
122  /* only insert into active keyingset? */
123  if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) {
124  /* Run the active Keying Set on the current data-source. */
126  C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
127  }
128  /* only insert into available channels? */
129  else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) {
130  if (act) {
131  for (fcu = act->curves.first; fcu; fcu = fcu->next) {
132  /* only insert keyframes for this F-Curve if it affects the current bone */
133  char pchan_name[sizeof(pchan->name)];
134  if (!BLI_str_quoted_substr(fcu->rna_path, "bones[", pchan_name, sizeof(pchan_name))) {
135  continue;
136  }
137 
138  /* only if bone name matches too...
139  * NOTE: this will do constraints too, but those are ok to do here too?
140  */
141  if (STREQ(pchan_name, pchan->name)) {
142  insert_keyframe(bmain,
143  reports,
144  id,
145  act,
146  ((fcu->grp) ? (fcu->grp->name) : (NULL)),
147  fcu->rna_path,
148  fcu->array_index,
149  &anim_eval_context,
150  ts->keyframe_type,
151  &nla_cache,
152  flag);
153  }
154  }
155  }
156  }
157  /* only insert keyframe if needed? */
158  else if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED)) {
159  bool do_loc = false, do_rot = false, do_scale = false;
160 
161  /* Filter the conditions when this happens
162  * (assume that 'curarea->spacetype == SPACE_VIEW3D'). */
163  if (tmode == TFM_TRANSLATION) {
164  if (targetless_ik) {
165  do_rot = true;
166  }
167  else {
168  do_loc = true;
169  }
170  }
171  else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
175  do_loc = true;
176  }
177 
179  do_rot = true;
180  }
181  }
182  else if (tmode == TFM_RESIZE) {
186  do_loc = true;
187  }
188 
190  do_scale = true;
191  }
192  }
193 
194  if (do_loc) {
197  C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
198  }
199  if (do_rot) {
202  C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
203  }
204  if (do_scale) {
207  C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
208  }
209  }
210  /* insert keyframe in all (transform) channels */
211  else {
214  C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time);
215  }
216 
217  /* free temp info */
218  BLI_freelistN(&dsources);
219  }
220 
222 }
223 
225  bKinematicConstraint *targetless_con)
226 {
228  NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC);
229 
230  /* for draw, but also for detecting while pose solving */
232 
233  bKinematicConstraint *temp_con_data = con->data;
234 
235  if (targetless_con) {
236  /* if exists, use values from last targetless (but disabled) IK-constraint as base */
237  *temp_con_data = *targetless_con;
238  }
239  else {
240  temp_con_data->flag = CONSTRAINT_IK_TIP;
241  }
242 
244 
245  return con;
246 }
247 
248 static void update_deg_with_temporary_ik(Main *bmain, Object *ob)
249 {
250  BIK_clear_data(ob->pose);
251  /* TODO(sergey): Consider doing partial update only. */
253 }
254 
255 /* -------------------------------------------------------------------- */
260 {
261  bConstraint *con = pchan->constraints.first;
262 
263  for (; con; con = con->next) {
264  if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->flag & CONSTRAINT_OFF) == 0 &&
265  (con->enforce != 0.0f)) {
267 
268  if (data->tar == NULL) {
269  return data;
270  }
271  if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0) {
272  return data;
273  }
274  }
275  }
276  return NULL;
277 }
278 
279 /* adds the IK to pchan - returns if added */
281 {
282  bKinematicConstraint *targetless = NULL;
284  bConstraint *con;
285 
286  /* Sanity check */
287  if (pchan == NULL) {
288  return 0;
289  }
290 
291  /* Rule: not if there's already an IK on this channel */
292  for (con = pchan->constraints.first; con; con = con->next) {
293  if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->flag & CONSTRAINT_OFF) == 0) {
294  data = con->data;
295 
296  if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == '\0')) {
297  /* make reference to constraint to base things off later
298  * (if it's the last targetless constraint encountered) */
299  targetless = (bKinematicConstraint *)con->data;
300 
301  /* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
302  if (con->enforce != 0.0f) {
303  data->flag |= CONSTRAINT_IK_AUTO;
304 
305  /* if no chain length has been specified,
306  * just make things obey standard rotation locks too */
307  if (data->rootbone == 0) {
308  for (bPoseChannel *pchan_iter = pchan; pchan_iter; pchan_iter = pchan_iter->parent) {
309  /* here, we set ik-settings for bone from pchan->protectflag */
310  /* XXX: careful with quats/axis-angle rotations where we're locking 4d components. */
311  if (pchan_iter->protectflag & OB_LOCK_ROTX) {
312  pchan_iter->ikflag |= BONE_IK_NO_XDOF_TEMP;
313  }
314  if (pchan_iter->protectflag & OB_LOCK_ROTY) {
315  pchan_iter->ikflag |= BONE_IK_NO_YDOF_TEMP;
316  }
317  if (pchan_iter->protectflag & OB_LOCK_ROTZ) {
318  pchan_iter->ikflag |= BONE_IK_NO_ZDOF_TEMP;
319  }
320  }
321  }
322 
323  /* Return early (as in: don't actually create a temporary constraint here), since adding
324  * will take place later in add_pose_transdata() for targetless constraints. */
325  return 0;
326  }
327  }
328 
329  if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) {
330  return 0;
331  }
332  }
333  }
334 
335  data = add_temporary_ik_constraint(pchan, targetless)->data;
336 
337  copy_v3_v3(data->grabtarget, pchan->pose_tail);
338 
339  /* watch-it! has to be 0 here, since we're still on the
340  * same bone for the first time through the loop T25885. */
341  data->rootbone = 0;
342 
343  /* we only include bones that are part of a continual connected chain */
344  do {
345  /* here, we set ik-settings for bone from pchan->protectflag */
346  /* XXX: careful with quats/axis-angle rotations where we're locking 4d components. */
347  if (pchan->protectflag & OB_LOCK_ROTX) {
348  pchan->ikflag |= BONE_IK_NO_XDOF_TEMP;
349  }
350  if (pchan->protectflag & OB_LOCK_ROTY) {
351  pchan->ikflag |= BONE_IK_NO_YDOF_TEMP;
352  }
353  if (pchan->protectflag & OB_LOCK_ROTZ) {
354  pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP;
355  }
356 
357  /* now we count this pchan as being included */
358  data->rootbone++;
359 
360  /* continue to parent, but only if we're connected to it */
361  if (pchan->bone->flag & BONE_CONNECTED) {
362  pchan = pchan->parent;
363  }
364  else {
365  pchan = NULL;
366  }
367  } while (pchan);
368 
369  /* make a copy of maximum chain-length */
370  data->max_rootbone = data->rootbone;
371 
372  return 1;
373 }
374 
375 /* bone is a candidate to get IK, but we don't do it if it has children connected */
377 {
378  Bone *bonec;
379  short wentdeeper = 0, added = 0;
380 
381  /* go deeper if children & children are connected */
382  for (bonec = bone->childbase.first; bonec; bonec = bonec->next) {
383  if (bonec->flag & BONE_CONNECTED) {
384  wentdeeper = 1;
385  added += pose_grab_with_ik_children(pose, bonec);
386  }
387  }
388  if (wentdeeper == 0) {
390  if (pchan) {
391  added += pose_grab_with_ik_add(pchan);
392  }
393  }
394 
395  return added;
396 }
397 
398 /* main call which adds temporal IK chains */
399 static short pose_grab_with_ik(Main *bmain, Object *ob)
400 {
401  bArmature *arm;
402  bPoseChannel *pchan, *parent;
403  Bone *bonec;
404  short tot_ik = 0;
405 
406  if ((ob == NULL) || (ob->pose == NULL) || (ob->mode & OB_MODE_POSE) == 0) {
407  return 0;
408  }
409 
410  arm = ob->data;
411 
412  /* Rule: allow multiple Bones
413  * (but they must be selected, and only one ik-solver per chain should get added) */
414  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
415  if (BKE_pose_is_layer_visible(arm, pchan)) {
416  if (pchan->bone->flag & (BONE_SELECTED | BONE_TRANSFORM_MIRROR)) {
417  /* Rule: no IK for solitary (unconnected) bones. */
418  for (bonec = pchan->bone->childbase.first; bonec; bonec = bonec->next) {
419  if (bonec->flag & BONE_CONNECTED) {
420  break;
421  }
422  }
423  if ((pchan->bone->flag & BONE_CONNECTED) == 0 && (bonec == NULL)) {
424  continue;
425  }
426 
427  /* rule: if selected Bone is not a root bone, it gets a temporal IK */
428  if (pchan->parent) {
429  /* only adds if there's no IK yet (and no parent bone was selected) */
430  for (parent = pchan->parent; parent; parent = parent->parent) {
432  break;
433  }
434  }
435  if (parent == NULL) {
436  tot_ik += pose_grab_with_ik_add(pchan);
437  }
438  }
439  else {
440  /* rule: go over the children and add IK to the tips */
441  tot_ik += pose_grab_with_ik_children(ob->pose, pchan->bone);
442  }
443  }
444  }
445  }
446 
447  /* iTaSC needs clear for new IK constraints */
448  if (tot_ik) {
449  update_deg_with_temporary_ik(bmain, ob);
450  }
451 
452  return (tot_ik) ? 1 : 0;
453 }
454 
457 /* -------------------------------------------------------------------- */
461 typedef struct PoseInitData_Mirror {
465  struct {
466  float loc[3];
467  float size[3];
468  union {
469  float eul[3];
470  float quat[4];
471  float axis_angle[4];
472  };
473  float curve_in_x;
474  float curve_out_x;
475  float roll1;
476  float roll2;
477  } orig;
482  float offset_mtx[4][4];
484 
486  bPoseChannel *pchan,
487  bPoseChannel *pchan_orig,
488  bool is_mirror_relative)
489 {
490  pid->pchan = pchan;
491  copy_v3_v3(pid->orig.loc, pchan->loc);
492  copy_v3_v3(pid->orig.size, pchan->size);
493  pid->orig.curve_in_x = pchan->curve_in_x;
494  pid->orig.curve_out_x = pchan->curve_out_x;
495  pid->orig.roll1 = pchan->roll1;
496  pid->orig.roll2 = pchan->roll2;
497 
498  if (pchan->rotmode > 0) {
499  copy_v3_v3(pid->orig.eul, pchan->eul);
500  }
501  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
502  copy_v3_v3(pid->orig.axis_angle, pchan->rotAxis);
503  pid->orig.axis_angle[3] = pchan->rotAngle;
504  }
505  else {
506  copy_qt_qt(pid->orig.quat, pchan->quat);
507  }
508 
509  if (is_mirror_relative) {
510  float pchan_mtx[4][4];
511  float pchan_mtx_mirror[4][4];
512 
513  float flip_mtx[4][4];
514  unit_m4(flip_mtx);
515  flip_mtx[0][0] = -1;
516 
517  BKE_pchan_to_mat4(pchan_orig, pchan_mtx_mirror);
518  BKE_pchan_to_mat4(pchan, pchan_mtx);
519 
520  mul_m4_m4m4(pchan_mtx_mirror, pchan_mtx_mirror, flip_mtx);
521  mul_m4_m4m4(pchan_mtx_mirror, flip_mtx, pchan_mtx_mirror);
522 
523  invert_m4(pchan_mtx_mirror);
524  mul_m4_m4m4(pid->offset_mtx, pchan_mtx, pchan_mtx_mirror);
525  }
526  else {
527  unit_m4(pid->offset_mtx);
528  }
529 }
530 
533 /* -------------------------------------------------------------------- */
538 {
539  Bone *bone = pchan->bone;
540  float pmat[3][3], omat[3][3];
541  float cmat[3][3], tmat[3][3];
542  float vec[3];
543 
544  copy_v3_v3(vec, pchan->pose_mat[3]);
545  copy_v3_v3(td->center, vec);
546 
547  td->ob = ob;
548  td->flag = TD_SELECTED;
549  if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
550  td->flag |= TD_NOCENTER;
551  }
552 
553  if (bone->flag & BONE_TRANSFORM_CHILD) {
554  td->flag |= TD_NOCENTER;
555  td->flag |= TD_NO_LOC;
556  }
557 
558  td->extra = pchan;
559  td->protectflag = pchan->protectflag;
560 
561  td->loc = pchan->loc;
562  copy_v3_v3(td->iloc, pchan->loc);
563 
564  td->ext->size = pchan->size;
565  copy_v3_v3(td->ext->isize, pchan->size);
566 
567  if (pchan->rotmode > 0) {
568  td->ext->rot = pchan->eul;
569  td->ext->rotAxis = NULL;
570  td->ext->rotAngle = NULL;
571  td->ext->quat = NULL;
572 
573  copy_v3_v3(td->ext->irot, pchan->eul);
574  }
575  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
576  td->ext->rot = NULL;
577  td->ext->rotAxis = pchan->rotAxis;
578  td->ext->rotAngle = &pchan->rotAngle;
579  td->ext->quat = NULL;
580 
581  td->ext->irotAngle = pchan->rotAngle;
582  copy_v3_v3(td->ext->irotAxis, pchan->rotAxis);
583  }
584  else {
585  td->ext->rot = NULL;
586  td->ext->rotAxis = NULL;
587  td->ext->rotAngle = NULL;
588  td->ext->quat = pchan->quat;
589 
590  copy_qt_qt(td->ext->iquat, pchan->quat);
591  }
592  td->ext->rotOrder = pchan->rotmode;
593 
594  /* proper way to get parent transform + own transform + constraints transform */
595  copy_m3_m4(omat, ob->obmat);
596 
597  /* New code, using "generic" BKE_bone_parent_transform_calc_from_pchan(). */
598  {
600  float rpmat[3][3];
601 
603  if (t->mode == TFM_TRANSLATION) {
604  copy_m3_m4(pmat, bpt.loc_mat);
605  }
606  else {
607  copy_m3_m4(pmat, bpt.rotscale_mat);
608  }
609 
610  /* Grrr! Exceptional case: When translating pose bones that are either Hinge or NoLocal,
611  * and want align snapping, we just need both loc_mat and rotscale_mat.
612  * So simply always store rotscale mat in td->ext, and always use it to apply rotations...
613  * Ugly to need such hacks! :/ */
614  copy_m3_m4(rpmat, bpt.rotscale_mat);
615 
616  if (constraints_list_needinv(t, &pchan->constraints)) {
617  copy_m3_m4(tmat, pchan->constinv);
618  invert_m3_m3(cmat, tmat);
619  mul_m3_series(td->mtx, cmat, omat, pmat);
620  mul_m3_series(td->ext->r_mtx, cmat, omat, rpmat);
621  }
622  else {
623  mul_m3_series(td->mtx, omat, pmat);
624  mul_m3_series(td->ext->r_mtx, omat, rpmat);
625  }
626  invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx);
627  }
628 
630 
631  /* exceptional case: rotate the pose bone which also applies transformation
632  * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */
633  if (!ELEM(t->mode, TFM_TRANSLATION, TFM_RESIZE) &&
634  (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
635  if (pchan->parent) {
636  /* same as td->smtx but without pchan->bone->bone_mat */
637  td->flag |= TD_PBONE_LOCAL_MTX_C;
638  mul_m3_m3m3(td->ext->l_smtx, pchan->bone->bone_mat, td->smtx);
639  }
640  else {
641  td->flag |= TD_PBONE_LOCAL_MTX_P;
642  }
643  }
644 
645  /* For `axismtx` we use bone's own transform. */
646  copy_m3_m4(pmat, pchan->pose_mat);
647  mul_m3_m3m3(td->axismtx, omat, pmat);
648  normalize_m3(td->axismtx);
649 
650  if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) {
651  if (!gimbal_axis_pose(ob, pchan, td->ext->axismtx_gimbal)) {
653  }
654  }
655 
656  if (t->mode == TFM_BONE_ENVELOPE_DIST) {
657  td->loc = NULL;
658  td->val = &bone->dist;
659  td->ival = bone->dist;
660  }
661  else if (t->mode == TFM_BONESIZE) {
662  /* Abusive storage of scale in the loc pointer :) */
663  td->loc = &bone->xwidth;
664  copy_v3_v3(td->iloc, td->loc);
665  td->val = NULL;
666  }
667 
668  /* in this case we can do target-less IK grabbing */
669  if (t->mode == TFM_TRANSLATION) {
671  if (data) {
672  if (data->flag & CONSTRAINT_IK_TIP) {
673  copy_v3_v3(data->grabtarget, pchan->pose_tail);
674  }
675  else {
676  copy_v3_v3(data->grabtarget, pchan->pose_head);
677  }
678  td->loc = data->grabtarget;
679  copy_v3_v3(td->iloc, td->loc);
680 
681  data->flag |= CONSTRAINT_IK_AUTO;
682 
683  /* Add a temporary auto IK constraint here, as we will only temporarily active this
684  * targetless bone during transform. (Targetless IK constraints are treated as if they are
685  * disabled unless they are transformed).
686  * Only do this for targetless IK though, AutoIK already added a constraint in
687  * pose_grab_with_ik_add() beforehand. */
688  if ((data->flag & CONSTRAINT_IK_TEMP) == 0) {
690  Main *bmain = CTX_data_main(t->context);
691  update_deg_with_temporary_ik(bmain, ob);
692  }
693 
694  /* only object matrix correction */
695  copy_m3_m3(td->mtx, omat);
697  }
698  }
699 
700  /* store reference to first constraint */
701  td->con = pchan->constraints.first;
702 }
703 
705 {
706  Main *bmain = CTX_data_main(t->context);
707 
708  t->data_len_all = 0;
709 
710  bool has_translate_rotate_buf[2] = {false, false};
711  bool *has_translate_rotate = (t->mode == TFM_TRANSLATION) ? has_translate_rotate_buf : NULL;
712 
714  Object *ob = tc->poseobj;
715  bPose *pose = ob->pose;
716 
717  bArmature *arm;
718 
719  /* check validity of state */
720  arm = BKE_armature_from_object(tc->poseobj);
721  if ((arm == NULL) || (pose == NULL)) {
722  continue;
723  }
724 
725  const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
726 
727  /* Set flags. */
728  transform_convert_pose_transflags_update(ob, t->mode, t->around);
729 
730  /* Now count, and check if we have autoIK or have to switch from translate to rotate. */
731  LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
732  Bone *bone = pchan->bone;
733  if (!(bone->flag & BONE_TRANSFORM)) {
734  continue;
735  }
736 
737  tc->data_len++;
738 
739  if (has_translate_rotate != NULL) {
740  if (has_translate_rotate[0] && has_translate_rotate[1]) {
741  continue;
742  }
743 
744  if (has_targetless_ik(pchan) == NULL) {
745  if (pchan->parent && (bone->flag & BONE_CONNECTED)) {
746  if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) {
747  has_translate_rotate[0] = true;
748  }
749  }
750  else {
751  if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) {
752  has_translate_rotate[0] = true;
753  }
754  }
755  if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) {
756  has_translate_rotate[1] = true;
757  }
758  }
759  else {
760  has_translate_rotate[0] = true;
761  }
762  }
763  }
764 
765  if (tc->data_len == 0) {
766  continue;
767  }
768 
769  if (arm->flag & ARM_RESTPOS) {
770  if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) {
771  BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled");
772  tc->data_len = 0;
773  continue;
774  }
775  }
776 
777  if (mirror) {
778  int total_mirrored = 0;
779  LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
780  /* Clear the MIRROR flag from previous runs. */
781  pchan->bone->flag &= ~BONE_TRANSFORM_MIRROR;
782 
783  if ((pchan->bone->flag & BONE_TRANSFORM) &&
784  BKE_pose_channel_get_mirrored(ob->pose, pchan->name)) {
785  total_mirrored++;
786  }
787  }
788 
789  PoseInitData_Mirror *pid = MEM_mallocN((total_mirrored + 1) * sizeof(PoseInitData_Mirror),
790  "PoseInitData_Mirror");
791 
792  /* Trick to terminate iteration. */
793  pid[total_mirrored].pchan = NULL;
794 
795  tc->custom.type.data = pid;
796  tc->custom.type.use_free = true;
797  }
798  }
799 
801  if (tc->data_len == 0) {
802  continue;
803  }
804  Object *ob = tc->poseobj;
805  TransData *td;
806  TransDataExtension *tdx;
807  int i;
808 
809  PoseInitData_Mirror *pid = tc->custom.type.data;
810  int pid_index = 0;
811  bPose *pose = ob->pose;
812 
813  if (pose == NULL) {
814  continue;
815  }
816 
817  const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0);
818  const bool is_mirror_relative = ((pose->flag & POSE_MIRROR_RELATIVE) != 0);
819 
820  tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
821 
822  /* init trans data */
823  td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone");
824  tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
825  "TransPoseBoneExt");
826  for (i = 0; i < tc->data_len; i++, td++, tdx++) {
827  td->ext = tdx;
828  td->val = NULL;
829  }
830 
831  if (mirror) {
832  LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
833  if (pchan->bone->flag & BONE_TRANSFORM) {
834  bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name);
835  if (pchan_mirror) {
836  pchan_mirror->bone->flag |= BONE_TRANSFORM_MIRROR;
837  pose_mirror_info_init(&pid[pid_index], pchan_mirror, pchan, is_mirror_relative);
838  pid_index++;
839  }
840  }
841  }
842  }
843 
844  /* do we need to add temporal IK chains? */
845  if ((pose->flag & POSE_AUTO_IK) && t->mode == TFM_TRANSLATION) {
846  if (pose_grab_with_ik(bmain, ob)) {
847  t->flag |= T_AUTOIK;
848  has_translate_rotate[0] = true;
849  }
850  }
851 
852  /* use pose channels to fill trans data */
853  td = tc->data;
854  LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
855  if (pchan->bone->flag & BONE_TRANSFORM) {
856  add_pose_transdata(t, pchan, ob, td);
857  td++;
858  }
859  }
860 
861  if (td != (tc->data + tc->data_len)) {
862  BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
863  }
864  }
865 
866  /* initialize initial auto=ik chainlen's? */
867  if (t->flag & T_AUTOIK) {
869  }
870 
871  /* if there are no translatable bones, do rotation */
872  if ((t->mode == TFM_TRANSLATION) && !has_translate_rotate[0]) {
873  if (has_translate_rotate[1]) {
874  t->mode = TFM_ROTATION;
875  }
876  else {
877  t->mode = TFM_RESIZE;
878  }
879  }
880 }
881 
883 {
884  t->data_len_all = 0;
885 
887  EditBone *ebo, *eboflip;
888  bArmature *arm = tc->obedit->data;
889  ListBase *edbo = arm->edbo;
890  bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
891  int total_mirrored = 0;
892 
893  tc->data_len = 0;
894  for (ebo = edbo->first; ebo; ebo = ebo->next) {
895  const int data_len_prev = tc->data_len;
896 
897  if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
898  if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
899  if (ebo->flag & BONE_SELECTED) {
900  tc->data_len++;
901  }
902  }
903  else if (t->mode == TFM_BONE_ROLL) {
904  if (ebo->flag & BONE_SELECTED) {
905  tc->data_len++;
906  }
907  }
908  else {
909  if (ebo->flag & BONE_TIPSEL) {
910  tc->data_len++;
911  }
912  if (ebo->flag & BONE_ROOTSEL) {
913  tc->data_len++;
914  }
915  }
916  }
917 
918  if (mirror && (data_len_prev < tc->data_len)) {
919  eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
920  if (eboflip) {
921  total_mirrored++;
922  }
923  }
924  }
925  if (!tc->data_len) {
926  continue;
927  }
928 
929  if (mirror) {
930  BoneInitData *bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
931 
932  /* trick to terminate iteration */
933  bid[total_mirrored].bone = NULL;
934 
935  tc->custom.type.data = bid;
936  tc->custom.type.use_free = true;
937  }
938  t->data_len_all += tc->data_len;
939  }
940 
942  t->data_len_all = -1;
943 
945  if (!tc->data_len) {
946  continue;
947  }
948 
949  EditBone *ebo, *eboflip;
950  bArmature *arm = tc->obedit->data;
951  ListBase *edbo = arm->edbo;
952  TransData *td, *td_old;
953  float mtx[3][3], smtx[3][3], bonemat[3][3];
954  bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
955  BoneInitData *bid = tc->custom.type.data;
956 
957  copy_m3_m4(mtx, tc->obedit->obmat);
959 
960  td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
961  int i = 0;
962 
963  for (ebo = edbo->first; ebo; ebo = ebo->next) {
964  td_old = td;
965 
966  /* (length == 0.0) on extrude, used for scaling radius of bone points. */
967  ebo->oldlength = ebo->length;
968 
969  if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
970  if (t->mode == TFM_BONE_ENVELOPE) {
971  if (ebo->flag & BONE_ROOTSEL) {
972  td->val = &ebo->rad_head;
973  td->ival = *td->val;
974 
975  copy_v3_v3(td->center, ebo->head);
976  td->flag = TD_SELECTED;
977 
978  copy_m3_m3(td->smtx, smtx);
979  copy_m3_m3(td->mtx, mtx);
980 
981  td->loc = NULL;
982  td->ext = NULL;
983  td->ob = tc->obedit;
984 
985  td++;
986  }
987  if (ebo->flag & BONE_TIPSEL) {
988  td->val = &ebo->rad_tail;
989  td->ival = *td->val;
990  copy_v3_v3(td->center, ebo->tail);
991  td->flag = TD_SELECTED;
992 
993  copy_m3_m3(td->smtx, smtx);
994  copy_m3_m3(td->mtx, mtx);
995 
996  td->loc = NULL;
997  td->ext = NULL;
998  td->ob = tc->obedit;
999 
1000  td++;
1001  }
1002  }
1003  else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
1004  if (ebo->flag & BONE_SELECTED) {
1005  if (t->mode == TFM_BONE_ENVELOPE_DIST) {
1006  td->loc = NULL;
1007  td->val = &ebo->dist;
1008  td->ival = ebo->dist;
1009  }
1010  else {
1011  /* Abusive storage of scale in the loc pointer :). */
1012  td->loc = &ebo->xwidth;
1013  copy_v3_v3(td->iloc, td->loc);
1014  td->val = NULL;
1015  }
1016  copy_v3_v3(td->center, ebo->head);
1017  td->flag = TD_SELECTED;
1018 
1019  /* use local bone matrix */
1020  ED_armature_ebone_to_mat3(ebo, bonemat);
1021  mul_m3_m3m3(td->mtx, mtx, bonemat);
1022  invert_m3_m3(td->smtx, td->mtx);
1023 
1024  copy_m3_m3(td->axismtx, td->mtx);
1025  normalize_m3(td->axismtx);
1026 
1027  td->ext = NULL;
1028  td->ob = tc->obedit;
1029 
1030  td++;
1031  }
1032  }
1033  else if (t->mode == TFM_BONE_ROLL) {
1034  if (ebo->flag & BONE_SELECTED) {
1035  td->loc = NULL;
1036  td->val = &(ebo->roll);
1037  td->ival = ebo->roll;
1038 
1039  copy_v3_v3(td->center, ebo->head);
1040  td->flag = TD_SELECTED;
1041 
1042  td->ext = NULL;
1043  td->ob = tc->obedit;
1044 
1045  td++;
1046  }
1047  }
1048  else {
1049  if (ebo->flag & BONE_TIPSEL) {
1050  copy_v3_v3(td->iloc, ebo->tail);
1051 
1052  /* Don't allow single selected tips to have a modified center,
1053  * causes problem with snapping (see T45974).
1054  * However, in rotation mode, we want to keep that 'rotate bone around root with
1055  * only its tip selected' behavior (see T46325). */
1056  if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
1057  ((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL))) {
1058  copy_v3_v3(td->center, ebo->head);
1059  }
1060  else {
1061  copy_v3_v3(td->center, td->iloc);
1062  }
1063 
1064  td->loc = ebo->tail;
1065  td->flag = TD_SELECTED;
1066  if (ebo->flag & BONE_EDITMODE_LOCKED) {
1068  }
1069 
1070  copy_m3_m3(td->smtx, smtx);
1071  copy_m3_m3(td->mtx, mtx);
1072 
1074 
1075  if ((ebo->flag & BONE_ROOTSEL) == 0) {
1076  td->extra = ebo;
1077  td->ival = ebo->roll;
1078  }
1079 
1080  td->ext = NULL;
1081  td->val = NULL;
1082  td->ob = tc->obedit;
1083 
1084  td++;
1085  }
1086  if (ebo->flag & BONE_ROOTSEL) {
1087  copy_v3_v3(td->iloc, ebo->head);
1088  copy_v3_v3(td->center, td->iloc);
1089  td->loc = ebo->head;
1090  td->flag = TD_SELECTED;
1091  if (ebo->flag & BONE_EDITMODE_LOCKED) {
1093  }
1094 
1095  copy_m3_m3(td->smtx, smtx);
1096  copy_m3_m3(td->mtx, mtx);
1097 
1099 
1100  td->extra = ebo; /* to fix roll */
1101  td->ival = ebo->roll;
1102 
1103  td->ext = NULL;
1104  td->val = NULL;
1105  td->ob = tc->obedit;
1106 
1107  td++;
1108  }
1109  }
1110  }
1111 
1112  if (mirror && (td_old != td)) {
1113  eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
1114  if (eboflip) {
1115  bid[i].bone = eboflip;
1116  bid[i].dist = eboflip->dist;
1117  bid[i].rad_head = eboflip->rad_head;
1118  bid[i].rad_tail = eboflip->rad_tail;
1119  bid[i].roll = eboflip->roll;
1120  bid[i].xwidth = eboflip->xwidth;
1121  bid[i].zwidth = eboflip->zwidth;
1122  copy_v3_v3(bid[i].head, eboflip->head);
1123  copy_v3_v3(bid[i].tail, eboflip->tail);
1124  i++;
1125  }
1126  }
1127  }
1128 
1129  if (mirror) {
1130  /* trick to terminate iteration */
1131  BLI_assert(i + 1 == (MEM_allocN_len(bid) / sizeof(*bid)));
1132  bid[i].bone = NULL;
1133  }
1134  }
1135 }
1136 
1139 /* -------------------------------------------------------------------- */
1144 {
1145  bArmature *arm;
1146  BoneInitData *bid = tc->custom.type.data;
1147  EditBone *ebo;
1148 
1149  if (tc->obedit) {
1150  arm = tc->obedit->data;
1151  }
1152  else {
1153  BLI_assert(tc->poseobj != NULL);
1154  arm = tc->poseobj->data;
1155  }
1156 
1157  while (bid->bone) {
1158  ebo = bid->bone;
1159 
1160  ebo->dist = bid->dist;
1161  ebo->rad_head = bid->rad_head;
1162  ebo->rad_tail = bid->rad_tail;
1163  ebo->roll = bid->roll;
1164  ebo->xwidth = bid->xwidth;
1165  ebo->zwidth = bid->zwidth;
1166  copy_v3_v3(ebo->head, bid->head);
1167  copy_v3_v3(ebo->tail, bid->tail);
1168 
1169  if (arm->flag & ARM_MIRROR_EDIT) {
1170  EditBone *ebo_child;
1171 
1172  /* Also move connected ebo_child, in case ebo_child's name aren't mirrored properly */
1173  for (ebo_child = arm->edbo->first; ebo_child; ebo_child = ebo_child->next) {
1174  if ((ebo_child->flag & BONE_CONNECTED) && (ebo_child->parent == ebo)) {
1175  copy_v3_v3(ebo_child->head, ebo->tail);
1176  ebo_child->rad_head = ebo->rad_tail;
1177  }
1178  }
1179 
1180  /* Also move connected parent, in case parent's name isn't mirrored properly */
1181  if ((ebo->flag & BONE_CONNECTED) && ebo->parent) {
1182  EditBone *parent = ebo->parent;
1183  copy_v3_v3(parent->tail, ebo->head);
1184  parent->rad_tail = ebo->rad_head;
1185  }
1186  }
1187 
1188  bid++;
1189  }
1190 }
1191 
1193 {
1194  if (t->state != TRANS_CANCEL) {
1196  }
1197 
1199  bArmature *arm = tc->obedit->data;
1200  ListBase *edbo = arm->edbo;
1201  EditBone *ebo, *ebo_parent;
1202  TransData *td = tc->data;
1203  int i;
1204 
1205  /* Ensure all bones are correctly adjusted */
1206  for (ebo = edbo->first; ebo; ebo = ebo->next) {
1207  ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL;
1208 
1209  if (ebo_parent) {
1210  /* If this bone has a parent tip that has been moved */
1211  if (ebo_parent->flag & BONE_TIPSEL) {
1212  copy_v3_v3(ebo->head, ebo_parent->tail);
1213  if (t->mode == TFM_BONE_ENVELOPE) {
1214  ebo->rad_head = ebo_parent->rad_tail;
1215  }
1216  }
1217  /* If this bone has a parent tip that has NOT been moved */
1218  else {
1219  copy_v3_v3(ebo_parent->tail, ebo->head);
1220  if (t->mode == TFM_BONE_ENVELOPE) {
1221  ebo_parent->rad_tail = ebo->rad_head;
1222  }
1223  }
1224  }
1225 
1226  /* on extrude bones, oldlength==0.0f, so we scale radius of points */
1227  ebo->length = len_v3v3(ebo->head, ebo->tail);
1228  if (ebo->oldlength == 0.0f) {
1229  ebo->rad_head = 0.25f * ebo->length;
1230  ebo->rad_tail = 0.10f * ebo->length;
1231  ebo->dist = 0.25f * ebo->length;
1232  if (ebo->parent) {
1233  if (ebo->rad_head > ebo->parent->rad_tail) {
1234  ebo->rad_head = ebo->parent->rad_tail;
1235  }
1236  }
1237  }
1238  else if (t->mode != TFM_BONE_ENVELOPE) {
1239  /* if bones change length, lets do that for the deform distance as well */
1240  ebo->dist *= ebo->length / ebo->oldlength;
1241  ebo->rad_head *= ebo->length / ebo->oldlength;
1242  ebo->rad_tail *= ebo->length / ebo->oldlength;
1243  ebo->oldlength = ebo->length;
1244 
1245  if (ebo_parent) {
1246  ebo_parent->rad_tail = ebo->rad_head;
1247  }
1248  }
1249  }
1250 
1252  /* fix roll */
1253  for (i = 0; i < tc->data_len; i++, td++) {
1254  if (td->extra) {
1255  float vec[3], up_axis[3];
1256  float qrot[4];
1257  float roll;
1258 
1259  ebo = td->extra;
1260 
1261  if (t->state == TRANS_CANCEL) {
1262  /* restore roll */
1263  ebo->roll = td->ival;
1264  }
1265  else {
1266  copy_v3_v3(up_axis, td->axismtx[2]);
1267 
1268  sub_v3_v3v3(vec, ebo->tail, ebo->head);
1269  normalize_v3(vec);
1270  rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
1271  mul_qt_v3(qrot, up_axis);
1272 
1273  /* roll has a tendency to flip in certain orientations - T34283, T33974. */
1274  roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false);
1275  ebo->roll = angle_compat_rad(roll, td->ival);
1276  }
1277  }
1278  }
1279  }
1280 
1281  if (arm->flag & ARM_MIRROR_EDIT) {
1282  if (t->state != TRANS_CANCEL) {
1284  }
1285  else {
1286  restoreBones(tc);
1287  }
1288  }
1289  }
1290 }
1291 
1294 /* -------------------------------------------------------------------- */
1303 {
1304  float flip_mtx[4][4];
1305  unit_m4(flip_mtx);
1306  flip_mtx[0][0] = -1;
1307 
1308  LISTBASE_FOREACH (bPoseChannel *, pchan_orig, &ob->pose->chanbase) {
1309  /* Clear the MIRROR flag from previous runs. */
1310  pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR;
1311  }
1312 
1313  bPose *pose = ob->pose;
1314  PoseInitData_Mirror *pid = NULL;
1315  if ((t->mode != TFM_BONESIZE) && (pose->flag & POSE_MIRROR_RELATIVE)) {
1316  pid = tc->custom.type.data;
1317  }
1318 
1319  TransData *td = tc->data;
1320  for (int i = tc->data_len; i--; td++) {
1321  bPoseChannel *pchan_orig = td->extra;
1322  BLI_assert(pchan_orig->bone->flag & BONE_TRANSFORM);
1323  /* No layer check, correct mirror is more important. */
1324  bPoseChannel *pchan = BKE_pose_channel_get_mirrored(pose, pchan_orig->name);
1325  if (pchan == NULL) {
1326  continue;
1327  }
1328 
1329  /* Also do bbone scaling. */
1330  pchan->bone->xwidth = pchan_orig->bone->xwidth;
1331  pchan->bone->zwidth = pchan_orig->bone->zwidth;
1332 
1333  /* We assume X-axis flipping for now. */
1334  pchan->curve_in_x = pchan_orig->curve_in_x * -1;
1335  pchan->curve_out_x = pchan_orig->curve_out_x * -1;
1336  pchan->roll1 = pchan_orig->roll1 * -1; /* XXX? */
1337  pchan->roll2 = pchan_orig->roll2 * -1; /* XXX? */
1338 
1339  float pchan_mtx_final[4][4];
1340  BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final);
1341  mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx);
1342  mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final);
1343  if (pid) {
1344  mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final);
1345  }
1346  BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false);
1347 
1348  /* Set flag to let auto key-frame know to key-frame the mirrored bone. */
1349  pchan->bone->flag |= BONE_TRANSFORM_MIRROR;
1350 
1351  /* In this case we can do target-less IK grabbing. */
1352  if (t->mode == TFM_TRANSLATION) {
1354  if (data == NULL) {
1355  continue;
1356  }
1357  mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc);
1358  if (pid) {
1359  /* TODO(germano): Relative Mirror support. */
1360  }
1361  data->flag |= CONSTRAINT_IK_AUTO;
1362  /* Add a temporary auto IK constraint here, as we will only temporarily active this
1363  * target-less bone during transform. (Target-less IK constraints are treated as if they are
1364  * disabled unless they are transformed).
1365  * Only do this for targetless IK though, AutoIK already added a constraint in
1366  * pose_grab_with_ik_add() beforehand. */
1367  if ((data->flag & CONSTRAINT_IK_TEMP) == 0) {
1369  Main *bmain = CTX_data_main(t->context);
1370  update_deg_with_temporary_ik(bmain, ob);
1371  }
1372  }
1373 
1374  if (pid) {
1375  pid++;
1376  }
1377  }
1378 }
1379 
1381 {
1382  bPoseChannel *pchan = pid->pchan;
1383  copy_v3_v3(pchan->loc, pid->orig.loc);
1384  copy_v3_v3(pchan->size, pid->orig.size);
1385  pchan->curve_in_x = pid->orig.curve_in_x;
1386  pchan->curve_out_x = pid->orig.curve_out_x;
1387  pchan->roll1 = pid->orig.roll1;
1388  pchan->roll2 = pid->orig.roll2;
1389 
1390  if (pchan->rotmode > 0) {
1391  copy_v3_v3(pchan->eul, pid->orig.eul);
1392  }
1393  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1394  copy_v3_v3(pchan->rotAxis, pid->orig.axis_angle);
1395  pchan->rotAngle = pid->orig.axis_angle[3];
1396  }
1397  else {
1398  copy_qt_qt(pchan->quat, pid->orig.quat);
1399  }
1400 }
1401 
1403 {
1404  bPose *pose = tc->poseobj->pose;
1405 
1406  if (!(pose->flag & POSE_MIRROR_EDIT)) {
1407  return;
1408  }
1409 
1410  for (PoseInitData_Mirror *pid = tc->custom.type.data; pid->pchan; pid++) {
1412  }
1413 }
1414 
1416 {
1417  if (t->mode == TFM_BONESIZE) {
1418  /* Handle the exception where for TFM_BONESIZE in edit mode we pretend to be
1419  * in pose mode (to use bone orientation matrix),
1420  * in that case we have to do mirroring as well. */
1422  Object *ob = tc->poseobj;
1423  bArmature *arm = ob->data;
1424  if (ob->mode == OB_MODE_EDIT) {
1425  if (arm->flag & ARM_MIRROR_EDIT) {
1426  if (t->state != TRANS_CANCEL) {
1428  }
1429  else {
1430  restoreBones(tc);
1431  }
1432  }
1433  }
1434  else if (ob->mode == OB_MODE_POSE) {
1435  /* actually support TFM_BONESIZE in posemode as well */
1437  bPose *pose = ob->pose;
1438  if (arm->flag & ARM_MIRROR_EDIT || pose->flag & POSE_MIRROR_EDIT) {
1440  }
1441  }
1442  }
1443  }
1444  else {
1445  GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
1446 
1448  Object *ob = tc->poseobj;
1449  bPose *pose = ob->pose;
1450 
1451  if (pose->flag & POSE_MIRROR_EDIT) {
1452  if (t->state != TRANS_CANCEL) {
1454  }
1455  else {
1457  }
1458  }
1459 
1460  /* if animtimer is running, and the object already has animation data,
1461  * check if the auto-record feature means that we should record 'samples'
1462  * (i.e. un-editable animation values)
1463  *
1464  * context is needed for keying set poll() functions.
1465  */
1466 
1467  /* TODO: autokeyframe calls need some setting to specify to add samples
1468  * (FPoints) instead of keyframes? */
1469  if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) {
1470 
1471  /* XXX: this currently doesn't work, since flags aren't set yet! */
1472  int targetless_ik = (t->flag & T_AUTOIK);
1473 
1474  animrecord_check_state(t, &ob->id);
1475  autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
1476  }
1477 
1478  if (motionpath_need_update_pose(t->scene, ob)) {
1479  BLI_gset_insert(motionpath_updates, ob);
1480  }
1481 
1483  }
1484 
1485  /* Update motion paths once for all transformed bones in an object. */
1486  GSetIterator gs_iter;
1487  GSET_ITER (gs_iter, motionpath_updates) {
1488  Object *ob = BLI_gsetIterator_getKey(&gs_iter);
1490  }
1491  BLI_gset_free(motionpath_updates, NULL);
1492  }
1493 }
1494 
1497 /* -------------------------------------------------------------------- */
1501 static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
1502 {
1503  Bone *bone = lb->first;
1504 
1505  for (; bone; bone = bone->next) {
1506  if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) {
1508  }
1509  else if ((bone->flag & BONE_TRANSFORM) && (ELEM(mode, TFM_ROTATION, TFM_TRACKBALL)) &&
1510  (around == V3D_AROUND_LOCAL_ORIGINS)) {
1511  bone->flag |= BONE_TRANSFORM_CHILD;
1512  }
1513  else {
1514  bone->flag &= ~BONE_TRANSFORM;
1515  }
1516 
1517  bone_children_clear_transflag(mode, around, &bone->childbase);
1518  }
1519 }
1520 
1521 void transform_convert_pose_transflags_update(Object *ob, const int mode, const short around)
1522 {
1523  bArmature *arm = ob->data;
1524  bPoseChannel *pchan;
1525  Bone *bone;
1526 
1527  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1528  bone = pchan->bone;
1529  if (PBONE_VISIBLE(arm, bone)) {
1530  if (bone->flag & BONE_SELECTED) {
1531  bone->flag |= BONE_TRANSFORM;
1532  }
1533  else {
1534  bone->flag &= ~BONE_TRANSFORM;
1535  }
1536 
1537  bone->flag &= ~BONE_HINGE_CHILD_TRANSFORM;
1538  bone->flag &= ~BONE_TRANSFORM_CHILD;
1539  }
1540  else {
1541  bone->flag &= ~BONE_TRANSFORM;
1542  }
1543  }
1544 
1545  /* make sure no bone can be transformed when a parent is transformed */
1546  /* since pchans are depsgraph sorted, the parents are in beginning of list */
1547  if (!ELEM(mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
1548  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1549  bone = pchan->bone;
1550  if (bone->flag & BONE_TRANSFORM) {
1551  bone_children_clear_transflag(mode, around, &bone->childbase);
1552  }
1553  }
1554  }
1555 }
1556 
1557 static short apply_targetless_ik(Object *ob)
1558 {
1559  bPoseChannel *pchan, *parchan, *chanlist[256];
1561  int segcount, apply = 0;
1562 
1563  /* now we got a difficult situation... we have to find the
1564  * target-less IK pchans, and apply transformation to the all
1565  * pchans that were in the chain */
1566 
1567  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1568  data = has_targetless_ik(pchan);
1569  if (data && (data->flag & CONSTRAINT_IK_AUTO)) {
1570 
1571  /* fill the array with the bones of the chain (armature.c does same, keep it synced) */
1572  segcount = 0;
1573 
1574  /* exclude tip from chain? */
1575  if (!(data->flag & CONSTRAINT_IK_TIP)) {
1576  parchan = pchan->parent;
1577  }
1578  else {
1579  parchan = pchan;
1580  }
1581 
1582  /* Find the chain's root & count the segments needed */
1583  for (; parchan; parchan = parchan->parent) {
1584  chanlist[segcount] = parchan;
1585  segcount++;
1586 
1587  if (segcount == data->rootbone || segcount > 255) {
1588  break; /* 255 is weak */
1589  }
1590  }
1591  for (; segcount; segcount--) {
1592  Bone *bone;
1593  float mat[4][4];
1594 
1595  /* `pose_mat(b) = pose_mat(b-1) * offs_bone * channel * constraint * IK` */
1596  /* We put in channel the entire result of: `mat = (channel * constraint * IK)` */
1597  /* `pose_mat(b) = pose_mat(b-1) * offs_bone * mat` */
1598  /* `mat = pose_mat(b) * inv(pose_mat(b-1) * offs_bone)` */
1599 
1600  parchan = chanlist[segcount - 1];
1601  bone = parchan->bone;
1602  bone->flag |= BONE_TRANSFORM; /* ensures it gets an auto key inserted */
1603 
1604  BKE_armature_mat_pose_to_bone(parchan, parchan->pose_mat, mat);
1605  /* apply and decompose, doesn't work for constraints or non-uniform scale well */
1606  {
1607  float rmat3[3][3], qrmat[3][3], imat3[3][3], smat[3][3];
1608 
1609  copy_m3_m4(rmat3, mat);
1610  /* Make sure that our rotation matrix only contains rotation and not scale. */
1611  normalize_m3(rmat3);
1612 
1613  /* rotation */
1614  /* T22409 is partially caused by this, as slight numeric error introduced during
1615  * the solving process leads to locked-axis values changing. However, we cannot modify
1616  * the values here, or else there are huge discrepancies between IK-solver (interactive)
1617  * and applied poses. */
1618  BKE_pchan_mat3_to_rot(parchan, rmat3, false);
1619 
1620  /* for size, remove rotation */
1621  /* causes problems with some constraints (so apply only if needed) */
1622  if (data->flag & CONSTRAINT_IK_STRETCH) {
1623  BKE_pchan_rot_to_mat3(parchan, qrmat);
1624  invert_m3_m3(imat3, qrmat);
1625  mul_m3_m3m3(smat, rmat3, imat3);
1626  mat3_to_size(parchan->size, smat);
1627  }
1628 
1629  /* causes problems with some constraints (e.g. childof), so disable this */
1630  /* as it is IK shouldn't affect location directly */
1631  /* copy_v3_v3(parchan->loc, mat[3]); */
1632  }
1633  }
1634 
1635  apply = 1;
1636  data->flag &= ~CONSTRAINT_IK_AUTO;
1637  }
1638  }
1639 
1640  return apply;
1641 }
1642 
1643 /* frees temporal IKs */
1644 static void pose_grab_with_ik_clear(Main *bmain, Object *ob)
1645 {
1647  bPoseChannel *pchan;
1648  bConstraint *con, *next;
1649  bool relations_changed = false;
1650 
1651  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1652  /* clear all temporary lock flags */
1654 
1655  pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
1656 
1657  /* remove all temporary IK-constraints added */
1658  for (con = pchan->constraints.first; con; con = next) {
1659  next = con->next;
1660  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
1661  data = con->data;
1662  if (data->flag & CONSTRAINT_IK_TEMP) {
1663  relations_changed = true;
1664 
1665  /* iTaSC needs clear for removed constraints */
1666  BIK_clear_data(ob->pose);
1667 
1668  BLI_remlink(&pchan->constraints, con);
1669  MEM_freeN(con->data);
1670  MEM_freeN(con);
1671  continue;
1672  }
1673  pchan->constflag |= PCHAN_HAS_IK;
1674  if (data->tar == NULL || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0)) {
1675  pchan->constflag |= PCHAN_HAS_TARGET;
1676  }
1677  }
1678  }
1679  }
1680 
1681  if (relations_changed) {
1682  /* TODO(sergey): Consider doing partial update only. */
1683  DEG_relations_tag_update(bmain);
1684  }
1685 }
1686 
1688 {
1689  Object *ob;
1690 
1691  if (t->mode == TFM_BONESIZE) {
1692  /* Handle the exception where for TFM_BONESIZE in edit mode we pretend to be
1693  * in pose mode (to use bone orientation matrix),
1694  * in that case we don't do operations like auto-keyframing. */
1696  ob = tc->poseobj;
1698  }
1699  }
1700  else {
1701  const bool canceled = (t->state == TRANS_CANCEL);
1702  GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
1703 
1705 
1706  bPoseChannel *pchan;
1707  short targetless_ik = 0;
1708 
1709  ob = tc->poseobj;
1710 
1711  if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) {
1712  /* when running transform non-interactively (operator exec),
1713  * we need to update the pose otherwise no updates get called during
1714  * transform and the auto-ik is not applied. see T26164. */
1715  struct Object *pose_ob = tc->poseobj;
1716  BKE_pose_where_is(t->depsgraph, t->scene, pose_ob);
1717  }
1718 
1719  /* Set BONE_TRANSFORM flags for auto-key, gizmo draw might have changed them. */
1720  if (!canceled && (t->mode != TFM_DUMMY)) {
1721  transform_convert_pose_transflags_update(ob, t->mode, t->around);
1722  }
1723 
1724  /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
1725  if (!canceled && t->mode == TFM_TRANSLATION) {
1726  targetless_ik = apply_targetless_ik(ob);
1727  }
1728  else {
1729  /* not forget to clear the auto flag */
1730  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
1732  if (data) {
1733  data->flag &= ~CONSTRAINT_IK_AUTO;
1734  }
1735  }
1736  }
1737 
1738  if (t->mode == TFM_TRANSLATION) {
1739  struct Main *bmain = CTX_data_main(t->context);
1740  pose_grab_with_ik_clear(bmain, ob);
1741  }
1742 
1743  /* automatic inserting of keys and unkeyed tagging -
1744  * only if transform wasn't canceled (or TFM_DUMMY) */
1745  if (!canceled && (t->mode != TFM_DUMMY)) {
1746  autokeyframe_pose(C, t->scene, ob, t->mode, targetless_ik);
1748  }
1749  else {
1751  }
1752 
1753  if (t->mode != TFM_DUMMY && motionpath_need_update_pose(t->scene, ob)) {
1754  BLI_gset_insert(motionpath_updates, ob);
1755  }
1756  }
1757 
1758  /* Update motion paths once for all transformed bones in an object. */
1759  GSetIterator gs_iter;
1760  GSET_ITER (gs_iter, motionpath_updates) {
1761  const ePosePathCalcRange range = canceled ? POSE_PATH_CALC_RANGE_CURRENT_FRAME :
1763  ob = BLI_gsetIterator_getKey(&gs_iter);
1764  ED_pose_recalculate_paths(C, t->scene, ob, range);
1765  }
1766  BLI_gset_free(motionpath_updates, NULL);
1767  }
1768 }
1769 
1773  /* flags */ (T_EDIT | T_POINTS),
1774  /* createTransData */ createTransArmatureVerts,
1775  /* recalcData */ recalcData_edit_armature,
1776  /* special_aftertrans_update */ NULL,
1777 };
1778 
1780  /* flags */ 0,
1781  /* createTransData */ createTransPose,
1782  /* recalcData */ recalcData_pose,
1783  /* special_aftertrans_update */ special_aftertrans_update__pose,
1784 };
void BIK_clear_data(struct bPose *pose)
Definition: ikplugin_api.c:94
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
struct bPoseChannel * BKE_pose_channel_get_mirrored(const struct bPose *pose, const char *name)
bool BKE_pose_is_layer_visible(const struct bArmature *arm, const struct bPoseChannel *pchan)
void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
Definition: anim_sys.c:3866
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:761
void BKE_bone_parent_transform_calc_from_pchan(const struct bPoseChannel *pchan, struct BoneParentTransform *r_bpt)
void BKE_pchan_to_mat4(const struct bPoseChannel *pchan, float r_chanmat[4][4])
struct bArmature * BKE_armature_from_object(struct Object *ob)
Definition: armature.c:342
void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, const float mat[4][4], bool use_compat)
Definition: armature.c:1958
void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, const float mat[3][3], bool use_compat)
Definition: armature.c:1912
void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
Definition: armature.c:1849
#define PBONE_VISIBLE(arm, bone)
Definition: BKE_armature.h:549
void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
Definition: armature.c:2538
void BKE_pchan_rot_to_mat3(const struct bPoseChannel *pchan, float r_mat[3][3])
struct bConstraint * BKE_constraint_add_for_pose(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type)
Definition: constraint.c:5858
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:775
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
#define BLI_assert(a)
Definition: BLI_assert.h:46
struct GSet GSet
Definition: BLI_ghash.h:340
GSet * BLI_gset_ptr_new(const char *info)
void BLI_gset_insert(GSet *gs, void *key)
Definition: BLI_ghash.c:962
#define GSET_ITER(gs_iter_, gset_)
Definition: BLI_ghash.h:471
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:458
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1206
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
#define PSEUDOINVERSE_EPSILON
void unit_m4(float m[4][4])
Definition: rct.c:1090
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1912
bool invert_m3_m3(float R[3][3], const float A[3][3])
Definition: math_matrix.c:1180
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
#define mul_m3_series(...)
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
void mat3_to_size(float size[3], const float M[3][3])
Definition: math_matrix.c:2131
void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
Definition: math_matrix.c:3107
float angle_compat_rad(float angle, float angle_compat)
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
void mul_qt_v3(const float q[4], float r[3])
Definition: math_rotation.c:59
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:33
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
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])
bool bool BLI_str_quoted_substr(const char *__restrict str, const char *__restrict prefix, char *result, size_t result_maxlen)
Definition: string.c:424
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ MOTIONPATH_BAKE_HAS_PATHS
@ ROT_MODE_AXISANGLE
@ BONE_IK_NO_YDOF_TEMP
@ BONE_IK_NO_XDOF_TEMP
@ BONE_IK_NO_ZDOF_TEMP
@ PCHAN_HAS_IK
@ PCHAN_HAS_TARGET
@ POSE_AUTO_IK
@ POSE_MIRROR_EDIT
@ POSE_MIRROR_RELATIVE
eInsertKeyFlags
@ INSERTKEY_MATRIX
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_TRANSFORM
@ BONE_EDITMODE_LOCKED
@ BONE_TRANSFORM_MIRROR
@ BONE_NO_LOCAL_LOCATION
@ BONE_TRANSFORM_CHILD
@ BONE_TIPSEL
@ BONE_CONNECTED
@ BONE_HINGE
@ BONE_HINGE_CHILD_TRANSFORM
@ ARM_MIRROR_EDIT
@ ARM_RESTPOS
@ CONSTRAINT_OFF
@ CONSTRAINT_DISABLE
@ CONSTRAINT_IK_TEMP
@ CONSTRAINT_IK_POS
@ CONSTRAINT_IK_AUTO
@ CONSTRAINT_IK_STRETCH
@ CONSTRAINT_IK_TIP
@ CONSTRAINT_TYPE_KINEMATIC
@ OB_MODE_EDIT
@ OB_MODE_POSE
@ OB_ARMATURE
@ OB_LOCK_ROTZ
@ OB_LOCK_ROT
@ OB_LOCK_ROTX
@ OB_LOCK_ROTY
@ OB_LOCK_LOC
@ OB_LOCK_SCALE
@ SCE_XFORM_AXIS_ALIGN
@ V3D_AROUND_ACTIVE
@ V3D_AROUND_CURSOR
@ V3D_AROUND_LOCAL_ORIGINS
@ V3D_ORIENT_GIMBAL
ePosePathCalcRange
Definition: ED_armature.h:294
@ POSE_PATH_CALC_RANGE_CURRENT_FRAME
Definition: ED_armature.h:295
@ POSE_PATH_CALC_RANGE_CHANGED
Definition: ED_armature.h:296
#define EBONE_VISIBLE(arm, ebone)
Definition: ED_armature.h:47
#define ANIM_KS_LOC_ROT_SCALE_ID
#define IS_AUTOKEY_FLAG(scene, flag)
@ MODIFYKEY_MODE_INSERT
#define ANIM_KS_LOCATION_ID
#define ANIM_KS_SCALING_ID
#define IS_AUTOKEY_ON(scene)
#define ANIM_KS_ROTATION_ID
@ TFM_RESIZE
Definition: ED_transform.h:32
@ TFM_BONESIZE
Definition: ED_transform.h:44
@ TFM_ROTATION
Definition: ED_transform.h:31
@ TFM_BONE_ENVELOPE
Definition: ED_transform.h:45
@ TFM_BONE_ROLL
Definition: ED_transform.h:49
@ TFM_TRANSLATION
Definition: ED_transform.h:30
@ TFM_BONE_ENVELOPE_DIST
Definition: ED_transform.h:62
@ TFM_DUMMY
Definition: ED_transform.h:29
@ TFM_TRACKBALL
Definition: ED_transform.h:39
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
float ED_armature_ebone_roll_to_vector(const EditBone *bone, const float align_axis[3], const bool axis_only)
void ED_armature_edit_transform_mirror_update(Object *obedit)
void ED_armature_ebone_to_mat3(EditBone *ebone, float r_mat[3][3])
EditBone * ED_armature_ebone_get_mirrored(const ListBase *edbo, EditBone *ebo)
Scene scene
const Depsgraph * depsgraph
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
Definition: keyframing.c:2850
eInsertKeyFlags ANIM_get_keyframing_flags(Scene *scene, const bool use_autokey_mode)
Definition: keyframing.c:82
int insert_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, ListBase *nla_cache, eInsertKeyFlags flag)
Definition: keyframing.c:1476
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
Definition: keyingsets.c:1038
KeyingSet * ANIM_scene_get_active_keyingset(const Scene *scene)
Definition: keyingsets.c:647
KeyingSet * ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[])
Definition: keyingsets.c:531
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
Definition: keyingsets.c:924
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:26
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static ulong * next
void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathCalcRange range)
Definition: pose_edit.c:154
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
bool gimbal_axis_pose(struct Object *ob, const struct bPoseChannel *pchan, float gmat[3][3])
bAction * action
struct EditBone * bone
float loc_mat[4][4]
Definition: BKE_armature.h:396
float rotscale_mat[4][4]
Definition: BKE_armature.h:395
float zwidth
char name[64]
float xwidth
float bone_mat[3][3]
float dist
struct Bone * next
ListBase childbase
float oldlength
Definition: BKE_armature.h:79
struct EditBone * next
Definition: BKE_armature.h:33
float tail[3]
Definition: BKE_armature.h:54
float roll
Definition: BKE_armature.h:50
struct Bone * bone
Definition: BKE_armature.h:106
float zwidth
Definition: BKE_armature.h:67
float length
Definition: BKE_armature.h:67
float xwidth
Definition: BKE_armature.h:67
float dist
Definition: BKE_armature.h:65
struct EditBone * parent
Definition: BKE_armature.h:41
float rad_tail
Definition: BKE_armature.h:68
float rad_head
Definition: BKE_armature.h:68
float head[3]
Definition: BKE_armature.h:53
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
struct bPose * pose
float obmat[4][4]
struct AnimData * adt
void * data
struct bPoseChannel * pchan
struct PoseInitData_Mirror::@602 orig
struct ToolSettings * toolsettings
struct RenderData r
char transform_pivot_point
float r_smtx[3][3]
float l_smtx[3][3]
float axismtx_gimbal[3][3]
float smtx[3][3]
short protectflag
struct bConstraint * con
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
float * val
struct Object * ob
ListBase curves
ListBase * edbo
struct bConstraint * next
ListBase constraints
struct Bone * bone
struct bPoseChannel * parent
float pose_head[3]
float pose_tail[3]
struct bPoseChannel * next
float constinv[4][4]
float pose_mat[4][4]
ListBase chanbase
short flag
bAnimVizSettings avs
void transform_autoik_update(TransInfo *t, short mode)
void transform_around_single_fallback(TransInfo *t)
void animrecord_check_state(TransInfo *t, struct ID *id)
bool constraints_list_needinv(TransInfo *t, ListBase *list)
conversion and adaptation of different datablocks to a common struct.
static void createTransArmatureVerts(bContext *UNUSED(C), TransInfo *t)
static void createTransPose(bContext *UNUSED(C), TransInfo *t)
static bool motionpath_need_update_pose(Scene *scene, Object *ob)
static void restoreMirrorPoseBones(TransDataContainer *tc)
static void recalcData_pose(TransInfo *t)
static void pose_mirror_info_init(PoseInitData_Mirror *pid, bPoseChannel *pchan, bPoseChannel *pchan_orig, bool is_mirror_relative)
static void pose_mirror_info_restore(const PoseInitData_Mirror *pid)
static void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, Object *ob)
struct BoneInitData BoneInitData
static void update_deg_with_temporary_ik(Main *bmain, Object *ob)
static bKinematicConstraint * has_targetless_ik(bPoseChannel *pchan)
static void bone_children_clear_transflag(int mode, short around, ListBase *lb)
static bConstraint * add_temporary_ik_constraint(bPoseChannel *pchan, bKinematicConstraint *targetless_con)
static void recalcData_edit_armature(TransInfo *t)
static short pose_grab_with_ik(Main *bmain, Object *ob)
static short pose_grab_with_ik_add(bPoseChannel *pchan)
static short apply_targetless_ik(Object *ob)
static void restoreBones(TransDataContainer *tc)
static void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
struct PoseInitData_Mirror PoseInitData_Mirror
static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
static void special_aftertrans_update__pose(bContext *C, TransInfo *t)
static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
TransConvertTypeInfo TransConvertType_EditArmature
static void pose_grab_with_ik_clear(Main *bmain, Object *ob)
TransConvertTypeInfo TransConvertType_Pose
void transform_convert_pose_transflags_update(Object *ob, const int mode, const short around)
@ TD_PBONE_LOCAL_MTX_P
@ TD_PBONE_LOCAL_MTX_C
@ TD_SELECTED
@ TD_NO_LOC
@ TD_NOCENTER
void applySnappingIndividual(TransInfo *t)