uv_texture_atlas/bake to vcols: moved to contrib: update class names: T63750
[blender-addons-contrib.git] / amaranth / animation / motion_paths.py
1 #  This program is free software; you can redistribute it and/or
2 #  modify it under the terms of the GNU General Public License
3 #  as published by the Free Software Foundation; either version 2
4 #  of the License, or (at your option) any later version.
5 #
6 #  This program is distributed in the hope that it will be useful,
7 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
8 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9 #  GNU General Public License for more details.
10 #
11 #  You should have received a copy of the GNU General Public License
12 #  along with this program; if not, write to the Free Software Foundation,
13 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 """
15 Bone Motion Paths:
16
17 Match Frame Range + Clear All Paths
18
19 * Clear All Paths:
20 Silly operator to loop through all bones and clear their paths, useful
21 when having hidden bones (othrewise you have to go through each one of
22 them and clear manually)
23
24 *Match Current Frame Range:
25 Set the current frame range as motion path range.
26
27 Both requests by Hjalti from Project Pampa
28 Thanks to Bassam Kurdali for helping finding out the weirdness behind
29 Motion Paths bpy.
30
31 Developed during Caminandes Open Movie Project
32 """
33
34 import bpy
35
36
37 class AMTH_POSE_OT_paths_clear_all(bpy.types.Operator):
38
39     """Clear motion paths from all bones"""
40     bl_idname = "pose.paths_clear_all"
41     bl_label = "Clear All Motion Paths"
42     bl_options = {"UNDO"}
43
44     @classmethod
45     def poll(cls, context):
46         return context.mode == "POSE"
47
48     def execute(self, context):
49         # silly but works
50         for b in context.object.data.bones:
51             b.select = True
52             bpy.ops.pose.paths_clear()
53             b.select = False
54         return {"FINISHED"}
55
56
57 class AMTH_POSE_OT_paths_frame_match(bpy.types.Operator):
58
59     """Match Start/End frame of scene to motion path range"""
60     bl_idname = "pose.paths_frame_match"
61     bl_label = "Match Frame Range"
62     bl_options = {"UNDO"}
63
64     def execute(self, context):
65         avs = context.object.pose.animation_visualization
66         scene = context.scene
67
68         if avs.motion_path.type == "RANGE":
69             if scene.use_preview_range:
70                 avs.motion_path.frame_start = scene.frame_preview_start
71                 avs.motion_path.frame_end = scene.frame_preview_end
72             else:
73                 avs.motion_path.frame_start = scene.frame_start
74                 avs.motion_path.frame_end = scene.frame_end
75
76         else:
77             if scene.use_preview_range:
78                 avs.motion_path.frame_before = scene.frame_preview_start
79                 avs.motion_path.frame_after = scene.frame_preview_end
80             else:
81                 avs.motion_path.frame_before = scene.frame_start
82                 avs.motion_path.frame_after = scene.frame_end
83
84         return {"FINISHED"}
85
86
87 def pose_motion_paths_ui(self, context):
88
89     layout = self.layout
90     scene = context.scene
91     avs = context.object.pose.animation_visualization
92     if context.active_pose_bone:
93         mpath = context.active_pose_bone.motion_path
94     layout.separator()
95     layout.label(text="Motion Paths Extras:")
96
97     split = layout.split()
98
99     col = split.column(align=True)
100
101     if context.selected_pose_bones:
102         if mpath:
103             sub = col.row(align=True)
104             sub.operator(
105                 "pose.paths_update", text="Update Path", icon="BONE_DATA")
106             sub.operator("pose.paths_clear", text="", icon="X")
107         else:
108             col.operator(
109                 "pose.paths_calculate",
110                 text="Calculate Path",
111                 icon="BONE_DATA")
112     else:
113         col.label(text="Select Bones First", icon="ERROR")
114
115     col = split.column(align=True)
116     col.operator(
117         AMTH_POSE_OT_paths_frame_match.bl_idname,
118         text="Set Preview Frame Range" if scene.use_preview_range else "Set Frame Range",
119         icon="PREVIEW_RANGE" if scene.use_preview_range else "TIME")
120
121     col = layout.column()
122     row = col.row(align=True)
123
124     if avs.motion_path.type == "RANGE":
125         row.prop(avs.motion_path, "frame_start", text="Start")
126         row.prop(avs.motion_path, "frame_end", text="End")
127     else:
128         row.prop(avs.motion_path, "frame_before", text="Before")
129         row.prop(avs.motion_path, "frame_after", text="After")
130
131     layout.separator()
132     layout.operator(AMTH_POSE_OT_paths_clear_all.bl_idname, icon="X")
133
134
135 def register():
136     bpy.utils.register_class(AMTH_POSE_OT_paths_clear_all)
137     bpy.utils.register_class(AMTH_POSE_OT_paths_frame_match)
138     bpy.types.DATA_PT_display.append(pose_motion_paths_ui)
139
140
141 def unregister():
142     bpy.utils.unregister_class(AMTH_POSE_OT_paths_clear_all)
143     bpy.utils.unregister_class(AMTH_POSE_OT_paths_frame_match)
144     bpy.types.DATA_PT_display.remove(pose_motion_paths_ui)