Merge branch 'blender2.7' of git.blender.org:blender
[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 /* ********************************************** */
66 /* Pose Apply */
67
68 /* helper for apply_armature_pose2bones - fixes parenting of objects
69  * that are bone-parented to armature */
70 static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Object *armob)
71 {
72         Depsgraph *depsgraph = CTX_data_depsgraph(C);
73         Main *bmain = CTX_data_main(C);
74         Object workob, *ob;
75
76         /* go through all objects in database */
77         for (ob = bmain->objects.first; ob; ob = ob->id.next) {
78                 /* if parent is bone in this armature, apply corrections */
79                 if ((ob->parent == armob) && (ob->partype == PARBONE)) {
80                         /* apply current transform from parent (not yet destroyed),
81                          * then calculate new parent inverse matrix
82                          */
83                         BKE_object_apply_mat4(ob, ob->obmat, false, false);
84
85                         BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob);
86                         invert_m4_m4(ob->parentinv, workob.obmat);
87                 }
88         }
89 }
90
91 /* set the current pose as the restpose */
92 static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op)
93 {
94         Main *bmain = CTX_data_main(C);
95         Depsgraph *depsgraph = CTX_data_depsgraph(C);
96         Scene *scene = CTX_data_scene(C);
97         // must be active object, not edit-object
98         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
99         const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
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");
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                 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
226 /* set the current pose as the restpose */
227 static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op))
228 {
229         ViewLayer *view_layer = CTX_data_view_layer(C);
230         View3D *v3d = CTX_wm_view3d(C);
231         Depsgraph *depsgraph = CTX_data_depsgraph(C);
232
233         FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob)
234         {
235                 /* loop over all selected pchans
236                  *
237                  * TODO, loop over children before parents if multiple bones
238                  * at once are to be predictable*/
239                 FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan)
240                 {
241                         const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
242                         bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
243                         float delta_mat[4][4];
244
245                         /* chan_mat already contains the delta transform from rest pose to pose-mode pose
246                          * as that is baked into there so that B-Bones will work. Once we've set this as the
247                          * new raw-transform components, don't recalc the poses yet, otherwise IK result will
248                          * change, thus changing the result we may be trying to record.
249                          */
250                         /* XXX For some reason, we can't use pchan->chan_mat here, gives odd rotation/offset (see T38251).
251                          *     Using pchan->pose_mat and bringing it back in bone space seems to work as expected!
252                          */
253                         BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, delta_mat);
254
255                         BKE_pchan_apply_mat4(pchan, delta_mat, true);
256                 }
257                 FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
258
259                 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
260
261                 /* note, notifier might evolve */
262                 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
263         }
264         FOREACH_OBJECT_IN_MODE_END;
265
266         return OPERATOR_FINISHED;
267 }
268
269 void POSE_OT_visual_transform_apply(wmOperatorType *ot)
270 {
271         /* identifiers */
272         ot->name = "Apply Visual Transform to Pose";
273         ot->idname = "POSE_OT_visual_transform_apply";
274         ot->description = "Apply final constrained position of pose bones to their transform";
275
276         /* callbacks */
277         ot->exec = pose_visual_transform_apply_exec;
278         ot->poll = ED_operator_posemode;
279
280         /* flags */
281         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
282 }
283
284 /* ********************************************** */
285 /* Copy/Paste */
286
287 /* This function is used to indicate that a bone is selected
288  * and needs to be included in copy buffer (used to be for inserting keys)
289  */
290 static void set_pose_keys(Object *ob)
291 {
292         bArmature *arm = ob->data;
293         bPoseChannel *chan;
294
295         if (ob->pose) {
296                 for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
297                         Bone *bone = chan->bone;
298                         if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
299                                 chan->flag |= POSE_KEY;
300                         else
301                                 chan->flag &= ~POSE_KEY;
302                 }
303         }
304 }
305
306 /**
307  * Perform paste pose, for a single bone.
308  *
309  * \param ob: Object where bone to paste to lives
310  * \param chan: Bone that pose to paste comes from
311  * \param selOnly: Only paste on selected bones
312  * \param flip: Flip on x-axis
313  * \return Whether the bone that we pasted to if we succeeded
314  */
315 static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bool selOnly, 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)) {
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, "flipped", false, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose");
610         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
611
612         RNA_def_boolean(ot->srna, "selected_mask", false, "On Selected Only", "Only paste the stored pose on to selected bones in the current pose");
613 }
614
615 /* ********************************************** */
616 /* Clear Pose Transforms */
617
618 /* clear scale of pose-channel */
619 static void pchan_clear_scale(bPoseChannel *pchan)
620 {
621         if ((pchan->protectflag & OB_LOCK_SCALEX) == 0)
622                 pchan->size[0] = 1.0f;
623         if ((pchan->protectflag & OB_LOCK_SCALEY) == 0)
624                 pchan->size[1] = 1.0f;
625         if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0)
626                 pchan->size[2] = 1.0f;
627
628         pchan->ease1 = 0.0f;
629         pchan->ease2 = 0.0f;
630         pchan->scaleIn = 1.0f;
631         pchan->scaleOut = 1.0f;
632 }
633
634 /* clear location of pose-channel */
635 static void pchan_clear_loc(bPoseChannel *pchan)
636 {
637         if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
638                 pchan->loc[0] = 0.0f;
639         if ((pchan->protectflag & OB_LOCK_LOCY) == 0)
640                 pchan->loc[1] = 0.0f;
641         if ((pchan->protectflag & OB_LOCK_LOCZ) == 0)
642                 pchan->loc[2] = 0.0f;
643 }
644
645 /* clear rotation of pose-channel */
646 static void pchan_clear_rot(bPoseChannel *pchan)
647 {
648         if (pchan->protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) {
649                 /* check if convert to eulers for locking... */
650                 if (pchan->protectflag & OB_LOCK_ROT4D) {
651                         /* perform clamping on a component by component basis */
652                         if (pchan->rotmode == ROT_MODE_AXISANGLE) {
653                                 if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
654                                         pchan->rotAngle = 0.0f;
655                                 if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
656                                         pchan->rotAxis[0] = 0.0f;
657                                 if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
658                                         pchan->rotAxis[1] = 0.0f;
659                                 if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
660                                         pchan->rotAxis[2] = 0.0f;
661
662                                 /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
663                                 if (IS_EQF(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQF(pchan->rotAxis[1], pchan->rotAxis[2]))
664                                         pchan->rotAxis[1] = 1.0f;
665                         }
666                         else if (pchan->rotmode == ROT_MODE_QUAT) {
667                                 if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
668                                         pchan->quat[0] = 1.0f;
669                                 if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
670                                         pchan->quat[1] = 0.0f;
671                                 if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
672                                         pchan->quat[2] = 0.0f;
673                                 if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
674                                         pchan->quat[3] = 0.0f;
675                         }
676                         else {
677                                 /* the flag may have been set for the other modes, so just ignore the extra flag... */
678                                 if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
679                                         pchan->eul[0] = 0.0f;
680                                 if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
681                                         pchan->eul[1] = 0.0f;
682                                 if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
683                                         pchan->eul[2] = 0.0f;
684                         }
685                 }
686                 else {
687                         /* perform clamping using euler form (3-components) */
688                         float eul[3], oldeul[3], quat1[4] = {0};
689                         float qlen = 0.0f;
690
691                         if (pchan->rotmode == ROT_MODE_QUAT) {
692                                 qlen = normalize_qt_qt(quat1, pchan->quat);
693                                 quat_to_eul(oldeul, quat1);
694                         }
695                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
696                                 axis_angle_to_eulO(oldeul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
697                         }
698                         else {
699                                 copy_v3_v3(oldeul, pchan->eul);
700                         }
701
702                         eul[0] = eul[1] = eul[2] = 0.0f;
703
704                         if (pchan->protectflag & OB_LOCK_ROTX)
705                                 eul[0] = oldeul[0];
706                         if (pchan->protectflag & OB_LOCK_ROTY)
707                                 eul[1] = oldeul[1];
708                         if (pchan->protectflag & OB_LOCK_ROTZ)
709                                 eul[2] = oldeul[2];
710
711                         if (pchan->rotmode == ROT_MODE_QUAT) {
712                                 eul_to_quat(pchan->quat, eul);
713
714                                 /* restore original quat size */
715                                 mul_qt_fl(pchan->quat, qlen);
716
717                                 /* quaternions flip w sign to accumulate rotations correctly */
718                                 if ((quat1[0] < 0.0f && pchan->quat[0] > 0.0f) || (quat1[0] > 0.0f && pchan->quat[0] < 0.0f)) {
719                                         mul_qt_fl(pchan->quat, -1.0f);
720                                 }
721                         }
722                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
723                                 eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
724                         }
725                         else {
726                                 copy_v3_v3(pchan->eul, eul);
727                         }
728                 }
729         }       /* Duplicated in source/blender/editors/object/object_transform.c */
730         else {
731                 if (pchan->rotmode == ROT_MODE_QUAT) {
732                         unit_qt(pchan->quat);
733                 }
734                 else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
735                         /* by default, make rotation of 0 radians around y-axis (roll) */
736                         unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
737                 }
738                 else {
739                         zero_v3(pchan->eul);
740                 }
741         }
742
743         /* Clear also Bendy Bone stuff - Roll is obvious,
744          * but Curve X/Y stuff is also kindof rotational in nature... */
745         pchan->roll1 = 0.0f;
746         pchan->roll2 = 0.0f;
747
748         pchan->curveInX = 0.0f;
749         pchan->curveInY = 0.0f;
750         pchan->curveOutX = 0.0f;
751         pchan->curveOutY = 0.0f;
752 }
753
754 /* clear loc/rot/scale of pose-channel */
755 static void pchan_clear_transforms(bPoseChannel *pchan)
756 {
757         pchan_clear_loc(pchan);
758         pchan_clear_rot(pchan);
759         pchan_clear_scale(pchan);
760 }
761
762 /* --------------- */
763
764 /* generic exec for clear-pose operators */
765 static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
766                                              void (*clear_func)(bPoseChannel *), const char default_ksName[])
767 {
768         Scene *scene = CTX_data_scene(C);
769         bool changed_multi = false;
770
771         /* sanity checks */
772         if (ELEM(NULL, clear_func, default_ksName)) {
773                 BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name");
774                 return OPERATOR_CANCELLED;
775         }
776
777         /* only clear relevant transforms for selected bones */
778         ViewLayer *view_layer = CTX_data_view_layer(C);
779         View3D *v3d = CTX_wm_view3d(C);
780         FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter)
781         {
782                 Object *ob_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), ob_iter); // XXX: UGLY HACK (for autokey + clear transforms)
783                 ListBase dsources = {NULL, NULL};
784                 bool changed = false;
785
786                 FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan)
787                 {
788                         /* run provided clearing function */
789                         clear_func(pchan);
790                         changed = true;
791
792                         /* do auto-keyframing as appropriate */
793                         if (autokeyframe_cfra_can_key(scene, &ob_iter->id)) {
794                                 /* clear any unkeyed tags */
795                                 if (pchan->bone) {
796                                         pchan->bone->flag &= ~BONE_UNKEYED;
797                                 }
798                                 /* tag for autokeying later */
799                                 ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan);
800
801 #if 1                   /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
802                                 bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
803                                 clear_func(pchan_eval);
804 #endif
805                         }
806                         else {
807                                 /* add unkeyed tags */
808                                 if (pchan->bone) {
809                                         pchan->bone->flag |= BONE_UNKEYED;
810                                 }
811                         }
812                 }
813                 FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
814
815                 if (changed) {
816                         changed_multi = true;
817
818                         /* perform autokeying on the bones if needed */
819                         if (!BLI_listbase_is_empty(&dsources)) {
820                                 /* get KeyingSet to use */
821                                 KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
822
823                                 /* insert keyframes */
824                                 ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
825
826                                 /* now recalculate paths */
827                                 if ((ob_iter->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
828                                         ED_pose_recalculate_paths(C, scene, ob_iter, false);
829                                 }
830
831                                 BLI_freelistN(&dsources);
832                         }
833
834                         DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
835
836                         /* note, notifier might evolve */
837                         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob_iter);
838                 }
839         }
840         FOREACH_OBJECT_IN_MODE_END;
841
842         return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
843 }
844
845 /* --------------- */
846
847 static int pose_clear_scale_exec(bContext *C, wmOperator *op)
848 {
849         return pose_clear_transform_generic_exec(C, op, pchan_clear_scale, ANIM_KS_SCALING_ID);
850 }
851
852 void POSE_OT_scale_clear(wmOperatorType *ot)
853 {
854         /* identifiers */
855         ot->name = "Clear Pose Scale";
856         ot->idname = "POSE_OT_scale_clear";
857         ot->description = "Reset scaling of selected bones to their default values";
858
859         /* api callbacks */
860         ot->exec = pose_clear_scale_exec;
861         ot->poll = ED_operator_posemode;
862
863         /* flags */
864         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
865 }
866
867
868 static int pose_clear_rot_exec(bContext *C, wmOperator *op)
869 {
870         return pose_clear_transform_generic_exec(C, op, pchan_clear_rot, ANIM_KS_ROTATION_ID);
871 }
872
873 void POSE_OT_rot_clear(wmOperatorType *ot)
874 {
875         /* identifiers */
876         ot->name = "Clear Pose Rotation";
877         ot->idname = "POSE_OT_rot_clear";
878         ot->description = "Reset rotations of selected bones to their default values";
879
880         /* api callbacks */
881         ot->exec = pose_clear_rot_exec;
882         ot->poll = ED_operator_posemode;
883
884         /* flags */
885         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
886 }
887
888
889 static int pose_clear_loc_exec(bContext *C, wmOperator *op)
890 {
891         return pose_clear_transform_generic_exec(C, op, pchan_clear_loc, ANIM_KS_LOCATION_ID);
892 }
893
894 void POSE_OT_loc_clear(wmOperatorType *ot)
895 {
896         /* identifiers */
897         ot->name = "Clear Pose Location";
898         ot->idname = "POSE_OT_loc_clear";
899         ot->description = "Reset locations of selected bones to their default values";
900
901         /* api callbacks */
902         ot->exec = pose_clear_loc_exec;
903         ot->poll = ED_operator_posemode;
904
905         /* flags */
906         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
907 }
908
909
910 static int pose_clear_transforms_exec(bContext *C, wmOperator *op)
911 {
912         return pose_clear_transform_generic_exec(C, op, pchan_clear_transforms, ANIM_KS_LOC_ROT_SCALE_ID);
913 }
914
915 void POSE_OT_transforms_clear(wmOperatorType *ot)
916 {
917         /* identifiers */
918         ot->name = "Clear Pose Transforms";
919         ot->idname = "POSE_OT_transforms_clear";
920         ot->description = "Reset location, rotation, and scaling of selected bones to their default values";
921
922         /* api callbacks */
923         ot->exec = pose_clear_transforms_exec;
924         ot->poll = ED_operator_posemode;
925
926         /* flags */
927         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
928 }
929
930 /* ********************************************** */
931 /* Clear User Transforms */
932
933 static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op)
934 {
935         ViewLayer *view_layer = CTX_data_view_layer(C);
936         View3D *v3d = CTX_wm_view3d(C);
937         Scene *scene = CTX_data_scene(C);
938         float cframe = (float)CFRA;
939         const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
940
941         FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob)
942         {
943                 if ((ob->adt) && (ob->adt->action)) {
944                         /* XXX: this is just like this to avoid contaminating anything else;
945                          * just pose values should change, so this should be fine
946                          */
947                         bPose *dummyPose = NULL;
948                         Object workob = {{NULL}};
949                         bPoseChannel *pchan;
950
951                         /* execute animation step for current frame using a dummy copy of the pose */
952                         BKE_pose_copy_data(&dummyPose, ob->pose, 0);
953
954                         BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name));
955                         workob.type = OB_ARMATURE;
956                         workob.data = ob->data;
957                         workob.adt = ob->adt;
958                         workob.pose = dummyPose;
959
960                         BKE_animsys_evaluate_animdata(NULL, scene, &workob.id, workob.adt, cframe, ADT_RECALC_ANIM);
961
962                         /* copy back values, but on selected bones only  */
963                         for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
964                                 pose_bone_do_paste(ob, pchan, only_select, 0);
965                         }
966
967                         /* free temp data - free manually as was copied without constraints */
968                         for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) {
969                                 if (pchan->prop) {
970                                         IDP_FreeProperty(pchan->prop);
971                                         MEM_freeN(pchan->prop);
972                                 }
973                         }
974
975                         /* was copied without constraints */
976                         BLI_freelistN(&dummyPose->chanbase);
977                         MEM_freeN(dummyPose);
978                 }
979                 else {
980                         /* no animation, so just reset whole pose to rest pose
981                          * (cannot just restore for selected though)
982                          */
983                         BKE_pose_rest(ob->pose);
984                 }
985
986                 /* notifiers and updates */
987                 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
988                 WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
989         }
990         FOREACH_OBJECT_IN_MODE_END;
991
992         return OPERATOR_FINISHED;
993 }
994
995 void POSE_OT_user_transforms_clear(wmOperatorType *ot)
996 {
997         /* identifiers */
998         ot->name = "Clear User Transforms";
999         ot->idname = "POSE_OT_user_transforms_clear";
1000         ot->description = "Reset pose on selected bones to keyframed state";
1001
1002         /* callbacks */
1003         ot->exec = pose_clear_user_transforms_exec;
1004         ot->poll = ED_operator_posemode;
1005
1006         /* flags */
1007         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1008
1009         /* properties */
1010         RNA_def_boolean(ot->srna, "only_selected", true, "Only Selected", "Only visible/selected bones");
1011 }