Cleanup: style, use braces for editors
[blender.git] / source / blender / editors / armature / pose_edit.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  * Pose Mode API's and Operators for Pose Mode armatures
19  */
20
21 /** \file
22  * \ingroup edarmature
23  */
24
25 #include "MEM_guardedalloc.h"
26
27 #include "BLI_math.h"
28 #include "BLI_blenlib.h"
29
30 #include "DNA_anim_types.h"
31 #include "DNA_armature_types.h"
32 #include "DNA_scene_types.h"
33 #include "DNA_object_types.h"
34
35 #include "BKE_action.h"
36 #include "BKE_anim.h"
37 #include "BKE_armature.h"
38 #include "BKE_context.h"
39 #include "BKE_deform.h"
40 #include "BKE_global.h"
41 #include "BKE_main.h"
42 #include "BKE_object.h"
43 #include "BKE_report.h"
44 #include "BKE_layer.h"
45 #include "BKE_scene.h"
46
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_query.h"
49
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 #include "RNA_enum_types.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "ED_anim_api.h"
58 #include "ED_armature.h"
59 #include "ED_keyframing.h"
60 #include "ED_screen.h"
61 #include "ED_object.h"
62 #include "ED_view3d.h"
63
64 #include "UI_interface.h"
65
66 #include "armature_intern.h"
67
68 #define DEBUG_TIME
69
70 #include "PIL_time.h"
71 #ifdef DEBUG_TIME
72 #  include "PIL_time_utildefines.h"
73 #endif
74
75 /* matches logic with ED_operator_posemode_context() */
76 Object *ED_pose_object_from_context(bContext *C)
77 {
78   ScrArea *sa = CTX_wm_area(C);
79   Object *ob;
80
81   /* Since this call may also be used from the buttons window,
82    * we need to check for where to get the object. */
83   if (sa && sa->spacetype == SPACE_PROPERTIES) {
84     ob = ED_object_context(C);
85   }
86   else {
87     ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
88   }
89
90   return ob;
91 }
92
93 /* This function is used to process the necessary updates for */
94 bool ED_object_posemode_enter_ex(struct Main *bmain, Object *ob)
95 {
96   BLI_assert(!ID_IS_LINKED(ob));
97   bool ok = false;
98
99   switch (ob->type) {
100     case OB_ARMATURE:
101       ob->restore_mode = ob->mode;
102       ob->mode |= OB_MODE_POSE;
103       /* Inform all CoW versions that we changed the mode. */
104       DEG_id_tag_update_ex(bmain, &ob->id, ID_RECALC_COPY_ON_WRITE);
105       ok = true;
106
107       break;
108     default:
109       break;
110   }
111
112   return ok;
113 }
114 bool ED_object_posemode_enter(bContext *C, Object *ob)
115 {
116   ReportList *reports = CTX_wm_reports(C);
117   if (ID_IS_LINKED(ob)) {
118     BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
119     return false;
120   }
121   struct Main *bmain = CTX_data_main(C);
122   bool ok = ED_object_posemode_enter_ex(bmain, ob);
123   if (ok) {
124     WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
125   }
126   return ok;
127 }
128
129 bool ED_object_posemode_exit_ex(struct Main *bmain, Object *ob)
130 {
131   bool ok = false;
132   if (ob) {
133     ob->restore_mode = ob->mode;
134     ob->mode &= ~OB_MODE_POSE;
135
136     /* Inform all CoW versions that we changed the mode. */
137     DEG_id_tag_update_ex(bmain, &ob->id, ID_RECALC_COPY_ON_WRITE);
138     ok = true;
139   }
140   return ok;
141 }
142 bool ED_object_posemode_exit(bContext *C, Object *ob)
143 {
144   struct Main *bmain = CTX_data_main(C);
145   bool ok = ED_object_posemode_exit_ex(bmain, ob);
146   if (ok) {
147     WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
148   }
149   return ok;
150 }
151
152 /* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
153 /* only_selected == 1: the active bone is allowed to be protected */
154 #if 0 /* UNUSED 2.5 */
155 static bool pose_has_protected_selected(Object *ob, short warn)
156 {
157   /* check protection */
158   if (ob->proxy) {
159     bPoseChannel *pchan;
160     bArmature *arm = ob->data;
161
162     for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
163       if (pchan->bone && (pchan->bone->layer & arm->layer)) {
164         if (pchan->bone->layer & arm->layer_protected) {
165           if (pchan->bone->flag & BONE_SELECTED)
166             break;
167         }
168       }
169     }
170     if (pchan) {
171       if (warn)
172         error("Cannot change Proxy protected bones");
173       return 1;
174     }
175   }
176   return 0;
177 }
178 #endif
179
180 /* ********************************************** */
181 /* Motion Paths */
182
183 /* For the object with pose/action: update paths for those that have got them
184  * This should selectively update paths that exist...
185  *
186  * To be called from various tools that do incremental updates
187  */
188 void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, bool current_frame_only)
189 {
190   /* Transform doesn't always have context available to do update. */
191   if (C == NULL) {
192     return;
193   }
194
195   Main *bmain = CTX_data_main(C);
196   Depsgraph *depsgraph = CTX_data_depsgraph(C);
197   ListBase targets = {NULL, NULL};
198   bool free_depsgraph = false;
199
200   /* Override depsgraph with a filtered, simpler copy */
201   if (!current_frame_only && G.debug_value != -1) {
202     DEG_FilterQuery query = {{0}};
203
204     DEG_FilterTarget *dft_ob = MEM_callocN(sizeof(DEG_FilterTarget), "DEG_FilterTarget");
205     dft_ob->id = &ob->id;
206     BLI_addtail(&query.targets, dft_ob);
207
208 #ifdef DEBUG_TIME
209     TIMEIT_START(filter_pose_depsgraph);
210 #endif
211
212     depsgraph = DEG_graph_filter(depsgraph, bmain, &query);
213
214 #ifdef DEBUG_TIME
215     TIMEIT_END(filter_pose_depsgraph);
216 #endif
217
218     free_depsgraph = true;
219     MEM_freeN(dft_ob);
220
221 #ifdef DEBUG_TIME
222     TIMEIT_START(filter_pose_update);
223 #endif
224
225     BKE_scene_graph_update_tagged(depsgraph, bmain);
226
227 #ifdef DEBUG_TIME
228     TIMEIT_END(filter_pose_update);
229 #endif
230   }
231
232   /* set flag to force recalc, then grab the relevant bones to target */
233   ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
234   animviz_get_object_motionpaths(ob, &targets);
235
236   /* recalculate paths, then free */
237 #ifdef DEBUG_TIME
238   TIMEIT_START(pose_path_calc);
239 #endif
240
241   animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, !free_depsgraph, current_frame_only);
242
243 #ifdef DEBUG_TIME
244   TIMEIT_END(pose_path_calc);
245 #endif
246
247   BLI_freelistN(&targets);
248
249   if (!current_frame_only) {
250     /* Tag armature object for copy on write - so paths will draw/redraw.
251      * For currently frame only we update evaluated object directly. */
252     DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
253   }
254
255   /* Free temporary depsgraph instance */
256   if (free_depsgraph) {
257     DEG_graph_free(depsgraph);
258   }
259 }
260
261 /* show popup to determine settings */
262 static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
263 {
264   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
265
266   if (ELEM(NULL, ob, ob->pose)) {
267     return OPERATOR_CANCELLED;
268   }
269
270   /* set default settings from existing/stored settings */
271   {
272     bAnimVizSettings *avs = &ob->pose->avs;
273     PointerRNA avs_ptr;
274
275     RNA_int_set(op->ptr, "start_frame", avs->path_sf);
276     RNA_int_set(op->ptr, "end_frame", avs->path_ef);
277
278     RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
279     RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
280   }
281
282   /* show popup dialog to allow editing of range... */
283   // FIXME: hardcoded dimensions here are just arbitrary
284   return WM_operator_props_dialog_popup(C, op, 200, 200);
285 }
286
287 /* For the object with pose/action: create path curves for selected bones
288  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
289  */
290 static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
291 {
292   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
293   Scene *scene = CTX_data_scene(C);
294
295   if (ELEM(NULL, ob, ob->pose)) {
296     return OPERATOR_CANCELLED;
297   }
298
299   /* grab baking settings from operator settings */
300   {
301     bAnimVizSettings *avs = &ob->pose->avs;
302     PointerRNA avs_ptr;
303
304     avs->path_sf = RNA_int_get(op->ptr, "start_frame");
305     avs->path_ef = RNA_int_get(op->ptr, "end_frame");
306
307     RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
308     RNA_enum_set(&avs_ptr, "bake_location", RNA_enum_get(op->ptr, "bake_location"));
309   }
310
311   /* set up path data for bones being calculated */
312   CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones_from_active_object) {
313     /* verify makes sure that the selected bone has a bone with the appropriate settings */
314     animviz_verify_motionpaths(op->reports, scene, ob, pchan);
315   }
316   CTX_DATA_END;
317
318 #ifdef DEBUG_TIME
319   TIMEIT_START(recalc_pose_paths);
320 #endif
321
322   /* calculate the bones that now have motionpaths... */
323   /* TODO: only make for the selected bones? */
324   ED_pose_recalculate_paths(C, scene, ob, false);
325
326 #ifdef DEBUG_TIME
327   TIMEIT_END(recalc_pose_paths);
328 #endif
329
330   /* notifiers for updates */
331   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
332
333   return OPERATOR_FINISHED;
334 }
335
336 void POSE_OT_paths_calculate(wmOperatorType *ot)
337 {
338   /* identifiers */
339   ot->name = "Calculate Bone Paths";
340   ot->idname = "POSE_OT_paths_calculate";
341   ot->description = "Calculate paths for the selected bones";
342
343   /* api callbacks */
344   ot->invoke = pose_calculate_paths_invoke;
345   ot->exec = pose_calculate_paths_exec;
346   ot->poll = ED_operator_posemode_exclusive;
347
348   /* flags */
349   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
350
351   /* properties */
352   RNA_def_int(ot->srna,
353               "start_frame",
354               1,
355               MINAFRAME,
356               MAXFRAME,
357               "Start",
358               "First frame to calculate bone paths on",
359               MINFRAME,
360               MAXFRAME / 2.0);
361   RNA_def_int(ot->srna,
362               "end_frame",
363               250,
364               MINAFRAME,
365               MAXFRAME,
366               "End",
367               "Last frame to calculate bone paths on",
368               MINFRAME,
369               MAXFRAME / 2.0);
370
371   RNA_def_enum(ot->srna,
372                "bake_location",
373                rna_enum_motionpath_bake_location_items,
374                MOTIONPATH_BAKE_HEADS,
375                "Bake Location",
376                "Which point on the bones is used when calculating paths");
377 }
378
379 /* --------- */
380
381 static bool pose_update_paths_poll(bContext *C)
382 {
383   if (ED_operator_posemode_exclusive(C)) {
384     Object *ob = CTX_data_active_object(C);
385     return (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
386   }
387
388   return false;
389 }
390
391 static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
392 {
393   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
394   Scene *scene = CTX_data_scene(C);
395
396   if (ELEM(NULL, ob, scene)) {
397     return OPERATOR_CANCELLED;
398   }
399
400   /* calculate the bones that now have motionpaths... */
401   /* TODO: only make for the selected bones? */
402   ED_pose_recalculate_paths(C, scene, ob, false);
403
404   /* notifiers for updates */
405   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
406
407   return OPERATOR_FINISHED;
408 }
409
410 void POSE_OT_paths_update(wmOperatorType *ot)
411 {
412   /* identifiers */
413   ot->name = "Update Bone Paths";
414   ot->idname = "POSE_OT_paths_update";
415   ot->description = "Recalculate paths for bones that already have them";
416
417   /* api callbakcs */
418   ot->exec = pose_update_paths_exec;
419   ot->poll = pose_update_paths_poll;
420
421   /* flags */
422   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
423 }
424
425 /* --------- */
426
427 /* for the object with pose/action: clear path curves for selected bones only */
428 static void ED_pose_clear_paths(Object *ob, bool only_selected)
429 {
430   bPoseChannel *pchan;
431   bool skipped = false;
432
433   if (ELEM(NULL, ob, ob->pose)) {
434     return;
435   }
436
437   /* free the motionpath blocks for all bones - This is easier for users to quickly clear all */
438   for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
439     if (pchan->mpath) {
440       if ((only_selected == false) || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) {
441         animviz_free_motionpath(pchan->mpath);
442         pchan->mpath = NULL;
443       }
444       else {
445         skipped = true;
446       }
447     }
448   }
449
450   /* if nothing was skipped, there should be no paths left! */
451   if (skipped == false) {
452     ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
453   }
454
455   /* tag armature object for copy on write - so removed paths don't still show */
456   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
457 }
458
459 /* operator callback - wrapper for the backend function  */
460 static int pose_clear_paths_exec(bContext *C, wmOperator *op)
461 {
462   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
463   bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
464
465   /* only continue if there's an object */
466   if (ELEM(NULL, ob, ob->pose)) {
467     return OPERATOR_CANCELLED;
468   }
469
470   /* use the backend function for this */
471   ED_pose_clear_paths(ob, only_selected);
472
473   /* notifiers for updates */
474   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
475
476   return OPERATOR_FINISHED;
477 }
478
479 /* operator callback/wrapper */
480 static int pose_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
481 {
482   if ((evt->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) {
483     RNA_boolean_set(op->ptr, "only_selected", true);
484   }
485   return pose_clear_paths_exec(C, op);
486 }
487
488 void POSE_OT_paths_clear(wmOperatorType *ot)
489 {
490   /* identifiers */
491   ot->name = "Clear Bone Paths";
492   ot->idname = "POSE_OT_paths_clear";
493   ot->description = "Clear path caches for all bones, hold Shift key for selected bones only";
494
495   /* api callbacks */
496   ot->invoke = pose_clear_paths_invoke;
497   ot->exec = pose_clear_paths_exec;
498   ot->poll = ED_operator_posemode_exclusive;
499
500   /* flags */
501   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
502
503   /* properties */
504   ot->prop = RNA_def_boolean(
505       ot->srna, "only_selected", false, "Only Selected", "Only clear paths from selected bones");
506   RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
507 }
508
509 /* --------- */
510
511 static int pose_update_paths_range_exec(bContext *C, wmOperator *UNUSED(op))
512 {
513   Scene *scene = CTX_data_scene(C);
514   Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
515
516   if (ELEM(NULL, scene, ob, ob->pose)) {
517     return OPERATOR_CANCELLED;
518   }
519
520   /* use Preview Range or Full Frame Range - whichever is in use */
521   ob->pose->avs.path_sf = PSFRA;
522   ob->pose->avs.path_ef = PEFRA;
523
524   /* tag for updates */
525   DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
526   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
527
528   return OPERATOR_FINISHED;
529 }
530
531 void POSE_OT_paths_range_update(wmOperatorType *ot)
532 {
533   /* identifiers */
534   ot->name = "Update Range from Scene";
535   ot->idname = "POSE_OT_paths_range_update";
536   ot->description = "Update frame range for motion paths from the Scene's current frame range";
537
538   /* callbacks */
539   ot->exec = pose_update_paths_range_exec;
540   ot->poll = ED_operator_posemode_exclusive;
541
542   /* flags */
543   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
544 }
545
546 /* ********************************************** */
547
548 static int pose_flip_names_exec(bContext *C, wmOperator *op)
549 {
550   Main *bmain = CTX_data_main(C);
551   ViewLayer *view_layer = CTX_data_view_layer(C);
552   View3D *v3d = CTX_wm_view3d(C);
553   const bool do_strip_numbers = RNA_boolean_get(op->ptr, "do_strip_numbers");
554
555   FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
556     bArmature *arm = ob->data;
557     ListBase bones_names = {NULL};
558
559     FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob, pchan) {
560       BLI_addtail(&bones_names, BLI_genericNodeN(pchan->name));
561     }
562     FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
563
564     ED_armature_bones_flip_names(bmain, arm, &bones_names, do_strip_numbers);
565
566     BLI_freelistN(&bones_names);
567
568     /* since we renamed stuff... */
569     DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
570
571     /* note, notifier might evolve */
572     WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
573   }
574   FOREACH_OBJECT_IN_MODE_END;
575
576   return OPERATOR_FINISHED;
577 }
578
579 void POSE_OT_flip_names(wmOperatorType *ot)
580 {
581   /* identifiers */
582   ot->name = "Flip Names";
583   ot->idname = "POSE_OT_flip_names";
584   ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
585
586   /* api callbacks */
587   ot->exec = pose_flip_names_exec;
588   ot->poll = ED_operator_posemode_local;
589
590   /* flags */
591   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
592
593   RNA_def_boolean(ot->srna,
594                   "do_strip_numbers",
595                   false,
596                   "Strip Numbers",
597                   "Try to remove right-most dot-number from flipped names "
598                   "(WARNING: may result in incoherent naming in some cases)");
599 }
600
601 /* ------------------ */
602
603 static int pose_autoside_names_exec(bContext *C, wmOperator *op)
604 {
605   Main *bmain = CTX_data_main(C);
606   char newname[MAXBONENAME];
607   short axis = RNA_enum_get(op->ptr, "axis");
608   Object *ob_prev = NULL;
609
610   /* loop through selected bones, auto-naming them */
611   CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
612     bArmature *arm = ob->data;
613     BLI_strncpy(newname, pchan->name, sizeof(newname));
614     if (bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis])) {
615       ED_armature_bone_rename(bmain, arm, pchan->name, newname);
616     }
617
618     if (ob_prev != ob) {
619       /* since we renamed stuff... */
620       DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
621
622       /* note, notifier might evolve */
623       WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
624       ob_prev = ob;
625     }
626   }
627   CTX_DATA_END;
628
629   return OPERATOR_FINISHED;
630 }
631
632 void POSE_OT_autoside_names(wmOperatorType *ot)
633 {
634   static const EnumPropertyItem axis_items[] = {
635       {0, "XAXIS", 0, "X-Axis", "Left/Right"},
636       {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
637       {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
638       {0, NULL, 0, NULL, NULL},
639   };
640
641   /* identifiers */
642   ot->name = "AutoName by Axis";
643   ot->idname = "POSE_OT_autoside_names";
644   ot->description =
645       "Automatically renames the selected bones according to which side of the target axis they "
646       "fall on";
647
648   /* api callbacks */
649   ot->invoke = WM_menu_invoke;
650   ot->exec = pose_autoside_names_exec;
651   ot->poll = ED_operator_posemode;
652
653   /* flags */
654   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
655
656   /* settings */
657   ot->prop = RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with");
658 }
659
660 /* ********************************************** */
661
662 static int pose_bone_rotmode_exec(bContext *C, wmOperator *op)
663 {
664   const int mode = RNA_enum_get(op->ptr, "type");
665   Object *prev_ob = NULL;
666
667   /* set rotation mode of selected bones  */
668   CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
669     pchan->rotmode = mode;
670
671     if (prev_ob != ob) {
672       /* Notifiers and updates. */
673       DEG_id_tag_update((ID *)ob, ID_RECALC_GEOMETRY);
674       WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
675       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
676       prev_ob = ob;
677     }
678   }
679   CTX_DATA_END;
680
681   return OPERATOR_FINISHED;
682 }
683
684 void POSE_OT_rotation_mode_set(wmOperatorType *ot)
685 {
686   /* identifiers */
687   ot->name = "Set Rotation Mode";
688   ot->idname = "POSE_OT_rotation_mode_set";
689   ot->description = "Set the rotation representation used by selected bones";
690
691   /* callbacks */
692   ot->invoke = WM_menu_invoke;
693   ot->exec = pose_bone_rotmode_exec;
694   ot->poll = ED_operator_posemode;
695
696   /* flags */
697   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
698
699   /* properties */
700   ot->prop = RNA_def_enum(
701       ot->srna, "type", rna_enum_object_rotation_mode_items, 0, "Rotation Mode", "");
702 }
703
704 /* ********************************************** */
705
706 static bool armature_layers_poll(bContext *C)
707 {
708   /* Armature layers operators can be used in posemode OR editmode for armatures */
709   return ED_operator_posemode(C) || ED_operator_editarmature(C);
710 }
711
712 static bArmature *armature_layers_get_data(Object **ob)
713 {
714   bArmature *arm = NULL;
715
716   /* Sanity checking and handling of posemode. */
717   if (*ob) {
718     Object *tob = BKE_object_pose_armature_get(*ob);
719     if (tob) {
720       *ob = tob;
721       arm = (*ob)->data;
722     }
723     else if ((*ob)->type == OB_ARMATURE) {
724       arm = (*ob)->data;
725     }
726   }
727
728   return arm;
729 }
730
731 /* Show all armature layers */
732
733 static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
734 {
735   Object *ob = CTX_data_active_object(C);
736   bArmature *arm = armature_layers_get_data(&ob);
737   PointerRNA ptr;
738   int maxLayers = (RNA_boolean_get(op->ptr, "all")) ? 32 : 16;
739   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
740   bool layers[32] = {false};
741   int i;
742
743   /* sanity checking */
744   if (arm == NULL) {
745     return OPERATOR_CANCELLED;
746   }
747
748   /* use RNA to set the layers
749    * although it would be faster to just set directly using bitflags, we still
750    * need to setup a RNA pointer so that we get the "update" callbacks for free...
751    */
752   RNA_id_pointer_create(&arm->id, &ptr);
753
754   for (i = 0; i < maxLayers; i++) {
755     layers[i] = 1;
756   }
757
758   RNA_boolean_set_array(&ptr, "layers", layers);
759
760   /* note, notifier might evolve */
761   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
762   DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
763
764   /* done */
765   return OPERATOR_FINISHED;
766 }
767
768 void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
769 {
770   /* identifiers */
771   ot->name = "Show All Layers";
772   ot->idname = "ARMATURE_OT_layers_show_all";
773   ot->description = "Make all armature layers visible";
774
775   /* callbacks */
776   ot->exec = pose_armature_layers_showall_exec;
777   ot->poll = armature_layers_poll;
778
779   /* flags */
780   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
781
782   /* properties */
783   ot->prop = RNA_def_boolean(
784       ot->srna, "all", 1, "All Layers", "Enable all layers or just the first 16 (top row)");
785 }
786
787 /* ------------------- */
788
789 /* Present a popup to get the layers that should be used */
790 static int armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
791 {
792   Object *ob = CTX_data_active_object(C);
793   bArmature *arm = armature_layers_get_data(&ob);
794   PointerRNA ptr;
795   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
796   bool layers[32];
797
798   /* sanity checking */
799   if (arm == NULL) {
800     return OPERATOR_CANCELLED;
801   }
802
803   /* Get RNA pointer to armature data to use that to retrieve the layers as ints
804    * to init the operator. */
805   RNA_id_pointer_create((ID *)arm, &ptr);
806   RNA_boolean_get_array(&ptr, "layers", layers);
807   RNA_boolean_set_array(op->ptr, "layers", layers);
808
809   /* part to sync with other similar operators... */
810   return WM_operator_props_popup(C, op, event);
811 }
812
813 /* Set the visible layers for the active armature (edit and pose modes) */
814 static int armature_layers_exec(bContext *C, wmOperator *op)
815 {
816   Object *ob = CTX_data_active_object(C);
817   bArmature *arm = armature_layers_get_data(&ob);
818   PointerRNA ptr;
819   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
820   bool layers[32];
821
822   if (arm == NULL) {
823     return OPERATOR_CANCELLED;
824   }
825
826   /* get the values set in the operator properties */
827   RNA_boolean_get_array(op->ptr, "layers", layers);
828
829   /* get pointer for armature, and write data there... */
830   RNA_id_pointer_create((ID *)arm, &ptr);
831   RNA_boolean_set_array(&ptr, "layers", layers);
832
833   /* note, notifier might evolve */
834   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
835   DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
836
837   return OPERATOR_FINISHED;
838 }
839
840 void ARMATURE_OT_armature_layers(wmOperatorType *ot)
841 {
842   /* identifiers */
843   ot->name = "Change Armature Layers";
844   ot->idname = "ARMATURE_OT_armature_layers";
845   ot->description = "Change the visible armature layers";
846
847   /* callbacks */
848   ot->invoke = armature_layers_invoke;
849   ot->exec = armature_layers_exec;
850   ot->poll = armature_layers_poll;
851
852   /* flags */
853   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
854
855   /* properties */
856   RNA_def_boolean_layer_member(
857       ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
858 }
859
860 /* ------------------- */
861
862 /* Present a popup to get the layers that should be used */
863 static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
864 {
865   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
866   bool layers[32] = {0};
867
868   /* get layers that are active already */
869   CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) {
870     short bit;
871
872     /* loop over the bits for this pchan's layers, adding layers where they're needed */
873     for (bit = 0; bit < 32; bit++) {
874       layers[bit] = (pchan->bone->layer & (1u << bit)) != 0;
875     }
876   }
877   CTX_DATA_END;
878
879   /* copy layers to operator */
880   RNA_boolean_set_array(op->ptr, "layers", layers);
881
882   /* part to sync with other similar operators... */
883   return WM_operator_props_popup(C, op, event);
884 }
885
886 /* Set the visible layers for the active armature (edit and pose modes) */
887 static int pose_bone_layers_exec(bContext *C, wmOperator *op)
888 {
889   PointerRNA ptr;
890   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
891   bool layers[32];
892
893   /* get the values set in the operator properties */
894   RNA_boolean_get_array(op->ptr, "layers", layers);
895
896   Object *prev_ob = NULL;
897
898   /* set layers of pchans based on the values set in the operator props */
899   CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
900     /* get pointer for pchan, and write flags this way */
901     RNA_pointer_create((ID *)ob->data, &RNA_Bone, pchan->bone, &ptr);
902     RNA_boolean_set_array(&ptr, "layers", layers);
903
904     if (prev_ob != ob) {
905       /* Note, notifier might evolve. */
906       WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
907       DEG_id_tag_update((ID *)ob->data, ID_RECALC_COPY_ON_WRITE);
908       prev_ob = ob;
909     }
910   }
911   CTX_DATA_END;
912   return OPERATOR_FINISHED;
913 }
914
915 void POSE_OT_bone_layers(wmOperatorType *ot)
916 {
917   /* identifiers */
918   ot->name = "Change Bone Layers";
919   ot->idname = "POSE_OT_bone_layers";
920   ot->description = "Change the layers that the selected bones belong to";
921
922   /* callbacks */
923   ot->invoke = pose_bone_layers_invoke;
924   ot->exec = pose_bone_layers_exec;
925   ot->poll = ED_operator_posemode_exclusive;
926
927   /* flags */
928   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
929
930   /* properties */
931   RNA_def_boolean_layer_member(
932       ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
933 }
934
935 /* ------------------- */
936
937 /* Present a popup to get the layers that should be used */
938 static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
939 {
940   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
941   bool layers[32] = {0};
942
943   /* get layers that are active already */
944   CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) {
945     short bit;
946
947     /* loop over the bits for this pchan's layers, adding layers where they're needed */
948     for (bit = 0; bit < 32; bit++) {
949       if (ebone->layer & (1u << bit)) {
950         layers[bit] = 1;
951       }
952     }
953   }
954   CTX_DATA_END;
955
956   /* copy layers to operator */
957   RNA_boolean_set_array(op->ptr, "layers", layers);
958
959   /* part to sync with other similar operators... */
960   return WM_operator_props_popup(C, op, event);
961 }
962
963 /* Set the visible layers for the active armature (edit and pose modes) */
964 static int armature_bone_layers_exec(bContext *C, wmOperator *op)
965 {
966   Object *ob = CTX_data_edit_object(C);
967   PointerRNA ptr;
968   /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
969   bool layers[32];
970
971   /* get the values set in the operator properties */
972   RNA_boolean_get_array(op->ptr, "layers", layers);
973
974   /* set layers of pchans based on the values set in the operator props */
975   CTX_DATA_BEGIN_WITH_ID (C, EditBone *, ebone, selected_editable_bones, bArmature *, arm) {
976     /* get pointer for pchan, and write flags this way */
977     RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr);
978     RNA_boolean_set_array(&ptr, "layers", layers);
979   }
980   CTX_DATA_END;
981
982   /* note, notifier might evolve */
983   WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
984
985   return OPERATOR_FINISHED;
986 }
987
988 void ARMATURE_OT_bone_layers(wmOperatorType *ot)
989 {
990   /* identifiers */
991   ot->name = "Change Bone Layers";
992   ot->idname = "ARMATURE_OT_bone_layers";
993   ot->description = "Change the layers that the selected bones belong to";
994
995   /* callbacks */
996   ot->invoke = armature_bone_layers_invoke;
997   ot->exec = armature_bone_layers_exec;
998   ot->poll = ED_operator_editarmature;
999
1000   /* flags */
1001   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1002
1003   /* properties */
1004   RNA_def_boolean_layer_member(
1005       ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
1006 }
1007
1008 /* ********************************************** */
1009 /* Show/Hide Bones */
1010
1011 static int hide_pose_bone_fn(Object *ob, Bone *bone, void *ptr)
1012 {
1013   bArmature *arm = ob->data;
1014   const bool hide_select = (bool)POINTER_AS_INT(ptr);
1015   int count = 0;
1016   if (arm->layer & bone->layer) {
1017     if (((bone->flag & BONE_SELECTED) != 0) == hide_select) {
1018       bone->flag |= BONE_HIDDEN_P;
1019       /* only needed when 'hide_select' is true, but harmless. */
1020       bone->flag &= ~BONE_SELECTED;
1021       if (arm->act_bone == bone) {
1022         arm->act_bone = NULL;
1023       }
1024       count += 1;
1025     }
1026   }
1027   return count;
1028 }
1029
1030 /* active object is armature in posemode, poll checked */
1031 static int pose_hide_exec(bContext *C, wmOperator *op)
1032 {
1033   ViewLayer *view_layer = CTX_data_view_layer(C);
1034   uint objects_len;
1035   Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
1036   bool changed_multi = false;
1037
1038   const int hide_select = !RNA_boolean_get(op->ptr, "unselected");
1039   void *hide_select_p = POINTER_FROM_INT(hide_select);
1040
1041   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1042     Object *ob_iter = objects[ob_index];
1043     bArmature *arm = ob_iter->data;
1044
1045     if (ob_iter->proxy != NULL) {
1046       BKE_report(op->reports, RPT_INFO, "Undo of hiding can only be done with Reveal Selected");
1047     }
1048
1049     bool changed = bone_looper(ob_iter, arm->bonebase.first, hide_select_p, hide_pose_bone_fn) !=
1050                    0;
1051     if (changed) {
1052       changed_multi = true;
1053       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob_iter);
1054       DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
1055     }
1056   }
1057   MEM_freeN(objects);
1058
1059   return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1060 }
1061
1062 void POSE_OT_hide(wmOperatorType *ot)
1063 {
1064   /* identifiers */
1065   ot->name = "Hide Selected";
1066   ot->idname = "POSE_OT_hide";
1067   ot->description = "Tag selected bones to not be visible in Pose Mode";
1068
1069   /* api callbacks */
1070   ot->exec = pose_hide_exec;
1071   ot->poll = ED_operator_posemode;
1072
1073   /* flags */
1074   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1075
1076   /* props */
1077   RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "");
1078 }
1079
1080 static int show_pose_bone_cb(Object *ob, Bone *bone, void *data)
1081 {
1082   const bool select = POINTER_AS_INT(data);
1083
1084   bArmature *arm = ob->data;
1085   int count = 0;
1086   if (arm->layer & bone->layer) {
1087     if (bone->flag & BONE_HIDDEN_P) {
1088       if (!(bone->flag & BONE_UNSELECTABLE)) {
1089         SET_FLAG_FROM_TEST(bone->flag, select, BONE_SELECTED);
1090       }
1091       bone->flag &= ~BONE_HIDDEN_P;
1092       count += 1;
1093     }
1094   }
1095
1096   return count;
1097 }
1098
1099 /* active object is armature in posemode, poll checked */
1100 static int pose_reveal_exec(bContext *C, wmOperator *op)
1101 {
1102   ViewLayer *view_layer = CTX_data_view_layer(C);
1103   uint objects_len;
1104   Object **objects = BKE_object_pose_array_get_unique(view_layer, CTX_wm_view3d(C), &objects_len);
1105   bool changed_multi = false;
1106   const bool select = RNA_boolean_get(op->ptr, "select");
1107   void *select_p = POINTER_FROM_INT(select);
1108
1109   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1110     Object *ob_iter = objects[ob_index];
1111     bArmature *arm = ob_iter->data;
1112
1113     bool changed = bone_looper(ob_iter, arm->bonebase.first, select_p, show_pose_bone_cb);
1114     if (changed) {
1115       changed_multi = true;
1116       WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob_iter);
1117       DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
1118     }
1119   }
1120   MEM_freeN(objects);
1121
1122   return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1123 }
1124
1125 void POSE_OT_reveal(wmOperatorType *ot)
1126 {
1127   /* identifiers */
1128   ot->name = "Reveal Selected";
1129   ot->idname = "POSE_OT_reveal";
1130   ot->description = "Reveal all bones hidden in Pose Mode";
1131
1132   /* api callbacks */
1133   ot->exec = pose_reveal_exec;
1134   ot->poll = ED_operator_posemode;
1135
1136   /* flags */
1137   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1138
1139   RNA_def_boolean(ot->srna, "select", true, "Select", "");
1140 }
1141
1142 /* ********************************************** */
1143 /* Flip Quats */
1144
1145 static int pose_flip_quats_exec(bContext *C, wmOperator *UNUSED(op))
1146 {
1147   Scene *scene = CTX_data_scene(C);
1148   KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
1149
1150   bool changed_multi = false;
1151
1152   ViewLayer *view_layer = CTX_data_view_layer(C);
1153   View3D *v3d = CTX_wm_view3d(C);
1154   FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) {
1155     bool changed = false;
1156     /* loop through all selected pchans, flipping and keying (as needed) */
1157     FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
1158       /* only if bone is using quaternion rotation */
1159       if (pchan->rotmode == ROT_MODE_QUAT) {
1160         changed = true;
1161         /* quaternions have 720 degree range */
1162         negate_v4(pchan->quat);
1163
1164         ED_autokeyframe_pchan(C, scene, ob_iter, pchan, ks);
1165       }
1166     }
1167     FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
1168
1169     if (changed) {
1170       changed_multi = true;
1171       /* notifiers and updates */
1172       DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
1173       WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob_iter);
1174     }
1175   }
1176   FOREACH_OBJECT_IN_MODE_END;
1177
1178   return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1179 }
1180
1181 void POSE_OT_quaternions_flip(wmOperatorType *ot)
1182 {
1183   /* identifiers */
1184   ot->name = "Flip Quats";
1185   ot->idname = "POSE_OT_quaternions_flip";
1186   ot->description =
1187       "Flip quaternion values to achieve desired rotations, while maintaining the same "
1188       "orientations";
1189
1190   /* callbacks */
1191   ot->exec = pose_flip_quats_exec;
1192   ot->poll = ED_operator_posemode;
1193
1194   /* flags */
1195   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1196 }