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