Cleanup: style, use braces for editors
[blender.git] / source / blender / editors / armature / pose_transform.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edarmature
22  */
23
24 #include "DNA_anim_types.h"
25 #include "DNA_armature_types.h"
26 #include "DNA_object_types.h"
27 #include "DNA_scene_types.h"
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_blenlib.h"
32 #include "BLI_math.h"
33 #include "BLI_string_utils.h"
34
35 #include "BKE_action.h"
36 #include "BKE_animsys.h"
37 #include "BKE_appdir.h"
38 #include "BKE_armature.h"
39 #include "BKE_blender_copybuffer.h"
40 #include "BKE_context.h"
41 #include "BKE_deform.h"
42 #include "BKE_idprop.h"
43 #include "BKE_layer.h"
44 #include "BKE_main.h"
45 #include "BKE_object.h"
46 #include "BKE_report.h"
47
48 #include "DEG_depsgraph.h"
49 #include "DEG_depsgraph_query.h"
50
51 #include "RNA_access.h"
52 #include "RNA_define.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "ED_armature.h"
58 #include "ED_keyframing.h"
59 #include "ED_screen.h"
60 #include "ED_util.h"
61
62 #include "armature_intern.h"
63
64 /* ********************************************** */
65 /* Pose Apply */
66
67 /* helper for apply_armature_pose2bones - fixes parenting of objects
68  * that are bone-parented to armature */
69 static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Object *armob)
70 {
71   Depsgraph *depsgraph = CTX_data_depsgraph(C);
72   Main *bmain = CTX_data_main(C);
73   Object workob, *ob;
74
75   /* go through all objects in database */
76   for (ob = bmain->objects.first; ob; ob = ob->id.next) {
77     /* if parent is bone in this armature, apply corrections */
78     if ((ob->parent == armob) && (ob->partype == PARBONE)) {
79       /* apply current transform from parent (not yet destroyed),
80        * then calculate new parent inverse matrix
81        */
82       BKE_object_apply_mat4(ob, ob->obmat, false, false);
83
84       BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
85       invert_m4_m4(ob->parentinv, workob.obmat);
86     }
87   }
88 }
89
90 /* set the current pose as the restpose */
91 static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
92 {
93   Main *bmain = CTX_data_main(C);
94   Depsgraph *depsgraph = CTX_data_depsgraph(C);
95   Scene *scene = CTX_data_scene(C);
96   // must be active object, not edit-object
97   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
98   const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
99   bArmature *arm = BKE_armature_from_object(ob);
100   bPose *pose;
101   bPoseChannel *pchan;
102   EditBone *curbone;
103
104   /* don't check if editmode (should be done by caller) */
105   if (ob->type != OB_ARMATURE) {
106     return OPERATOR_CANCELLED;
107   }
108   if (BKE_object_obdata_is_libdata(ob)) {
109     BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature");
110     return OPERATOR_CANCELLED;
111   }
112
113   /* helpful warnings... */
114   /* TODO: add warnings to be careful about actions, applying deforms first, etc. */
115   if (ob->adt && ob->adt->action) {
116     BKE_report(op->reports,
117                RPT_WARNING,
118                "Actions on this armature will be destroyed by this new rest pose as the "
119                "transforms stored are relative to the old rest pose");
120   }
121
122   /* Get editbones of active armature to alter */
123   ED_armature_to_edit(arm);
124
125   /* get pose of active object and move it out of posemode */
126   pose = ob->pose;
127
128   for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
129     const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
130     curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name);
131
132     /* simply copy the head/tail values from pchan over to curbone */
133     copy_v3_v3(curbone->head, pchan_eval->pose_head);
134     copy_v3_v3(curbone->tail, pchan_eval->pose_tail);
135
136     /* fix roll:
137      * 1. find auto-calculated roll value for this bone now
138      * 2. remove this from the 'visual' y-rotation
139      */
140     {
141       float premat[3][3], imat[3][3], pmat[3][3], tmat[3][3];
142       float delta[3], eul[3];
143
144       /* obtain new auto y-rotation */
145       sub_v3_v3v3(delta, curbone->tail, curbone->head);
146       vec_roll_to_mat3(delta, 0.0f, premat);
147       invert_m3_m3(imat, premat);
148
149       /* get pchan 'visual' matrix */
150       copy_m3_m4(pmat, pchan_eval->pose_mat);
151
152       /* remove auto from visual and get euler rotation */
153       mul_m3_m3m3(tmat, imat, pmat);
154       mat3_to_eul(eul, tmat);
155
156       /* just use this euler-y as new roll value */
157       curbone->roll = eul[1];
158     }
159
160     /* combine pose and rest values for bendy bone settings,
161      * then clear the pchan values (so we don't get a double-up)
162      */
163     if (pchan->bone->segments > 1) {
164       /* combine rest/pose values  */
165       curbone->curveInX += pchan_eval->curveInX;
166       curbone->curveInY += pchan_eval->curveInY;
167       curbone->curveOutX += pchan_eval->curveOutX;
168       curbone->curveOutY += pchan_eval->curveOutY;
169       curbone->roll1 += pchan_eval->roll1;
170       curbone->roll2 += pchan_eval->roll2;
171       curbone->ease1 += pchan_eval->ease1;
172       curbone->ease2 += pchan_eval->ease2;
173       curbone->scaleIn += pchan_eval->scaleIn;
174       curbone->scaleOut += pchan_eval->scaleOut;
175
176       /* reset pose values */
177       pchan->curveInX = pchan->curveOutX = 0.0f;
178       pchan->curveInY = pchan->curveOutY = 0.0f;
179       pchan->roll1 = pchan->roll2 = 0.0f;
180       pchan->ease1 = pchan->ease2 = 0.0f;
181       pchan->scaleIn = pchan->scaleOut = 1.0f;
182     }
183
184     /* clear transform values for pchan */
185     zero_v3(pchan->loc);
186     zero_v3(pchan->eul);
187     unit_qt(pchan->quat);
188     unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
189     pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f;
190
191     /* set anim lock */
192     curbone->flag |= BONE_UNKEYED;
193   }
194
195   /* convert editbones back to bones, and then free the edit-data */
196   ED_armature_from_edit(bmain, arm);
197   ED_armature_edit_free(arm);
198
199   /* flush positions of posebones */
200   BKE_pose_where_is(depsgraph, scene, ob);
201
202   /* fix parenting of objects which are bone-parented */
203   applyarmature_fix_boneparents(C, scene, ob);
204
205   /* note, notifier might evolve */
206   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
207   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
208
209   return OPERATOR_FINISHED;
210 }
211
212 void POSE_OT_armature_apply(wmOperatorType *ot)
213 {
214   /* identifiers */
215   ot->name = "Apply Pose as Rest Pose";
216   ot->idname = "POSE_OT_armature_apply";
217   ot->description = "Apply the current pose as the new rest pose";
218
219   /* callbacks */
220   ot->exec = apply_armature_pose2bones_exec;
221   ot->poll = ED_operator_posemode;
222
223   /* flags */
224   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
225 }
226
227 /* set the current pose as the restpose */
228 static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
229 {
230   ViewLayer *view_layer = CTX_data_view_layer(C);
231   View3D *v3d = CTX_wm_view3d(C);
232   Depsgraph *depsgraph = CTX_data_depsgraph(C);
233
234   FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
235     /* loop over all selected pchans
236      *
237      * TODO, loop over children before parents if multiple bones
238      * at once are to be predictable*/
239     FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan) {
240       const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
241       bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
242       float delta_mat[4][4];
243
244       /* chan_mat already contains the delta transform from rest pose to pose-mode pose
245        * as that is baked into there so that B-Bones will work. Once we've set this as the
246        * new raw-transform components, don't recalc the poses yet, otherwise IK result will
247        * change, thus changing the result we may be trying to record.
248        */
249       /* XXX For some reason, we can't use pchan->chan_mat here, gives odd rotation/offset
250        * (see T38251).
251        * Using pchan->pose_mat and bringing it back in bone space seems to work as expected!
252        */
253       BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, delta_mat);
254
255       BKE_pchan_apply_mat4(pchan, delta_mat, true);
256     }
257     FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
258
259     DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
260
261     /* note, notifier might evolve */
262     WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
263   }
264   FOREACH_OBJECT_IN_MODE_END;
265
266   return OPERATOR_FINISHED;
267 }
268
269 void POSE_OT_visual_transform_apply(wmOperatorType *ot)
270 {
271   /* identifiers */
272   ot->name = "Apply Visual Transform to Pose";
273   ot->idname = "POSE_OT_visual_transform_apply";
274   ot->description = "Apply final constrained position of pose bones to their transform";
275
276   /* callbacks */
277   ot->exec = pose_visual_transform_apply_exec;
278   ot->poll = ED_operator_posemode;
279
280   /* flags */
281   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
282 }
283
284 /* ********************************************** */
285 /* Copy/Paste */
286
287 /* This function is used to indicate that a bone is selected
288  * and needs to be included in copy buffer (used to be for inserting keys)
289  */
290 static void set_pose_keys(Object *ob)
291 {
292   bArmature *arm = ob->data;
293   bPoseChannel *chan;
294
295   if (ob->pose) {
296     for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
297       Bone *bone = chan->bone;
298       if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) {
299         chan->flag |= POSE_KEY;
300       }
301       else {
302         chan->flag &= ~POSE_KEY;
303       }
304     }
305   }
306 }
307
308 /**
309  * Perform paste pose, for a single bone.
310  *
311  * \param ob: Object where bone to paste to lives
312  * \param chan: Bone that pose to paste comes from
313  * \param selOnly: Only paste on selected bones
314  * \param flip: Flip on x-axis
315  * \return Whether the bone that we pasted to if we succeeded
316  */
317 static bPoseChannel *pose_bone_do_paste(Object *ob,
318                                         bPoseChannel *chan,
319                                         const bool selOnly,
320                                         const bool flip)
321 {
322   bPoseChannel *pchan;
323   char name[MAXBONENAME];
324   short paste_ok;
325
326   /* get the name - if flipping, we must flip this first */
327   if (flip) {
328     BLI_string_flip_side_name(name, chan->name, false, sizeof(name));
329   }
330   else {
331     BLI_strncpy(name, chan->name, sizeof(name));
332   }
333
334   /* only copy when:
335    *  1) channel exists - poses are not meant to add random channels to anymore
336    *  2) if selection-masking is on, channel is selected -
337    *     only selected bones get pasted on, allowing making both sides symmetrical.
338    */
339   pchan = BKE_pose_channel_find_name(ob->pose, name);
340
341   if (selOnly) {
342     paste_ok = ((pchan) && (pchan->bone->flag & BONE_SELECTED));
343   }
344   else {
345     paste_ok = (pchan != NULL);
346   }
347
348   /* continue? */
349   if (paste_ok) {
350     /* only loc rot size
351      * - only copies transform info for the pose
352      */
353     copy_v3_v3(pchan->loc, chan->loc);
354     copy_v3_v3(pchan->size, chan->size);
355     pchan->flag = chan->flag;
356
357     /* check if rotation modes are compatible (i.e. do they need any conversions) */
358     if (pchan->rotmode == chan->rotmode) {
359       /* copy the type of rotation in use */
360       if (pchan->rotmode > 0) {
361         copy_v3_v3(pchan->eul, chan->eul);
362       }
363       else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
364         copy_v3_v3(pchan->rotAxis, chan->rotAxis);
365         pchan->rotAngle = chan->rotAngle;
366       }
367       else {
368         copy_qt_qt(pchan->quat, chan->quat);
369       }
370     }
371     else if (pchan->rotmode > 0) {
372       /* quat/axis-angle to euler */
373       if (chan->rotmode == ROT_MODE_AXISANGLE) {
374         axis_angle_to_eulO(pchan->eul, pchan->rotmode, chan->rotAxis, chan->rotAngle);
375       }
376       else {
377         quat_to_eulO(pchan->eul, pchan->rotmode, chan->quat);
378       }
379     }
380     else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
381       /* quat/euler to axis angle */
382       if (chan->rotmode > 0) {
383         eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->eul, chan->rotmode);
384       }
385       else {
386         quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->quat);
387       }
388     }
389     else {
390       /* euler/axis-angle to quat */
391       if (chan->rotmode > 0) {
392         eulO_to_quat(pchan->quat, chan->eul, chan->rotmode);
393       }
394       else {
395         axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle);
396       }
397     }
398
399     /* B-Bone posing options should also be included... */
400     pchan->curveInX = chan->curveInX;
401     pchan->curveInY = chan->curveInY;
402     pchan->curveOutX = chan->curveOutX;
403     pchan->curveOutY = chan->curveOutY;
404
405     pchan->roll1 = chan->roll1;
406     pchan->roll2 = chan->roll2;
407     pchan->ease1 = chan->ease1;
408     pchan->ease2 = chan->ease2;
409     pchan->scaleIn = chan->scaleIn;
410     pchan->scaleOut = chan->scaleOut;
411
412     /* paste flipped pose? */
413     if (flip) {
414       pchan->loc[0] *= -1;
415
416       pchan->curveInX *= -1;
417       pchan->curveOutX *= -1;
418       pchan->roll1 *= -1;  // XXX?
419       pchan->roll2 *= -1;  // XXX?
420
421       /* has to be done as eulers... */
422       if (pchan->rotmode > 0) {
423         pchan->eul[1] *= -1;
424         pchan->eul[2] *= -1;
425       }
426       else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
427         float eul[3];
428
429         axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
430         eul[1] *= -1;
431         eul[2] *= -1;
432         eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
433       }
434       else {
435         float eul[3];
436
437         normalize_qt(pchan->quat);
438         quat_to_eul(eul, pchan->quat);
439         eul[1] *= -1;
440         eul[2] *= -1;
441         eul_to_quat(pchan->quat, eul);
442       }
443     }
444
445     /* ID properties */
446     if (chan->prop) {
447       if (pchan->prop) {
448         /* if we have existing properties on a bone, just copy over the values of
449          * matching properties (i.e. ones which will have some impact) on to the
450          * target instead of just blinding replacing all [
451          */
452         IDP_SyncGroupValues(pchan->prop, chan->prop);
453       }
454       else {
455         /* no existing properties, so assume that we want copies too? */
456         pchan->prop = IDP_CopyProperty(chan->prop);
457       }
458     }
459   }
460
461   /* return whether paste went ahead */
462   return pchan;
463 }
464
465 /* ---- */
466
467 static int pose_copy_exec(bContext *C, wmOperator *op)
468 {
469   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
470   char str[FILE_MAX];
471   /* Sanity checking. */
472   if (ELEM(NULL, ob, ob->pose)) {
473     BKE_report(op->reports, RPT_ERROR, "No pose to copy");
474     return OPERATOR_CANCELLED;
475   }
476   /* Sets chan->flag to POSE_KEY if bone selected. */
477   set_pose_keys(ob);
478   /* Construct a local bmain and only put object and it's data into it,
479    * o this way we don't expand any other objects into the copy buffer
480    * file.
481    *
482    * TODO(sergey): Find an easier way to tell copy buffer to only store
483    * data we are actually interested in. Maybe pass it a flag to skip
484    * any datablock expansion?
485    */
486   Main *temp_bmain = BKE_main_new();
487   Object ob_copy = *ob;
488   bArmature arm_copy = *((bArmature *)ob->data);
489   ob_copy.data = &arm_copy;
490   BLI_addtail(&temp_bmain->objects, &ob_copy);
491   BLI_addtail(&temp_bmain->armatures, &arm_copy);
492   /* begin copy buffer on a temp bmain. */
493   BKE_copybuffer_begin(temp_bmain);
494   /* Store the whole object to the copy buffer because pose can't be
495    * existing on it's own.
496    */
497   BKE_copybuffer_tag_ID(&ob_copy.id);
498   BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer_pose.blend");
499   BKE_copybuffer_save(temp_bmain, str, op->reports);
500   /* We clear the lists so no datablocks gets freed,
501    * This is required because objects in temp bmain shares same pointers
502    * as the real ones.
503    */
504   BLI_listbase_clear(&temp_bmain->objects);
505   BLI_listbase_clear(&temp_bmain->armatures);
506   BKE_main_free(temp_bmain);
507   /* We are all done! */
508   BKE_report(op->reports, RPT_INFO, "Copied pose to buffer");
509   return OPERATOR_FINISHED;
510 }
511
512 void POSE_OT_copy(wmOperatorType *ot)
513 {
514   /* identifiers */
515   ot->name = "Copy Pose";
516   ot->idname = "POSE_OT_copy";
517   ot->description = "Copies the current pose of the selected bones to copy/paste buffer";
518
519   /* api callbacks */
520   ot->exec = pose_copy_exec;
521   ot->poll = ED_operator_posemode;
522
523   /* flag */
524   ot->flag = OPTYPE_REGISTER;
525 }
526
527 /* ---- */
528
529 static int pose_paste_exec(bContext *C, wmOperator *op)
530 {
531   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
532   Scene *scene = CTX_data_scene(C);
533   bPoseChannel *chan;
534   const bool flip = RNA_boolean_get(op->ptr, "flipped");
535   bool selOnly = RNA_boolean_get(op->ptr, "selected_mask");
536
537   /* Get KeyingSet to use. */
538   KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
539
540   /* Sanity checks. */
541   if (ELEM(NULL, ob, ob->pose)) {
542     return OPERATOR_CANCELLED;
543   }
544
545   /* Read copy buffer .blend file. */
546   char str[FILE_MAX];
547   Main *tmp_bmain = BKE_main_new();
548   BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer_pose.blend");
549   if (!BKE_copybuffer_read(tmp_bmain, str, op->reports, FILTER_ID_OB)) {
550     BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
551     BKE_main_free(tmp_bmain);
552     return OPERATOR_CANCELLED;
553   }
554   /* Make sure data from this file is usable for pose paste. */
555   if (BLI_listbase_count_at_most(&tmp_bmain->objects, 2) != 1) {
556     BKE_report(op->reports, RPT_ERROR, "Copy buffer is not from pose mode");
557     BKE_main_free(tmp_bmain);
558     return OPERATOR_CANCELLED;
559   }
560
561   Object *object_from = tmp_bmain->objects.first;
562   bPose *pose_from = object_from->pose;
563   if (pose_from == NULL) {
564     BKE_report(op->reports, RPT_ERROR, "Copy buffer has no pose");
565     BKE_main_free(tmp_bmain);
566     return OPERATOR_CANCELLED;
567   }
568
569   /* If selOnly option is enabled, if user hasn't selected any bones,
570    * just go back to default behavior to be more in line with other
571    * pose tools.
572    */
573   if (selOnly) {
574     if (CTX_DATA_COUNT(C, selected_pose_bones) == 0) {
575       selOnly = false;
576     }
577   }
578
579   /* Safely merge all of the channels in the buffer pose into any
580    * existing pose.
581    */
582   for (chan = pose_from->chanbase.first; chan; chan = chan->next) {
583     if (chan->flag & POSE_KEY) {
584       /* Try to perform paste on this bone. */
585       bPoseChannel *pchan = pose_bone_do_paste(ob, chan, selOnly, flip);
586       if (pchan != NULL) {
587         /* Keyframing tagging for successful paste, */
588         ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
589       }
590     }
591   }
592   BKE_main_free(tmp_bmain);
593
594   /* Update event for pose and deformation children. */
595   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
596
597   /* Recalculate paths if any of the bones have paths... */
598   if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
599     ED_pose_recalculate_paths(C, scene, ob, false);
600   }
601
602   /* Notifiers for updates, */
603   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
604
605   return OPERATOR_FINISHED;
606 }
607
608 void POSE_OT_paste(wmOperatorType *ot)
609 {
610   PropertyRNA *prop;
611
612   /* identifiers */
613   ot->name = "Paste Pose";
614   ot->idname = "POSE_OT_paste";
615   ot->description = "Paste the stored pose on to the current pose";
616
617   /* api callbacks */
618   ot->exec = pose_paste_exec;
619   ot->poll = ED_operator_posemode;
620
621   /* flag */
622   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
623
624   /* properties */
625   prop = RNA_def_boolean(ot->srna,
626                          "flipped",
627                          false,
628                          "Flipped on X-Axis",
629                          "Paste the stored pose flipped on to current pose");
630   RNA_def_property_flag(prop, PROP_SKIP_SAVE);
631
632   RNA_def_boolean(ot->srna,
633                   "selected_mask",
634                   false,
635                   "On Selected Only",
636                   "Only paste the stored pose on to selected bones in the current pose");
637 }
638
639 /* ********************************************** */
640 /* Clear Pose Transforms */
641
642 /* clear scale of pose-channel */
643 static void pchan_clear_scale(bPoseChannel *pchan)
644 {
645   if ((pchan->protectflag & OB_LOCK_SCALEX) == 0) {
646     pchan->size[0] = 1.0f;
647   }
648   if ((pchan->protectflag & OB_LOCK_SCALEY) == 0) {
649     pchan->size[1] = 1.0f;
650   }
651   if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0) {
652     pchan->size[2] = 1.0f;
653   }
654
655   pchan->ease1 = 0.0f;
656   pchan->ease2 = 0.0f;
657   pchan->scaleIn = 1.0f;
658   pchan->scaleOut = 1.0f;
659 }
660
661 /* clear location of pose-channel */
662 static void pchan_clear_loc(bPoseChannel *pchan)
663 {
664   if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
665     pchan->loc[0] = 0.0f;
666   }
667   if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
668     pchan->loc[1] = 0.0f;
669   }
670   if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
671     pchan->loc[2] = 0.0f;
672   }
673 }
674
675 /* clear rotation of pose-channel */
676 static void pchan_clear_rot(bPoseChannel *pchan)
677 {
678   if (pchan->protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) {
679     /* check if convert to eulers for locking... */
680     if (pchan->protectflag & OB_LOCK_ROT4D) {
681       /* perform clamping on a component by component basis */
682       if (pchan->rotmode == ROT_MODE_AXISANGLE) {
683         if ((pchan->protectflag & OB_LOCK_ROTW) == 0) {
684           pchan->rotAngle = 0.0f;
685         }
686         if ((pchan->protectflag & OB_LOCK_ROTX) == 0) {
687           pchan->rotAxis[0] = 0.0f;
688         }
689         if ((pchan->protectflag & OB_LOCK_ROTY) == 0) {
690           pchan->rotAxis[1] = 0.0f;
691         }
692         if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) {
693           pchan->rotAxis[2] = 0.0f;
694         }
695
696         /* check validity of axis - axis should never be 0,0,0
697          * (if so, then we make it rotate about y). */
698         if (IS_EQF(pchan->rotAxis[0], pchan->rotAxis[1]) &&
699             IS_EQF(pchan->rotAxis[1], pchan->rotAxis[2])) {
700           pchan->rotAxis[1] = 1.0f;
701         }
702       }
703       else if (pchan->rotmode == ROT_MODE_QUAT) {
704         if ((pchan->protectflag & OB_LOCK_ROTW) == 0) {
705           pchan->quat[0] = 1.0f;
706         }
707         if ((pchan->protectflag & OB_LOCK_ROTX) == 0) {
708           pchan->quat[1] = 0.0f;
709         }
710         if ((pchan->protectflag & OB_LOCK_ROTY) == 0) {
711           pchan->quat[2] = 0.0f;
712         }
713         if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) {
714           pchan->quat[3] = 0.0f;
715         }
716       }
717       else {
718         /* the flag may have been set for the other modes, so just ignore the extra flag... */
719         if ((pchan->protectflag & OB_LOCK_ROTX) == 0) {
720           pchan->eul[0] = 0.0f;
721         }
722         if ((pchan->protectflag & OB_LOCK_ROTY) == 0) {
723           pchan->eul[1] = 0.0f;
724         }
725         if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) {
726           pchan->eul[2] = 0.0f;
727         }
728       }
729     }
730     else {
731       /* perform clamping using euler form (3-components) */
732       float eul[3], oldeul[3], quat1[4] = {0};
733       float qlen = 0.0f;
734
735       if (pchan->rotmode == ROT_MODE_QUAT) {
736         qlen = normalize_qt_qt(quat1, pchan->quat);
737         quat_to_eul(oldeul, quat1);
738       }
739       else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
740         axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
741       }
742       else {
743         copy_v3_v3(oldeul, pchan->eul);
744       }
745
746       eul[0] = eul[1] = eul[2] = 0.0f;
747
748       if (pchan->protectflag & OB_LOCK_ROTX) {
749         eul[0] = oldeul[0];
750       }
751       if (pchan->protectflag & OB_LOCK_ROTY) {
752         eul[1] = oldeul[1];
753       }
754       if (pchan->protectflag & OB_LOCK_ROTZ) {
755         eul[2] = oldeul[2];
756       }
757
758       if (pchan->rotmode == ROT_MODE_QUAT) {
759         eul_to_quat(pchan->quat, eul);
760
761         /* restore original quat size */
762         mul_qt_fl(pchan->quat, qlen);
763
764         /* quaternions flip w sign to accumulate rotations correctly */
765         if ((quat1[0] < 0.0f && pchan->quat[0] > 0.0f) ||
766             (quat1[0] > 0.0f && pchan->quat[0] < 0.0f)) {
767           mul_qt_fl(pchan->quat, -1.0f);
768         }
769       }
770       else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
771         eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
772       }
773       else {
774         copy_v3_v3(pchan->eul, eul);
775       }
776     }
777   } /* Duplicated in source/blender/editors/object/object_transform.c */
778   else {
779     if (pchan->rotmode == ROT_MODE_QUAT) {
780       unit_qt(pchan->quat);
781     }
782     else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
783       /* by default, make rotation of 0 radians around y-axis (roll) */
784       unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
785     }
786     else {
787       zero_v3(pchan->eul);
788     }
789   }
790
791   /* Clear also Bendy Bone stuff - Roll is obvious,
792    * but Curve X/Y stuff is also kindof rotational in nature... */
793   pchan->roll1 = 0.0f;
794   pchan->roll2 = 0.0f;
795
796   pchan->curveInX = 0.0f;
797   pchan->curveInY = 0.0f;
798   pchan->curveOutX = 0.0f;
799   pchan->curveOutY = 0.0f;
800 }
801
802 /* clear loc/rot/scale of pose-channel */
803 static void pchan_clear_transforms(bPoseChannel *pchan)
804 {
805   pchan_clear_loc(pchan);
806   pchan_clear_rot(pchan);
807   pchan_clear_scale(pchan);
808 }
809
810 /* --------------- */
811
812 /* generic exec for clear-pose operators */
813 static int pose_clear_transform_generic_exec(bContext *C,
814                                              wmOperator *op,
815                                              void (*clear_func)(bPoseChannel *),
816                                              const char default_ksName[])
817 {
818   Scene *scene = CTX_data_scene(C);
819   bool changed_multi = false;
820
821   /* sanity checks */
822   if (ELEM(NULL, clear_func, default_ksName)) {
823     BKE_report(op->reports,
824                RPT_ERROR,
825                "Programming error: missing clear transform function or keying set name");
826     return OPERATOR_CANCELLED;
827   }
828
829   /* only clear relevant transforms for selected bones */
830   ViewLayer *view_layer = CTX_data_view_layer(C);
831   View3D *v3d = CTX_wm_view3d(C);
832   FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
833     Object *ob_eval = DEG_get_evaluated_object(
834         CTX_data_depsgraph(C), ob_iter);  // XXX: UGLY HACK (for autokey + clear transforms)
835     ListBase dsources = {NULL, NULL};
836     bool changed = false;
837
838     FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
839       /* run provided clearing function */
840       clear_func(pchan);
841       changed = true;
842
843       /* do auto-keyframing as appropriate */
844       if (autokeyframe_cfra_can_key(scene, &ob_iter->id)) {
845         /* clear any unkeyed tags */
846         if (pchan->bone) {
847           pchan->bone->flag &= ~BONE_UNKEYED;
848         }
849         /* tag for autokeying later */
850         ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan);
851
852 #if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
853         bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
854         clear_func(pchan_eval);
855 #endif
856       }
857       else {
858         /* add unkeyed tags */
859         if (pchan->bone) {
860           pchan->bone->flag |= BONE_UNKEYED;
861         }
862       }
863     }
864     FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
865
866     if (changed) {
867       changed_multi = true;
868
869       /* perform autokeying on the bones if needed */
870       if (!BLI_listbase_is_empty(&dsources)) {
871         /* get KeyingSet to use */
872         KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
873
874         /* insert keyframes */
875         ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
876
877         /* now recalculate paths */
878         if ((ob_iter->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
879           ED_pose_recalculate_paths(C, scene, ob_iter, false);
880         }
881
882         BLI_freelistN(&dsources);
883       }
884
885       DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
886
887       /* note, notifier might evolve */
888       WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob_iter);
889     }
890   }
891   FOREACH_OBJECT_IN_MODE_END;
892
893   return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
894 }
895
896 /* --------------- */
897
898 static int pose_clear_scale_exec(bContext *C, wmOperator *op)
899 {
900   return pose_clear_transform_generic_exec(C, op, pchan_clear_scale, ANIM_KS_SCALING_ID);
901 }
902
903 void POSE_OT_scale_clear(wmOperatorType *ot)
904 {
905   /* identifiers */
906   ot->name = "Clear Pose Scale";
907   ot->idname = "POSE_OT_scale_clear";
908   ot->description = "Reset scaling of selected bones to their default values";
909
910   /* api callbacks */
911   ot->exec = pose_clear_scale_exec;
912   ot->poll = ED_operator_posemode;
913
914   /* flags */
915   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
916 }
917
918 static int pose_clear_rot_exec(bContext *C, wmOperator *op)
919 {
920   return pose_clear_transform_generic_exec(C, op, pchan_clear_rot, ANIM_KS_ROTATION_ID);
921 }
922
923 void POSE_OT_rot_clear(wmOperatorType *ot)
924 {
925   /* identifiers */
926   ot->name = "Clear Pose Rotation";
927   ot->idname = "POSE_OT_rot_clear";
928   ot->description = "Reset rotations of selected bones to their default values";
929
930   /* api callbacks */
931   ot->exec = pose_clear_rot_exec;
932   ot->poll = ED_operator_posemode;
933
934   /* flags */
935   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
936 }
937
938 static int pose_clear_loc_exec(bContext *C, wmOperator *op)
939 {
940   return pose_clear_transform_generic_exec(C, op, pchan_clear_loc, ANIM_KS_LOCATION_ID);
941 }
942
943 void POSE_OT_loc_clear(wmOperatorType *ot)
944 {
945   /* identifiers */
946   ot->name = "Clear Pose Location";
947   ot->idname = "POSE_OT_loc_clear";
948   ot->description = "Reset locations of selected bones to their default values";
949
950   /* api callbacks */
951   ot->exec = pose_clear_loc_exec;
952   ot->poll = ED_operator_posemode;
953
954   /* flags */
955   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
956 }
957
958 static int pose_clear_transforms_exec(bContext *C, wmOperator *op)
959 {
960   return pose_clear_transform_generic_exec(
961       C, op, pchan_clear_transforms, ANIM_KS_LOC_ROT_SCALE_ID);
962 }
963
964 void POSE_OT_transforms_clear(wmOperatorType *ot)
965 {
966   /* identifiers */
967   ot->name = "Clear Pose Transforms";
968   ot->idname = "POSE_OT_transforms_clear";
969   ot->description =
970       "Reset location, rotation, and scaling of selected bones to their default values";
971
972   /* api callbacks */
973   ot->exec = pose_clear_transforms_exec;
974   ot->poll = ED_operator_posemode;
975
976   /* flags */
977   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
978 }
979
980 /* ********************************************** */
981 /* Clear User Transforms */
982
983 static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
984 {
985   ViewLayer *view_layer = CTX_data_view_layer(C);
986   View3D *v3d = CTX_wm_view3d(C);
987   Scene *scene = CTX_data_scene(C);
988   float cframe = (float)CFRA;
989   const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
990
991   FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
992     if ((ob->adt) && (ob->adt->action)) {
993       /* XXX: this is just like this to avoid contaminating anything else;
994        * just pose values should change, so this should be fine
995        */
996       bPose *dummyPose = NULL;
997       Object workob = {{NULL}};
998       bPoseChannel *pchan;
999
1000       /* execute animation step for current frame using a dummy copy of the pose */
1001       BKE_pose_copy_data(&dummyPose, ob->pose, 0);
1002
1003       BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name));
1004       workob.type = OB_ARMATURE;
1005       workob.data = ob->data;
1006       workob.adt = ob->adt;
1007       workob.pose = dummyPose;
1008
1009       BKE_animsys_evaluate_animdata(NULL, scene, &workob.id, workob.adt, cframe, ADT_RECALC_ANIM);
1010
1011       /* copy back values, but on selected bones only  */
1012       for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
1013         pose_bone_do_paste(ob, pchan, only_select, 0);
1014       }
1015
1016       /* free temp data - free manually as was copied without constraints */
1017       for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
1018         if (pchan->prop) {
1019           IDP_FreeProperty(pchan->prop);
1020           MEM_freeN(pchan->prop);
1021         }
1022       }
1023
1024       /* was copied without constraints */
1025       BLI_freelistN(&dummyPose->chanbase);
1026       MEM_freeN(dummyPose);
1027     }
1028     else {
1029       /* no animation, so just reset whole pose to rest pose
1030        * (cannot just restore for selected though)
1031        */
1032       BKE_pose_rest(ob->pose);
1033     }
1034
1035     /* notifiers and updates */
1036     DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1037     WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
1038   }
1039   FOREACH_OBJECT_IN_MODE_END;
1040
1041   return OPERATOR_FINISHED;
1042 }
1043
1044 void POSE_OT_user_transforms_clear(wmOperatorType *ot)
1045 {
1046   /* identifiers */
1047   ot->name = "Clear User Transforms";
1048   ot->idname = "POSE_OT_user_transforms_clear";
1049   ot->description = "Reset pose on selected bones to keyframed state";
1050
1051   /* callbacks */
1052   ot->exec = pose_clear_user_transforms_exec;
1053   ot->poll = ED_operator_posemode;
1054
1055   /* flags */
1056   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1057
1058   /* properties */
1059   RNA_def_boolean(ot->srna, "only_selected", true, "Only Selected", "Only visible/selected bones");
1060 }