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