Blender  V2.93
pose_transform.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  */
19 
24 #include "DNA_anim_types.h"
25 #include "DNA_armature_types.h"
26 #include "DNA_constraint_types.h"
27 #include "DNA_object_types.h"
28 #include "DNA_scene_types.h"
29 
30 #include "MEM_guardedalloc.h"
31 
32 #include "BLI_blenlib.h"
33 #include "BLI_math.h"
34 #include "BLI_string_utils.h"
35 
36 #include "BKE_action.h"
37 #include "BKE_animsys.h"
38 #include "BKE_appdir.h"
39 #include "BKE_armature.h"
40 #include "BKE_blender_copybuffer.h"
41 #include "BKE_context.h"
42 #include "BKE_deform.h"
43 #include "BKE_idprop.h"
44 #include "BKE_layer.h"
45 #include "BKE_main.h"
46 #include "BKE_object.h"
47 #include "BKE_report.h"
48 
49 #include "DEG_depsgraph.h"
50 #include "DEG_depsgraph_query.h"
51 
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54 
55 #include "WM_api.h"
56 #include "WM_types.h"
57 
58 #include "ED_armature.h"
59 #include "ED_keyframing.h"
60 #include "ED_screen.h"
61 #include "ED_util.h"
62 
63 #include "UI_interface.h"
64 #include "UI_resources.h"
65 
66 #include "armature_intern.h"
67 
68 /* -------------------------------------------------------------------- */
72 /* helper for apply_armature_pose2bones - fixes parenting of objects
73  * that are bone-parented to armature */
75 {
76  /* Depsgraph has been ensured to be evaluated at the beginning of the operator.
77  *
78  * Must not evaluate depsgraph here yet, since this will ruin object matrix which we want to
79  * preserve after other changes has been done in the operator.
80  *
81  * TODO(sergey): This seems very similar to `ignore_parent_tx()`, which was now ensured to work
82  * quite reliably. Can we de-duplicate the code? Or at least verify we don't need an extra logic
83  * in this function. */
85  Main *bmain = CTX_data_main(C);
86  Object workob, *ob;
87 
88  /* go through all objects in database */
89  for (ob = bmain->objects.first; ob; ob = ob->id.next) {
90  /* if parent is bone in this armature, apply corrections */
91  if ((ob->parent == armob) && (ob->partype == PARBONE)) {
92  /* apply current transform from parent (not yet destroyed),
93  * then calculate new parent inverse matrix
94  */
95  BKE_object_apply_mat4(ob, ob->obmat, false, false);
96 
98  invert_m4_m4(ob->parentinv, workob.obmat);
99  }
100  }
101 }
102 
103 /* Sets the bone head, tail and roll to match the supplied parameters. */
105  const float pose_mat[4][4],
106  const float new_tail[3],
107  float r_new_arm_mat[4][4])
108 {
109  /* Simply copy the head/tail values from pchan over to curbone. */
110  copy_v3_v3(curbone->head, pose_mat[3]);
111  copy_v3_v3(curbone->tail, new_tail);
112 
113  /* Fix roll:
114  * 1. find auto-calculated roll value for this bone now
115  * 2. remove this from the 'visual' y-rotation
116  */
117  {
118  float premat[3][3], pmat[3][3];
119  float delta[3];
120 
121  /* Obtain new auto y-rotation. */
122  sub_v3_v3v3(delta, curbone->tail, curbone->head);
123 
124  copy_m3_m4(pmat, pose_mat);
125  mat3_vec_to_roll(pmat, delta, &curbone->roll);
126 
127  /* Compute new rest pose matrix if requested. */
128  if (r_new_arm_mat) {
129  vec_roll_to_mat3(delta, curbone->roll, premat);
130  copy_m4_m3(r_new_arm_mat, premat);
131  copy_v3_v3(r_new_arm_mat[3], pose_mat[3]);
132  }
133  }
134 }
135 
136 /* Copy properties over from pchan to curbone and reset channels. */
138  bPoseChannel *pchan,
139  const bPoseChannel *pchan_eval)
140 {
141  /* Combine pose and rest values for bendy bone settings,
142  * then clear the pchan values (so we don't get a double-up).
143  */
144  if (pchan->bone->segments > 1) {
145  /* Combine rest/pose values. */
146  curbone->curve_in_x += pchan_eval->curve_in_x;
147  curbone->curve_in_y += pchan_eval->curve_in_y;
148  curbone->curve_out_x += pchan_eval->curve_out_x;
149  curbone->curve_out_y += pchan_eval->curve_out_y;
150  curbone->roll1 += pchan_eval->roll1;
151  curbone->roll2 += pchan_eval->roll2;
152  curbone->ease1 += pchan_eval->ease1;
153  curbone->ease2 += pchan_eval->ease2;
154 
155  curbone->scale_in_x *= pchan_eval->scale_in_x;
156  curbone->scale_in_y *= pchan_eval->scale_in_y;
157  curbone->scale_out_x *= pchan_eval->scale_out_x;
158  curbone->scale_out_y *= pchan_eval->scale_out_y;
159 
160  /* Reset pose values. */
161  pchan->curve_in_x = pchan->curve_out_x = 0.0f;
162  pchan->curve_in_y = pchan->curve_out_y = 0.0f;
163  pchan->roll1 = pchan->roll2 = 0.0f;
164  pchan->ease1 = pchan->ease2 = 0.0f;
165  pchan->scale_in_x = pchan->scale_in_y = 1.0f;
166  pchan->scale_out_x = pchan->scale_out_y = 1.0f;
167  }
168 
169  /* Clear transform values for pchan. */
170  zero_v3(pchan->loc);
171  zero_v3(pchan->eul);
172  unit_qt(pchan->quat);
173  unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
174  pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
175 }
176 
177 /* Adjust the current edit position of the bone using the pose space matrix. */
179  bPoseChannel *pchan,
180  const float delta_mat[4][4],
181  float r_new_arm_mat[4][4])
182 {
183  EditBone *curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
184  float delta[3], new_tail[3], premat[3][3], new_pose[4][4];
185 
186  /* Current orientation matrix. */
187  sub_v3_v3v3(delta, curbone->tail, curbone->head);
188  vec_roll_to_mat3(delta, curbone->roll, premat);
189 
190  /* New location and orientation. */
191  mul_m4_m4m3(new_pose, delta_mat, premat);
192  mul_v3_m4v3(new_pose[3], delta_mat, curbone->head);
193  mul_v3_m4v3(new_tail, delta_mat, curbone->tail);
194 
195  applyarmature_set_edit_position(curbone, new_pose, new_tail, r_new_arm_mat);
196 }
197 
198 /* Data about parent position for Apply To Selected mode. */
201 
202  /* New rest position of the bone with scale included. */
203  float new_rest_mat[4][4];
204  /* New arm_mat of the bone == new_rest_mat without scale. */
205  float new_arm_mat[4][4];
207 
208 /* Recursive walk for Apply To Selected mode; pstate NULL unless child of an applied bone. */
210  bPose *pose,
211  bPose *pose_eval,
212  Bone *bone,
213  ListBase *selected,
215 {
216  bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name);
217  const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(pose_eval, bone->name);
218 
219  if (!pchan || !pchan_eval) {
220  return;
221  }
222 
223  ApplyArmature_ParentState new_pstate = {.bone = bone};
224 
225  if (BLI_findptr(selected, pchan, offsetof(CollectionPointerLink, ptr.data))) {
226  /* SELECTED BONE: Snap to final pose transform minus un-applied parent effects.
227  *
228  * I.e. bone position with accumulated parent effects but no local
229  * transformation will match the original final pose_mat.
230  *
231  * Pose channels are reset as expected.
232  */
233  EditBone *curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
234  BoneParentTransform invparent;
235  float new_tail[3];
236 
237  if (pchan->parent) {
238  BoneParentTransform old_bpt, new_bpt;
239  float offs_bone[4][4];
240 
241  /* Parent effects on the bone transform that have to be removed. */
242  BKE_bone_offset_matrix_get(bone, offs_bone);
244  bone->inherit_scale_mode,
245  offs_bone,
246  bone->parent->arm_mat,
247  pchan_eval->parent->pose_mat,
248  &old_bpt);
249 
250  /* Applied parent effects that have to be kept, if any. */
251  float(*new_parent_pose)[4] = pstate ? pstate->new_rest_mat : bone->parent->arm_mat;
253  bone->inherit_scale_mode,
254  offs_bone,
255  bone->parent->arm_mat,
256  new_parent_pose,
257  &new_bpt);
258 
260  BKE_bone_parent_transform_combine(&new_bpt, &old_bpt, &invparent);
261  }
262  else {
264  }
265 
266  /* Apply change without inherited unapplied parent transformations. */
267  BKE_bone_parent_transform_apply(&invparent, pchan_eval->pose_mat, new_pstate.new_rest_mat);
268 
269  copy_v3_fl3(new_tail, 0.0, bone->length, 0.0);
270  mul_m4_v3(new_pstate.new_rest_mat, new_tail);
271 
273  curbone, new_pstate.new_rest_mat, new_tail, new_pstate.new_arm_mat);
274  applyarmature_transfer_properties(curbone, pchan, pchan_eval);
275 
276  pstate = &new_pstate;
277  }
278  else if (pstate) {
279  /* UNSELECTED CHILD OF SELECTED: Include applied parent effects.
280  *
281  * The inherited transform of applied (selected) bones is baked
282  * into the rest pose so that the final bone position doesn't
283  * change.
284  *
285  * Pose channels are not changed, with the exception of the inherited
286  * applied parent scale being baked into the location pose channel.
287  */
289  float offs_bone[4][4], delta[4][4], old_chan_loc[3];
290 
291  /* Include applied parent effects. */
292  BKE_bone_offset_matrix_get(bone, offs_bone);
294  bone->inherit_scale_mode,
295  offs_bone,
296  pstate->bone->arm_mat,
297  pstate->new_rest_mat,
298  &bpt);
299 
300  unit_m4(new_pstate.new_rest_mat);
301  BKE_bone_parent_transform_apply(&bpt, new_pstate.new_rest_mat, new_pstate.new_rest_mat);
302 
303  /* Bone location channel in pose space relative to bone head. */
304  mul_v3_mat3_m4v3(old_chan_loc, bpt.loc_mat, pchan_eval->loc);
305 
306  /* Apply the change to the rest bone position. */
307  invert_m4_m4(delta, bone->arm_mat);
308  mul_m4_m4m4(delta, new_pstate.new_rest_mat, delta);
309 
310  applyarmature_adjust_edit_position(arm, pchan, delta, new_pstate.new_arm_mat);
311 
312  /* Location pose channel has to be updated, because it is affected
313  * by parent scaling, and the rest pose has no scale by definition. */
314  if (!(bone->flag & BONE_CONNECTED) && !is_zero_v3(old_chan_loc)) {
315  float inv_parent_arm[4][4];
316 
317  /* Compute the channel coordinate space matrices for the new rest state. */
318  invert_m4_m4(inv_parent_arm, pstate->new_arm_mat);
319  mul_m4_m4m4(offs_bone, inv_parent_arm, new_pstate.new_arm_mat);
321  bone->inherit_scale_mode,
322  offs_bone,
323  pstate->new_arm_mat,
324  pstate->new_arm_mat,
325  &bpt);
326 
327  /* Re-apply the location to keep the final effect. */
328  invert_m4(bpt.loc_mat);
329  mul_v3_mat3_m4v3(pchan->loc, bpt.loc_mat, old_chan_loc);
330  }
331 
332  pstate = &new_pstate;
333  }
334 
335  LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
336  applyarmature_process_selected_recursive(arm, pose, pose_eval, child, selected, pstate);
337  }
338 }
339 
340 /* Reset bone constraint so that it is correct after the pose has been applied. */
341 static void applyarmature_reset_bone_constraint(const bConstraint *constraint)
342 {
343  /* TODO(Sybren): This function needs too much knowledge of the internals of specific constraints.
344  * When it is extended with one or two more constraints, move the functionality into a
345  * bConstraintTypeInfo callback function. */
346  switch (constraint->type) {
348  bStretchToConstraint *stretch_to = (bStretchToConstraint *)constraint->data;
349  stretch_to->orglength = 0.0f; /* Force recalculation on next evaluation. */
350  break;
351  }
352  default:
353  /* Most constraints don't need resetting. */
354  break;
355  }
356 }
357 
358 /* Reset bone constraints of the given pose channel so that they are correct after the pose has
359  * been applied. */
361 {
362  LISTBASE_FOREACH (bConstraint *, constraint, &pchan->constraints) {
364  }
365 }
366 
367 /* Reset all (or only selected) bone constraints so that they are correct after the pose has been
368  * applied. */
369 static void applyarmature_reset_constraints(bPose *pose, const bool use_selected)
370 {
371  for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
372  BLI_assert(pchan->bone != NULL);
373  if (use_selected && (pchan->bone->flag & BONE_SELECTED) == 0) {
374  continue;
375  }
377  }
378 }
379 
380 /* set the current pose as the restpose */
382 {
383  Main *bmain = CTX_data_main(C);
386  /* must be active object, not edit-object */
388  const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
390  bPose *pose;
391  bPoseChannel *pchan;
392  ListBase selected_bones;
393 
394  const bool use_selected = RNA_boolean_get(op->ptr, "selected");
395 
396  /* don't check if editmode (should be done by caller) */
397  if (ob->type != OB_ARMATURE) {
398  return OPERATOR_CANCELLED;
399  }
401  BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature");
402  return OPERATOR_CANCELLED;
403  }
404 
405  /* helpful warnings... */
406  /* TODO: add warnings to be careful about actions, applying deforms first, etc. */
407  if (ob->adt && ob->adt->action) {
408  BKE_report(op->reports,
409  RPT_WARNING,
410  "Actions on this armature will be destroyed by this new rest pose as the "
411  "transforms stored are relative to the old rest pose");
412  }
413 
414  /* Find selected bones before switching to edit mode. */
415  if (use_selected) {
416  CTX_data_selected_pose_bones(C, &selected_bones);
417 
418  if (!selected_bones.first) {
419  return OPERATOR_CANCELLED;
420  }
421  }
422 
423  /* Get editbones of active armature to alter */
424  ED_armature_to_edit(arm);
425 
426  /* get pose of active object and move it out of posemode */
427  pose = ob->pose;
428 
429  if (use_selected) {
430  /* The selected only mode requires a recursive walk to handle parent-child relations. */
431  LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
433  arm, pose, ob_eval->pose, bone, &selected_bones, NULL);
434  }
435 
436  BLI_freelistN(&selected_bones);
437  }
438  else {
439  for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
440  const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
441  EditBone *curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
442 
443  applyarmature_set_edit_position(curbone, pchan_eval->pose_mat, pchan_eval->pose_tail, NULL);
444  applyarmature_transfer_properties(curbone, pchan, pchan_eval);
445  }
446  }
447 
448  /* convert editbones back to bones, and then free the edit-data */
449  ED_armature_from_edit(bmain, arm);
451 
452  /* flush positions of posebones */
454 
455  /* fix parenting of objects which are bone-parented */
457 
458  /* For the affected bones, reset specific constraints that are now known to be invalid. */
459  applyarmature_reset_constraints(pose, use_selected);
460 
461  /* note, notifier might evolve */
464 
465  return OPERATOR_FINISHED;
466 }
467 
469 {
470  uiLayout *layout = op->layout;
472  PointerRNA ptr;
473 
474  RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
475 
476  uiItemR(layout, &ptr, "selected", 0, NULL, ICON_NONE);
477 }
478 
480 {
481  /* identifiers */
482  ot->name = "Apply Pose as Rest Pose";
483  ot->idname = "POSE_OT_armature_apply";
484  ot->description = "Apply the current pose as the new rest pose";
485 
486  /* callbacks */
490 
491  /* flags */
493 
495  "selected",
496  false,
497  "Selected Only",
498  "Only apply the selected bones (with propagation to children)");
499 }
500 
503 /* -------------------------------------------------------------------- */
507 /* set the current pose as the restpose */
509 {
510  ViewLayer *view_layer = CTX_data_view_layer(C);
511  View3D *v3d = CTX_wm_view3d(C);
512 
513  /* Needed to ensure #bPoseChannel.pose_mat are up to date. */
515 
516  FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
517  const bArmature *arm = ob->data;
518 
519  int chanbase_len = BLI_listbase_count(&ob->pose->chanbase);
520  /* Storage for the calculated matrices to prevent reading from modified values.
521  * NOTE: this could be avoided if children were always calculated before parents
522  * however ensuring this is involved and doesn't give any significant advantage. */
523  struct {
524  float matrix[4][4];
525  bool is_set;
526  } *pchan_xform_array = MEM_mallocN(sizeof(*pchan_xform_array) * chanbase_len, __func__);
527  bool changed = false;
528 
529  int i;
530  LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, i) {
531  if (!((pchan->bone->flag & BONE_SELECTED) && PBONE_VISIBLE(arm, pchan->bone))) {
532  pchan_xform_array[i].is_set = false;
533  continue;
534  }
535 
536  /* `chan_mat` already contains the delta transform from rest pose to pose-mode pose
537  * as that is baked into there so that B-Bones will work. Once we've set this as the
538  * new raw-transform components, don't recalculate the poses yet, otherwise IK result will
539  * change, thus changing the result we may be trying to record. */
540 
541  /* NOTE: For some reason `pchan->chan_mat` can't be used here as it gives odd
542  * rotation/offset, see T38251.
543  * Using `pchan->pose_mat` and bringing it back in bone space seems to work as expected!
544  * This matches how visual key-framing works. */
545  BKE_armature_mat_pose_to_bone(pchan, pchan->pose_mat, pchan_xform_array[i].matrix);
546  pchan_xform_array[i].is_set = true;
547  changed = true;
548  }
549 
550  if (changed) {
551  /* Perform separately to prevent feedback loop. */
552  LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, i) {
553  if (!pchan_xform_array[i].is_set) {
554  continue;
555  }
556  BKE_pchan_apply_mat4(pchan, pchan_xform_array[i].matrix, true);
557  }
558 
560 
561  /* note, notifier might evolve */
563  }
564 
565  MEM_freeN(pchan_xform_array);
566  }
568 
569  return OPERATOR_FINISHED;
570 }
571 
573 {
574  /* identifiers */
575  ot->name = "Apply Visual Transform to Pose";
576  ot->idname = "POSE_OT_visual_transform_apply";
577  ot->description = "Apply final constrained position of pose bones to their transform";
578 
579  /* callbacks */
582 
583  /* flags */
585 }
586 
589 /* -------------------------------------------------------------------- */
593 /* This function is used to indicate that a bone is selected
594  * and needs to be included in copy buffer (used to be for inserting keys)
595  */
596 static void set_pose_keys(Object *ob)
597 {
598  bArmature *arm = ob->data;
599  bPoseChannel *chan;
600 
601  if (ob->pose) {
602  for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
603  Bone *bone = chan->bone;
604  if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) {
605  chan->flag |= POSE_KEY;
606  }
607  else {
608  chan->flag &= ~POSE_KEY;
609  }
610  }
611  }
612 }
613 
624  bPoseChannel *chan,
625  const bool selOnly,
626  const bool flip)
627 {
628  char name[MAXBONENAME];
629 
630  /* get the name - if flipping, we must flip this first */
631  if (flip) {
632  BLI_string_flip_side_name(name, chan->name, false, sizeof(name));
633  }
634  else {
635  BLI_strncpy(name, chan->name, sizeof(name));
636  }
637 
638  /* only copy when:
639  * 1) channel exists - poses are not meant to add random channels to anymore
640  * 2) if selection-masking is on, channel is selected -
641  * only selected bones get pasted on, allowing making both sides symmetrical.
642  */
643  bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, name);
644  if (pchan == NULL) {
645  return NULL;
646  }
647  if (selOnly && (pchan->bone->flag & BONE_SELECTED) == 0) {
648  return NULL;
649  }
650 
651  /* only loc rot size
652  * - only copies transform info for the pose
653  */
654  copy_v3_v3(pchan->loc, chan->loc);
655  copy_v3_v3(pchan->size, chan->size);
656  pchan->flag = chan->flag;
657 
658  /* check if rotation modes are compatible (i.e. do they need any conversions) */
659  if (pchan->rotmode == chan->rotmode) {
660  /* copy the type of rotation in use */
661  if (pchan->rotmode > 0) {
662  copy_v3_v3(pchan->eul, chan->eul);
663  }
664  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
665  copy_v3_v3(pchan->rotAxis, chan->rotAxis);
666  pchan->rotAngle = chan->rotAngle;
667  }
668  else {
669  copy_qt_qt(pchan->quat, chan->quat);
670  }
671  }
672  else if (pchan->rotmode > 0) {
673  /* quat/axis-angle to euler */
674  if (chan->rotmode == ROT_MODE_AXISANGLE) {
675  axis_angle_to_eulO(pchan->eul, pchan->rotmode, chan->rotAxis, chan->rotAngle);
676  }
677  else {
678  quat_to_eulO(pchan->eul, pchan->rotmode, chan->quat);
679  }
680  }
681  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
682  /* quat/euler to axis angle */
683  if (chan->rotmode > 0) {
684  eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->eul, chan->rotmode);
685  }
686  else {
687  quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->quat);
688  }
689  }
690  else {
691  /* euler/axis-angle to quat */
692  if (chan->rotmode > 0) {
693  eulO_to_quat(pchan->quat, chan->eul, chan->rotmode);
694  }
695  else {
696  axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle);
697  }
698  }
699 
700  /* B-Bone posing options should also be included... */
701  pchan->curve_in_x = chan->curve_in_x;
702  pchan->curve_in_y = chan->curve_in_y;
703  pchan->curve_out_x = chan->curve_out_x;
704  pchan->curve_out_y = chan->curve_out_y;
705 
706  pchan->roll1 = chan->roll1;
707  pchan->roll2 = chan->roll2;
708  pchan->ease1 = chan->ease1;
709  pchan->ease2 = chan->ease2;
710  pchan->scale_in_x = chan->scale_in_x;
711  pchan->scale_in_y = chan->scale_in_y;
712  pchan->scale_out_x = chan->scale_out_x;
713  pchan->scale_out_y = chan->scale_out_y;
714 
715  /* paste flipped pose? */
716  if (flip) {
717  pchan->loc[0] *= -1;
718 
719  pchan->curve_in_x *= -1;
720  pchan->curve_out_x *= -1;
721  pchan->roll1 *= -1; /* XXX? */
722  pchan->roll2 *= -1; /* XXX? */
723 
724  /* has to be done as eulers... */
725  if (pchan->rotmode > 0) {
726  pchan->eul[1] *= -1;
727  pchan->eul[2] *= -1;
728  }
729  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
730  float eul[3];
731 
733  eul[1] *= -1;
734  eul[2] *= -1;
736  }
737  else {
738  float eul[3];
739 
740  normalize_qt(pchan->quat);
741  quat_to_eul(eul, pchan->quat);
742  eul[1] *= -1;
743  eul[2] *= -1;
744  eul_to_quat(pchan->quat, eul);
745  }
746  }
747 
748  /* ID properties */
749  if (chan->prop) {
750  if (pchan->prop) {
751  /* if we have existing properties on a bone, just copy over the values of
752  * matching properties (i.e. ones which will have some impact) on to the
753  * target instead of just blinding replacing all [
754  */
755  IDP_SyncGroupValues(pchan->prop, chan->prop);
756  }
757  else {
758  /* no existing properties, so assume that we want copies too? */
759  pchan->prop = IDP_CopyProperty(chan->prop);
760  }
761  }
762 
763  return pchan;
764 }
765 
768 /* -------------------------------------------------------------------- */
773 {
775  char str[FILE_MAX];
776  /* Sanity checking. */
777  if (ELEM(NULL, ob, ob->pose)) {
778  BKE_report(op->reports, RPT_ERROR, "No pose to copy");
779  return OPERATOR_CANCELLED;
780  }
781  /* Sets chan->flag to POSE_KEY if bone selected. */
782  set_pose_keys(ob);
783  /* Construct a local bmain and only put object and its data into it,
784  * o this way we don't expand any other objects into the copy buffer
785  * file.
786  *
787  * TODO(sergey): Find an easier way to tell copy buffer to only store
788  * data we are actually interested in. Maybe pass it a flag to skip
789  * any datablock expansion?
790  */
791  Main *temp_bmain = BKE_main_new();
793 
794  Object ob_copy = *ob;
795  ob_copy.adt = NULL;
796  bArmature arm_copy = *((bArmature *)ob->data);
797  arm_copy.adt = NULL;
798  ob_copy.data = &arm_copy;
799  BLI_addtail(&temp_bmain->objects, &ob_copy);
800  BLI_addtail(&temp_bmain->armatures, &arm_copy);
801  /* begin copy buffer on a temp bmain. */
802  BKE_copybuffer_begin(temp_bmain);
803  /* Store the whole object to the copy buffer because pose can't be
804  * existing on its own.
805  */
806  BKE_copybuffer_tag_ID(&ob_copy.id);
807  BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
808  BKE_copybuffer_save(temp_bmain, str, op->reports);
809  /* We clear the lists so no datablocks gets freed,
810  * This is required because objects in temp bmain shares same pointers
811  * as the real ones.
812  */
813  BLI_listbase_clear(&temp_bmain->objects);
814  BLI_listbase_clear(&temp_bmain->armatures);
815  BKE_main_free(temp_bmain);
816  /* We are all done! */
817  BKE_report(op->reports, RPT_INFO, "Copied pose to buffer");
818  return OPERATOR_FINISHED;
819 }
820 
822 {
823  /* identifiers */
824  ot->name = "Copy Pose";
825  ot->idname = "POSE_OT_copy";
826  ot->description = "Copies the current pose of the selected bones to copy/paste buffer";
827 
828  /* api callbacks */
831 
832  /* flag */
834 }
835 
838 /* -------------------------------------------------------------------- */
843 {
846  bPoseChannel *chan;
847  const bool flip = RNA_boolean_get(op->ptr, "flipped");
848  bool selOnly = RNA_boolean_get(op->ptr, "selected_mask");
849 
850  /* Get KeyingSet to use. */
852 
853  /* Sanity checks. */
854  if (ELEM(NULL, ob, ob->pose)) {
855  return OPERATOR_CANCELLED;
856  }
857 
858  /* Read copy buffer .blend file. */
859  char str[FILE_MAX];
860  Main *tmp_bmain = BKE_main_new();
862 
863  BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend");
864  if (!BKE_copybuffer_read(tmp_bmain, str, op->reports, FILTER_ID_OB)) {
865  BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
866  BKE_main_free(tmp_bmain);
867  return OPERATOR_CANCELLED;
868  }
869  /* Make sure data from this file is usable for pose paste. */
870  if (BLI_listbase_count_at_most(&tmp_bmain->objects, 2) != 1) {
871  BKE_report(op->reports, RPT_ERROR, "Copy buffer is not from pose mode");
872  BKE_main_free(tmp_bmain);
873  return OPERATOR_CANCELLED;
874  }
875 
876  Object *object_from = tmp_bmain->objects.first;
877  bPose *pose_from = object_from->pose;
878  if (pose_from == NULL) {
879  BKE_report(op->reports, RPT_ERROR, "Copy buffer has no pose");
880  BKE_main_free(tmp_bmain);
881  return OPERATOR_CANCELLED;
882  }
883 
884  /* If selOnly option is enabled, if user hasn't selected any bones,
885  * just go back to default behavior to be more in line with other
886  * pose tools.
887  */
888  if (selOnly) {
889  if (CTX_DATA_COUNT(C, selected_pose_bones) == 0) {
890  selOnly = false;
891  }
892  }
893 
894  /* Safely merge all of the channels in the buffer pose into any
895  * existing pose.
896  */
897  for (chan = pose_from->chanbase.first; chan; chan = chan->next) {
898  if (chan->flag & POSE_KEY) {
899  /* Try to perform paste on this bone. */
900  bPoseChannel *pchan = pose_bone_do_paste(ob, chan, selOnly, flip);
901  if (pchan != NULL) {
902  /* Keyframing tagging for successful paste, */
903  ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
904  }
905  }
906  }
907  BKE_main_free(tmp_bmain);
908 
909  /* Update event for pose and deformation children. */
911 
912  /* Recalculate paths if any of the bones have paths... */
915  }
916 
917  /* Notifiers for updates, */
919 
920  return OPERATOR_FINISHED;
921 }
922 
924 {
925  PropertyRNA *prop;
926 
927  /* identifiers */
928  ot->name = "Paste Pose";
929  ot->idname = "POSE_OT_paste";
930  ot->description = "Paste the stored pose on to the current pose";
931 
932  /* api callbacks */
935 
936  /* flag */
938 
939  /* properties */
940  prop = RNA_def_boolean(ot->srna,
941  "flipped",
942  false,
943  "Flipped on X-Axis",
944  "Paste the stored pose flipped on to current pose");
946 
948  "selected_mask",
949  false,
950  "On Selected Only",
951  "Only paste the stored pose on to selected bones in the current pose");
952 }
953 
956 /* -------------------------------------------------------------------- */
960 /* clear scale of pose-channel */
961 static void pchan_clear_scale(bPoseChannel *pchan)
962 {
963  if ((pchan->protectflag & OB_LOCK_SCALEX) == 0) {
964  pchan->size[0] = 1.0f;
965  }
966  if ((pchan->protectflag & OB_LOCK_SCALEY) == 0) {
967  pchan->size[1] = 1.0f;
968  }
969  if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0) {
970  pchan->size[2] = 1.0f;
971  }
972 
973  pchan->ease1 = 0.0f;
974  pchan->ease2 = 0.0f;
975  pchan->scale_in_x = pchan->scale_in_y = 1.0f;
976  pchan->scale_out_x = pchan->scale_out_y = 1.0f;
977 }
978 /* Clear the scale. When X-mirror is enabled,
979  * also clear the scale of the mirrored pose channel. */
980 static void pchan_clear_scale_with_mirrored(const bPose *pose, bPoseChannel *pchan)
981 {
982  if (pose->flag & POSE_MIRROR_EDIT) {
983  bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
984  if (pchan_mirror != NULL) {
985  pchan_clear_scale(pchan_mirror);
986  }
987  }
988  pchan_clear_scale(pchan);
989 }
990 
991 /* clear location of pose-channel */
992 static void pchan_clear_loc(bPoseChannel *pchan)
993 {
994  if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
995  pchan->loc[0] = 0.0f;
996  }
997  if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
998  pchan->loc[1] = 0.0f;
999  }
1000  if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
1001  pchan->loc[2] = 0.0f;
1002  }
1003 }
1004 /* Clear the Location. When X-mirror is enabled,
1005  * also clear the location of the mirrored pose channel. */
1006 static void pchan_clear_loc_with_mirrored(const bPose *pose, bPoseChannel *pchan)
1007 {
1008  if (pose->flag & POSE_MIRROR_EDIT) {
1009  bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
1010  if (pchan_mirror != NULL) {
1011  pchan_clear_loc(pchan_mirror);
1012  }
1013  }
1014  pchan_clear_loc(pchan);
1015 }
1016 
1017 /* clear rotation of pose-channel */
1018 static void pchan_clear_rot(bPoseChannel *pchan)
1019 {
1021  /* check if convert to eulers for locking... */
1022  if (pchan->protectflag & OB_LOCK_ROT4D) {
1023  /* perform clamping on a component by component basis */
1024  if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1025  if ((pchan->protectflag & OB_LOCK_ROTW) == 0) {
1026  pchan->rotAngle = 0.0f;
1027  }
1028  if ((pchan->protectflag & OB_LOCK_ROTX) == 0) {
1029  pchan->rotAxis[0] = 0.0f;
1030  }
1031  if ((pchan->protectflag & OB_LOCK_ROTY) == 0) {
1032  pchan->rotAxis[1] = 0.0f;
1033  }
1034  if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) {
1035  pchan->rotAxis[2] = 0.0f;
1036  }
1037 
1038  /* check validity of axis - axis should never be 0,0,0
1039  * (if so, then we make it rotate about y). */
1040  if (IS_EQF(pchan->rotAxis[0], pchan->rotAxis[1]) &&
1041  IS_EQF(pchan->rotAxis[1], pchan->rotAxis[2])) {
1042  pchan->rotAxis[1] = 1.0f;
1043  }
1044  }
1045  else if (pchan->rotmode == ROT_MODE_QUAT) {
1046  if ((pchan->protectflag & OB_LOCK_ROTW) == 0) {
1047  pchan->quat[0] = 1.0f;
1048  }
1049  if ((pchan->protectflag & OB_LOCK_ROTX) == 0) {
1050  pchan->quat[1] = 0.0f;
1051  }
1052  if ((pchan->protectflag & OB_LOCK_ROTY) == 0) {
1053  pchan->quat[2] = 0.0f;
1054  }
1055  if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) {
1056  pchan->quat[3] = 0.0f;
1057  }
1058  }
1059  else {
1060  /* the flag may have been set for the other modes, so just ignore the extra flag... */
1061  if ((pchan->protectflag & OB_LOCK_ROTX) == 0) {
1062  pchan->eul[0] = 0.0f;
1063  }
1064  if ((pchan->protectflag & OB_LOCK_ROTY) == 0) {
1065  pchan->eul[1] = 0.0f;
1066  }
1067  if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) {
1068  pchan->eul[2] = 0.0f;
1069  }
1070  }
1071  }
1072  else {
1073  /* perform clamping using euler form (3-components) */
1074  float eul[3], oldeul[3], quat1[4] = {0};
1075  float qlen = 0.0f;
1076 
1077  if (pchan->rotmode == ROT_MODE_QUAT) {
1078  qlen = normalize_qt_qt(quat1, pchan->quat);
1079  quat_to_eul(oldeul, quat1);
1080  }
1081  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1082  axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
1083  }
1084  else {
1085  copy_v3_v3(oldeul, pchan->eul);
1086  }
1087 
1088  eul[0] = eul[1] = eul[2] = 0.0f;
1089 
1090  if (pchan->protectflag & OB_LOCK_ROTX) {
1091  eul[0] = oldeul[0];
1092  }
1093  if (pchan->protectflag & OB_LOCK_ROTY) {
1094  eul[1] = oldeul[1];
1095  }
1096  if (pchan->protectflag & OB_LOCK_ROTZ) {
1097  eul[2] = oldeul[2];
1098  }
1099 
1100  if (pchan->rotmode == ROT_MODE_QUAT) {
1101  eul_to_quat(pchan->quat, eul);
1102 
1103  /* restore original quat size */
1104  mul_qt_fl(pchan->quat, qlen);
1105 
1106  /* quaternions flip w sign to accumulate rotations correctly */
1107  if ((quat1[0] < 0.0f && pchan->quat[0] > 0.0f) ||
1108  (quat1[0] > 0.0f && pchan->quat[0] < 0.0f)) {
1109  mul_qt_fl(pchan->quat, -1.0f);
1110  }
1111  }
1112  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1113  eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
1114  }
1115  else {
1116  copy_v3_v3(pchan->eul, eul);
1117  }
1118  }
1119  } /* Duplicated in source/blender/editors/object/object_transform.c */
1120  else {
1121  if (pchan->rotmode == ROT_MODE_QUAT) {
1122  unit_qt(pchan->quat);
1123  }
1124  else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
1125  /* by default, make rotation of 0 radians around y-axis (roll) */
1126  unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
1127  }
1128  else {
1129  zero_v3(pchan->eul);
1130  }
1131  }
1132 
1133  /* Clear also Bendy Bone stuff - Roll is obvious,
1134  * but Curve X/Y stuff is also kindof rotational in nature... */
1135  pchan->roll1 = 0.0f;
1136  pchan->roll2 = 0.0f;
1137 
1138  pchan->curve_in_x = 0.0f;
1139  pchan->curve_in_y = 0.0f;
1140  pchan->curve_out_x = 0.0f;
1141  pchan->curve_out_y = 0.0f;
1142 }
1143 /* Clear the rotation. When X-mirror is enabled,
1144  * also clear the rotation of the mirrored pose channel. */
1145 static void pchan_clear_rot_with_mirrored(const bPose *pose, bPoseChannel *pchan)
1146 {
1147  if (pose->flag & POSE_MIRROR_EDIT) {
1148  bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
1149  if (pchan_mirror != NULL) {
1150  pchan_clear_rot(pchan_mirror);
1151  }
1152  }
1153  pchan_clear_rot(pchan);
1154 }
1155 
1156 /* clear loc/rot/scale of pose-channel */
1157 static void pchan_clear_transforms(const bPose *pose, bPoseChannel *pchan)
1158 {
1159  pchan_clear_loc_with_mirrored(pose, pchan);
1160  pchan_clear_rot_with_mirrored(pose, pchan);
1161  pchan_clear_scale_with_mirrored(pose, pchan);
1162 }
1163 
1164 /* --------------- */
1165 
1166 /* generic exec for clear-pose operators */
1168  wmOperator *op,
1169  void (*clear_func)(const bPose *, bPoseChannel *),
1170  const char default_ksName[])
1171 {
1174  bool changed_multi = false;
1175 
1176  /* sanity checks */
1177  if (ELEM(NULL, clear_func, default_ksName)) {
1178  BKE_report(op->reports,
1179  RPT_ERROR,
1180  "Programming error: missing clear transform function or keying set name");
1181  return OPERATOR_CANCELLED;
1182  }
1183 
1184  /* only clear relevant transforms for selected bones */
1185  ViewLayer *view_layer = CTX_data_view_layer(C);
1186  View3D *v3d = CTX_wm_view3d(C);
1187  FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
1188  /* XXX: UGLY HACK (for autokey + clear transforms) */
1189  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
1190  ListBase dsources = {NULL, NULL};
1191  bool changed = false;
1192 
1193  FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
1194  /* run provided clearing function */
1195  clear_func(ob_iter->pose, pchan);
1196  changed = true;
1197 
1198  /* do auto-keyframing as appropriate */
1199  if (autokeyframe_cfra_can_key(scene, &ob_iter->id)) {
1200  /* tag for autokeying later */
1201  ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan);
1202 
1203 #if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
1204  bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
1205  clear_func(ob_iter->pose, pchan_eval);
1206 #endif
1207  }
1208  }
1210 
1211  if (changed) {
1212  changed_multi = true;
1213 
1214  /* perform autokeying on the bones if needed */
1215  if (!BLI_listbase_is_empty(&dsources)) {
1216  /* get KeyingSet to use */
1217  KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
1218 
1219  /* insert keyframes */
1220  ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
1221 
1222  /* now recalculate paths */
1223  if ((ob_iter->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
1225  }
1226 
1227  BLI_freelistN(&dsources);
1228  }
1229 
1230  DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
1231 
1232  /* note, notifier might evolve */
1234  }
1235  }
1237 
1238  return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1239 }
1240 
1243 /* -------------------------------------------------------------------- */
1248 {
1251 }
1252 
1254 {
1255  /* identifiers */
1256  ot->name = "Clear Pose Scale";
1257  ot->idname = "POSE_OT_scale_clear";
1258  ot->description = "Reset scaling of selected bones to their default values";
1259 
1260  /* api callbacks */
1263 
1264  /* flags */
1266 }
1267 
1270 /* -------------------------------------------------------------------- */
1275 {
1278 }
1279 
1281 {
1282  /* identifiers */
1283  ot->name = "Clear Pose Rotation";
1284  ot->idname = "POSE_OT_rot_clear";
1285  ot->description = "Reset rotations of selected bones to their default values";
1286 
1287  /* api callbacks */
1290 
1291  /* flags */
1293 }
1294 
1297 /* -------------------------------------------------------------------- */
1302 {
1305 }
1306 
1308 {
1309  /* identifiers */
1310  ot->name = "Clear Pose Location";
1311  ot->idname = "POSE_OT_loc_clear";
1312  ot->description = "Reset locations of selected bones to their default values";
1313 
1314  /* api callbacks */
1317 
1318  /* flags */
1320 }
1321 
1324 /* -------------------------------------------------------------------- */
1329 {
1332 }
1333 
1335 {
1336  /* identifiers */
1337  ot->name = "Clear Pose Transforms";
1338  ot->idname = "POSE_OT_transforms_clear";
1339  ot->description =
1340  "Reset location, rotation, and scaling of selected bones to their default values";
1341 
1342  /* api callbacks */
1345 
1346  /* flags */
1348 }
1349 
1352 /* -------------------------------------------------------------------- */
1357 {
1358  ViewLayer *view_layer = CTX_data_view_layer(C);
1359  View3D *v3d = CTX_wm_view3d(C);
1363  (float)CFRA);
1364  const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
1365 
1366  FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
1367  if ((ob->adt) && (ob->adt->action)) {
1368  /* XXX: this is just like this to avoid contaminating anything else;
1369  * just pose values should change, so this should be fine
1370  */
1371  bPose *dummyPose = NULL;
1372  Object workob = {{NULL}};
1373  bPoseChannel *pchan;
1374 
1375  /* execute animation step for current frame using a dummy copy of the pose */
1376  BKE_pose_copy_data(&dummyPose, ob->pose, 0);
1377 
1378  BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name));
1379  workob.type = OB_ARMATURE;
1380  workob.data = ob->data;
1381  workob.adt = ob->adt;
1382  workob.pose = dummyPose;
1383 
1385  &workob.id, workob.adt, &anim_eval_context, ADT_RECALC_ANIM, false);
1386 
1387  /* copy back values, but on selected bones only */
1388  for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
1389  pose_bone_do_paste(ob, pchan, only_select, 0);
1390  }
1391 
1392  /* free temp data - free manually as was copied without constraints */
1393  for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
1394  if (pchan->prop) {
1395  IDP_FreeProperty(pchan->prop);
1396  }
1397  }
1398 
1399  /* was copied without constraints */
1400  BLI_freelistN(&dummyPose->chanbase);
1401  MEM_freeN(dummyPose);
1402  }
1403  else {
1404  /* No animation, so just reset to the rest pose. */
1405  BKE_pose_rest(ob->pose, only_select);
1406  }
1407 
1408  /* notifiers and updates */
1411  }
1413 
1414  return OPERATOR_FINISHED;
1415 }
1416 
1418 {
1419  /* identifiers */
1420  ot->name = "Clear User Transforms";
1421  ot->idname = "POSE_OT_user_transforms_clear";
1422  ot->description = "Reset pose bone transforms to keyframed state";
1423 
1424  /* callbacks */
1427 
1428  /* flags */
1430 
1431  /* properties */
1432  RNA_def_boolean(ot->srna, "only_selected", true, "Only Selected", "Only visible/selected bones");
1433 }
1434 
typedef float(TangentPoint)[2]
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)
void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints)
void BKE_pose_rest(struct bPose *pose, bool selected_bones_only)
Definition: action.c:1636
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:637
@ ADT_RECALC_ANIM
Definition: BKE_animsys.h:238
void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, const bool flush_to_original)
const char * BKE_tempdir_base(void)
Definition: appdir.c:1182
void vec_roll_to_mat3(const float vec[3], const float roll, float r_mat[3][3])
Definition: armature.c:2212
struct bArmature * BKE_armature_from_object(struct Object *ob)
Definition: armature.c:353
void mat3_vec_to_roll(const float mat[3][3], const float vec[3], float *r_roll)
Definition: armature.c:2072
void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, const float mat[4][4], bool use_compat)
Definition: armature.c:1951
void BKE_bone_parent_transform_combine(const struct BoneParentTransform *in1, const struct BoneParentTransform *in2, struct BoneParentTransform *result)
Definition: armature.c:1803
void BKE_armature_mat_pose_to_bone(struct bPoseChannel *pchan, const float inmat[4][4], float outmat[4][4])
Definition: armature.c:1828
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_END
Definition: BKE_armature.h:353
void BKE_bone_parent_transform_invert(struct BoneParentTransform *bpt)
Definition: armature.c:1796
void BKE_bone_offset_matrix_get(const struct Bone *bone, float offs_bone[4][4])
#define PBONE_VISIBLE(arm, bone)
Definition: BKE_armature.h:338
void BKE_bone_parent_transform_clear(struct BoneParentTransform *bpt)
Definition: armature.c:1789
void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
Definition: armature.c:2739
void BKE_bone_parent_transform_calc_from_matrices(int bone_flag, int inherit_scale_mode, const float offs_bone[4][4], const float parent_arm_mat[4][4], const float parent_pose_mat[4][4], struct BoneParentTransform *r_bpt)
Definition: armature.c:1644
#define FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN(_ob, _pchan)
Definition: BKE_armature.h:349
void BKE_bone_parent_transform_apply(const struct BoneParentTransform *bpt, const float inmat[4][4], float outmat[4][4])
Definition: armature.c:1812
bool BKE_copybuffer_read(struct Main *bmain_dst, const char *libname, struct ReportList *reports, const uint64_t id_types_mask)
bool BKE_copybuffer_save(struct Main *bmain_src, const char *filename, struct ReportList *reports)
void BKE_copybuffer_begin(struct Main *bmain_src)
void BKE_copybuffer_tag_ID(struct ID *id)
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
#define CTX_DATA_COUNT(C, member)
Definition: BKE_context.h:272
int CTX_data_selected_pose_bones(const bContext *C, ListBase *list)
Definition: context.c:1356
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
support for deformation groups and hooks.
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1040
void IDP_SyncGroupValues(struct IDProperty *dest, const struct IDProperty *src) ATTR_NONNULL()
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define FOREACH_OBJECT_IN_MODE_END
Definition: BKE_layer.h:284
#define FOREACH_OBJECT_IN_MODE_BEGIN(_view_layer, _v3d, _object_type, _object_mode, _instance)
Definition: BKE_layer.h:280
struct Main * BKE_main_new(void)
Definition: main.c:45
void BKE_main_free(struct Main *mainvar)
Definition: main.c:53
const char * BKE_main_blendfile_path_from_global(void)
Definition: main.c:439
General operations, lookup, etc. for blender objects.
bool BKE_object_obdata_is_libdata(const struct Object *ob)
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.c:2487
void BKE_object_workob_calc_parent(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct Object *workob)
Definition: object.c:3667
void BKE_object_apply_mat4(struct Object *ob, const float mat[4][4], const bool use_compat, const bool use_parent)
Definition: object.c:3754
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#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
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
Definition: BLI_listbase.h:180
int BLI_listbase_count_at_most(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1187
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
Definition: math_matrix.c:437
void unit_m4(float m[4][4])
Definition: rct.c:1140
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:120
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
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:804
void quat_to_eulO(float eul[3], const short order, const float quat[4])
void eulO_to_quat(float quat[4], const float eul[3], const short order)
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const short order)
void mul_qt_fl(float q[4], const float f)
@ EULER_ORDER_DEFAULT
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
float normalize_qt(float q[4])
void unit_qt(float q[4])
Definition: math_rotation.c:46
void eul_to_quat(float quat[4], const float eul[3])
void quat_to_eul(float eul[3], const float quat[4])
float normalize_qt_qt(float r[4], const float q[4])
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
void axis_angle_to_eulO(float eul[3], const short order, const float axis[3], const float angle)
void unit_axis_angle(float axis[3], float *angle)
Definition: math_rotation.c:38
void copy_qt_qt(float q[4], const float a[4])
Definition: math_rotation.c:52
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 bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void zero_v3(float r[3])
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
#define STRNCPY(dst, src)
Definition: BLI_string.h:163
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
#define UNUSED(x)
#define ELEM(...)
#define IS_EQF(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
#define FILTER_ID_OB
Definition: DNA_ID.h:722
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ MOTIONPATH_BAKE_HAS_PATHS
@ ROT_MODE_QUAT
@ ROT_MODE_AXISANGLE
@ POSE_KEY
@ POSE_MIRROR_EDIT
#define MAXBONENAME
@ BONE_SELECTED
@ BONE_CONNECTED
@ CONSTRAINT_TYPE_STRETCHTO
@ OB_MODE_POSE
Object is a sort of wrapper for general info.
@ OB_LOCK_ROTZ
@ OB_LOCK_ROT4D
@ OB_LOCK_SCALEZ
@ OB_LOCK_ROTX
@ OB_LOCK_SCALEX
@ OB_LOCK_ROTW
@ OB_LOCK_LOCY
@ OB_LOCK_LOCZ
@ OB_LOCK_ROTY
@ OB_LOCK_SCALEY
@ OB_LOCK_LOCX
@ PARBONE
@ OB_ARMATURE
#define CFRA
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ POSE_PATH_CALC_RANGE_FULL
Definition: ED_armature.h:203
#define ANIM_KS_LOC_ROT_SCALE_ID
@ MODIFYKEY_MODE_INSERT
#define ANIM_KS_LOCATION_ID
#define ANIM_KS_WHOLE_CHARACTER_ID
#define ANIM_KS_SCALING_ID
#define ANIM_KS_ROTATION_ID
bool ED_operator_posemode(struct bContext *C)
Definition: screen_ops.c:484
Read Guarded memory(de)allocation.
StructRNA RNA_PoseBone
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_POSE
Definition: WM_types.h:359
#define ND_TRANSFORM
Definition: WM_types.h:357
#define NC_OBJECT
Definition: WM_types.h:280
void ED_armature_edit_free(struct bArmature *arm)
void ED_armature_from_edit(Main *bmain, bArmature *arm)
EditBone * ED_armature_ebone_find_name(const ListBase *edbo, const char *name)
void ED_armature_to_edit(bArmature *arm)
Scene scene
const Depsgraph * depsgraph
#define str(s)
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
Definition: keyframing.c:2779
bool ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
Definition: keyframing.c:3023
int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
Definition: keyingsets.c:1028
KeyingSet * ANIM_get_keyingset_for_autokeying(const Scene *scene, const char *transformKSName)
Definition: keyingsets.c:725
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
Definition: keyingsets.c:898
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, ePosePathCalcRange range)
Definition: pose_edit.c:203
static void pchan_clear_scale_with_mirrored(const bPose *pose, bPoseChannel *pchan)
static void applyarmature_process_selected_recursive(bArmature *arm, bPose *pose, bPose *pose_eval, Bone *bone, ListBase *selected, ApplyArmature_ParentState *pstate)
void POSE_OT_armature_apply(wmOperatorType *ot)
static void pchan_clear_transforms(const bPose *pose, bPoseChannel *pchan)
void POSE_OT_transforms_clear(wmOperatorType *ot)
static void applyarmature_reset_bone_constraints(const bPoseChannel *pchan)
void POSE_OT_paste(wmOperatorType *ot)
static int pose_copy_exec(bContext *C, wmOperator *op)
static void applyarmature_set_edit_position(EditBone *curbone, const float pose_mat[4][4], const float new_tail[3], float r_new_arm_mat[4][4])
static int pose_paste_exec(bContext *C, wmOperator *op)
static void pchan_clear_scale(bPoseChannel *pchan)
void POSE_OT_visual_transform_apply(wmOperatorType *ot)
static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Object *armob)
static void applyarmature_reset_bone_constraint(const bConstraint *constraint)
static void pchan_clear_loc_with_mirrored(const bPose *pose, bPoseChannel *pchan)
static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
static int pose_clear_rot_exec(bContext *C, wmOperator *op)
static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
static int pose_clear_loc_exec(bContext *C, wmOperator *op)
static void applyarmature_reset_constraints(bPose *pose, const bool use_selected)
static void pchan_clear_rot(bPoseChannel *pchan)
static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
void POSE_OT_copy(wmOperatorType *ot)
void POSE_OT_rot_clear(wmOperatorType *ot)
static int pose_clear_scale_exec(bContext *C, wmOperator *op)
static void applyarmature_adjust_edit_position(bArmature *arm, bPoseChannel *pchan, const float delta_mat[4][4], float r_new_arm_mat[4][4])
static void applyarmature_transfer_properties(EditBone *curbone, bPoseChannel *pchan, const bPoseChannel *pchan_eval)
static void apply_armature_pose2bones_ui(bContext *C, wmOperator *op)
void POSE_OT_loc_clear(wmOperatorType *ot)
static void set_pose_keys(Object *ob)
struct ApplyArmature_ParentState ApplyArmature_ParentState
static void pchan_clear_loc(bPoseChannel *pchan)
void POSE_OT_scale_clear(wmOperatorType *ot)
static bPoseChannel * pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bool selOnly, const bool flip)
void POSE_OT_user_transforms_clear(wmOperatorType *ot)
static int pose_clear_transforms_exec(bContext *C, wmOperator *op)
static void pchan_clear_rot_with_mirrored(const bPose *pose, bPoseChannel *pchan)
static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, void(*clear_func)(const bPose *, bPoseChannel *), const char default_ksName[])
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
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
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
bAction * action
float loc_mat[4][4]
Definition: BKE_armature.h:247
struct Bone * parent
char name[64]
char inherit_scale_mode
short segments
float length
float arm_mat[4][4]
ListBase childbase
float ease2
Definition: BKE_armature.h:85
float roll1
Definition: BKE_armature.h:82
float scale_out_y
Definition: BKE_armature.h:87
float tail[3]
Definition: BKE_armature.h:66
float roll
Definition: BKE_armature.h:62
float roll2
Definition: BKE_armature.h:82
float curve_in_x
Definition: BKE_armature.h:83
float scale_out_x
Definition: BKE_armature.h:87
float curve_in_y
Definition: BKE_armature.h:83
float ease1
Definition: BKE_armature.h:85
float curve_out_y
Definition: BKE_armature.h:84
float curve_out_x
Definition: BKE_armature.h:84
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
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
char name[1024]
Definition: BKE_main.h:118
ListBase armatures
Definition: BKE_main.h:168
ListBase objects
Definition: BKE_main.h:148
short partype
struct bPose * pose
float parentinv[4][4]
float obmat[4][4]
struct AnimData * adt
struct Object * parent
void * data
void * data
Definition: RNA_types.h:52
struct AnimData * adt
ListBase bonebase
unsigned int layer
ListBase * edbo
ListBase constraints
IDProperty * prop
struct Bone * bone
struct bPoseChannel * parent
float pose_tail[3]
struct bPoseChannel * next
float pose_mat[4][4]
ListBase chanbase
short flag
bAnimVizSettings avs
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
void(* ui)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:787
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
IDProperty * properties
struct uiLayout * layout
struct wmOperatorType * type
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156