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