Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCansecoGPC <machaquiro@yahoo.es>2019-12-09 16:42:04 +0300
committerCansecoGPC <machaquiro@yahoo.es>2019-12-09 16:42:04 +0300
commit75af6e5dcf84cc2d2693374a01ecbad0f874701b (patch)
tree86d5ad098857a591e9f997881d762e839b33e98a /amaranth/animation
parent395ca8a4be7a66c72a5556c51f958644601a846b (diff)
Amaranth: Add back from addons contrib
Diffstat (limited to 'amaranth/animation')
-rw-r--r--amaranth/animation/__init__.py0
-rw-r--r--amaranth/animation/frame_current.py45
-rw-r--r--amaranth/animation/jump_frames.py209
-rw-r--r--amaranth/animation/motion_paths.py144
-rw-r--r--amaranth/animation/timeline_extra_info.py67
5 files changed, 465 insertions, 0 deletions
diff --git a/amaranth/animation/__init__.py b/amaranth/animation/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/amaranth/animation/__init__.py
diff --git a/amaranth/animation/frame_current.py b/amaranth/animation/frame_current.py
new file mode 100644
index 00000000..6bea2009
--- /dev/null
+++ b/amaranth/animation/frame_current.py
@@ -0,0 +1,45 @@
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+"""
+Current Frame Slider
+
+Currently the only way to change the current frame is to have a Timeline
+editor open, but sometimes you don't have one, or you're fullscreen.
+This option adds the Current Frame slider to the Specials menu. Find it
+hitting the W menu in Object mode, you can slide or click in the middle
+of the button to set the frame manually.
+"""
+
+import bpy
+
+
+def button_frame_current(self, context):
+ get_addon = "amaranth" in context.preferences.addons.keys()
+ if not get_addon:
+ return
+
+ scene = context.scene
+ if context.preferences.addons["amaranth"].preferences.use_frame_current:
+ self.layout.separator()
+ self.layout.prop(scene, "frame_current", text="Set Current Frame")
+
+
+def register():
+ bpy.types.VIEW3D_MT_object_context_menu.append(button_frame_current)
+ bpy.types.VIEW3D_MT_pose_context_menu.append(button_frame_current)
+
+
+def unregister():
+ bpy.types.VIEW3D_MT_object_context_menu.remove(button_frame_current)
+ bpy.types.VIEW3D_MT_pose_context_menu.remove(button_frame_current)
diff --git a/amaranth/animation/jump_frames.py b/amaranth/animation/jump_frames.py
new file mode 100644
index 00000000..fb12cb35
--- /dev/null
+++ b/amaranth/animation/jump_frames.py
@@ -0,0 +1,209 @@
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+"""
+Jump X Frames on Shift Up/Down
+
+When you hit Shift Up/Down, you'll jump 10 frames forward/backwards.
+Sometimes is nice to tweak that value.
+
+In the User Preferences, Editing tab, you'll find a "Frames to Jump"
+slider where you can adjust how many frames you'd like to move
+forwards/backwards.
+
+Make sure you save your user settings if you want to use this value from
+now on.
+
+Find it on the User Preferences, Editing.
+"""
+
+import bpy
+from bpy.types import Operator
+from bpy.props import BoolProperty
+
+KEYMAPS = list()
+
+
+# FUNCTION: Check if object has keyframes for a specific frame
+def is_keyframe(ob, frame):
+ if ob is not None and ob.animation_data is not None and ob.animation_data.action is not None:
+ for fcu in ob.animation_data.action.fcurves:
+ if frame in (p.co.x for p in fcu.keyframe_points):
+ return True
+ return False
+
+
+# monkey path is_keyframe function
+bpy.types.Object.is_keyframe = is_keyframe
+
+
+# FEATURE: Jump to frame in-between next and previous keyframe
+class AMTH_SCREEN_OT_keyframe_jump_inbetween(Operator):
+ """Jump to half in-between keyframes"""
+ bl_idname = "screen.amth_keyframe_jump_inbetween"
+ bl_label = "Jump to Keyframe In-between"
+
+ backwards: BoolProperty()
+
+ def execute(self, context):
+ back = self.backwards
+
+ scene = context.scene
+ ob = bpy.context.object
+ frame_start = scene.frame_start
+ frame_end = scene.frame_end
+
+ if not context.scene.get("amth_keyframes_jump"):
+ context.scene["amth_keyframes_jump"] = list()
+
+ keyframes_list = context.scene["amth_keyframes_jump"]
+
+ for f in range(frame_start, frame_end):
+ if ob.is_keyframe(f):
+ keyframes_list = list(keyframes_list)
+ keyframes_list.append(f)
+
+ if keyframes_list:
+ keyframes_list_half = []
+
+ for i, item in enumerate(keyframes_list):
+ try:
+ next_item = keyframes_list[i + 1]
+ keyframes_list_half.append(int((item + next_item) / 2))
+ except:
+ pass
+
+ if len(keyframes_list_half) > 1:
+ if back:
+ v = (scene.frame_current == keyframes_list_half[::-1][-1],
+ scene.frame_current < keyframes_list_half[::-1][-1])
+ if any(v):
+ self.report({"INFO"}, "No keyframes behind")
+ else:
+ for i in keyframes_list_half[::-1]:
+ if scene.frame_current > i:
+ scene.frame_current = i
+ break
+ else:
+ v = (scene.frame_current == keyframes_list_half[-1],
+ scene.frame_current > keyframes_list_half[-1])
+ if any(v):
+ self.report({"INFO"}, "No keyframes ahead")
+ else:
+ for i in keyframes_list_half:
+ if scene.frame_current < i:
+ scene.frame_current = i
+ break
+ else:
+ self.report({"INFO"}, "Object has only 1 keyframe")
+ else:
+ self.report({"INFO"}, "Object has no keyframes")
+
+ return {"FINISHED"}
+
+
+# FEATURE: Jump forward/backward every N frames
+class AMTH_SCREEN_OT_frame_jump(Operator):
+ """Jump a number of frames forward/backwards"""
+ bl_idname = "screen.amaranth_frame_jump"
+ bl_label = "Jump Frames"
+
+ forward: BoolProperty(default=True)
+
+ def execute(self, context):
+ scene = context.scene
+
+ get_addon = "amaranth" in context.preferences.addons.keys()
+ if not get_addon:
+ return {"CANCELLED"}
+
+ preferences = context.preferences.addons["amaranth"].preferences
+
+ if preferences.use_framerate:
+ framedelta = scene.render.fps
+ else:
+ framedelta = preferences.frames_jump
+ if self.forward:
+ scene.frame_current = scene.frame_current + framedelta
+ else:
+ scene.frame_current = scene.frame_current - framedelta
+
+ return {"FINISHED"}
+
+
+def ui_userpreferences_edit(self, context):
+ get_addon = "amaranth" in context.preferences.addons.keys()
+ if not get_addon:
+ return
+
+ preferences = context.preferences.addons["amaranth"].preferences
+
+ col = self.layout.column()
+ split = col.split(factor=0.21)
+ split.prop(preferences, "frames_jump",
+ text="Frames to Jump")
+
+
+def label(self, context):
+ get_addon = "amaranth" in context.preferences.addons.keys()
+ if not get_addon:
+ return
+
+ layout = self.layout
+
+ if context.preferences.addons["amaranth"].preferences.use_timeline_extra_info:
+ row = layout.row(align=True)
+
+ row.operator(AMTH_SCREEN_OT_keyframe_jump_inbetween.bl_idname,
+ icon="PREV_KEYFRAME", text="").backwards = True
+ row.operator(AMTH_SCREEN_OT_keyframe_jump_inbetween.bl_idname,
+ icon="NEXT_KEYFRAME", text="").backwards = False
+
+
+def register():
+ bpy.utils.register_class(AMTH_SCREEN_OT_frame_jump)
+ bpy.utils.register_class(AMTH_SCREEN_OT_keyframe_jump_inbetween)
+ bpy.types.USERPREF_PT_animation_timeline.append(ui_userpreferences_edit)
+ bpy.types.USERPREF_PT_animation_timeline.append(label)
+
+ # register keyboard shortcuts
+ wm = bpy.context.window_manager
+ kc = wm.keyconfigs.addon
+
+ km = kc.keymaps.new(name="Frames")
+ kmi = km.keymap_items.new('screen.amth_keyframe_jump_inbetween', 'UP_ARROW', 'PRESS', shift=True, ctrl=True)
+ kmi.properties.backwards = False
+ KEYMAPS.append((km, kmi))
+
+ kmi = km.keymap_items.new('screen.amth_keyframe_jump_inbetween', 'DOWN_ARROW', 'PRESS', shift=True, ctrl=True)
+ kmi.properties.backwards = True
+ KEYMAPS.append((km, kmi))
+
+ kmi = km.keymap_items.new(
+ "screen.amaranth_frame_jump", "UP_ARROW", "PRESS", shift=True)
+ kmi.properties.forward = True
+ KEYMAPS.append((km, kmi))
+
+ kmi = km.keymap_items.new(
+ "screen.amaranth_frame_jump", "DOWN_ARROW", "PRESS", shift=True)
+ kmi.properties.forward = False
+ KEYMAPS.append((km, kmi))
+
+
+def unregister():
+ bpy.utils.unregister_class(AMTH_SCREEN_OT_frame_jump)
+ bpy.utils.unregister_class(AMTH_SCREEN_OT_keyframe_jump_inbetween)
+ bpy.types.USERPREF_PT_animation_timeline.remove(ui_userpreferences_edit)
+ for km, kmi in KEYMAPS:
+ km.keymap_items.remove(kmi)
+ KEYMAPS.clear()
diff --git a/amaranth/animation/motion_paths.py b/amaranth/animation/motion_paths.py
new file mode 100644
index 00000000..7988b452
--- /dev/null
+++ b/amaranth/animation/motion_paths.py
@@ -0,0 +1,144 @@
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+"""
+Bone Motion Paths:
+
+Match Frame Range + Clear All Paths
+
+* Clear All Paths:
+Silly operator to loop through all bones and clear their paths, useful
+when having hidden bones (othrewise you have to go through each one of
+them and clear manually)
+
+*Match Current Frame Range:
+Set the current frame range as motion path range.
+
+Both requests by Hjalti from Project Pampa
+Thanks to Bassam Kurdali for helping finding out the weirdness behind
+Motion Paths bpy.
+
+Developed during Caminandes Open Movie Project
+"""
+
+import bpy
+
+
+class AMTH_POSE_OT_paths_clear_all(bpy.types.Operator):
+
+ """Clear motion paths from all bones"""
+ bl_idname = "pose.paths_clear_all"
+ bl_label = "Clear All Motion Paths"
+ bl_options = {"UNDO"}
+
+ @classmethod
+ def poll(cls, context):
+ return context.mode == "POSE"
+
+ def execute(self, context):
+ # silly but works
+ for b in context.object.data.bones:
+ b.select = True
+ bpy.ops.pose.paths_clear()
+ b.select = False
+ return {"FINISHED"}
+
+
+class AMTH_POSE_OT_paths_frame_match(bpy.types.Operator):
+
+ """Match Start/End frame of scene to motion path range"""
+ bl_idname = "pose.paths_frame_match"
+ bl_label = "Match Frame Range"
+ bl_options = {"UNDO"}
+
+ def execute(self, context):
+ avs = context.object.pose.animation_visualization
+ scene = context.scene
+
+ if avs.motion_path.type == "RANGE":
+ if scene.use_preview_range:
+ avs.motion_path.frame_start = scene.frame_preview_start
+ avs.motion_path.frame_end = scene.frame_preview_end
+ else:
+ avs.motion_path.frame_start = scene.frame_start
+ avs.motion_path.frame_end = scene.frame_end
+
+ else:
+ if scene.use_preview_range:
+ avs.motion_path.frame_before = scene.frame_preview_start
+ avs.motion_path.frame_after = scene.frame_preview_end
+ else:
+ avs.motion_path.frame_before = scene.frame_start
+ avs.motion_path.frame_after = scene.frame_end
+
+ return {"FINISHED"}
+
+
+def pose_motion_paths_ui(self, context):
+
+ layout = self.layout
+ scene = context.scene
+ avs = context.object.pose.animation_visualization
+ if context.active_pose_bone:
+ mpath = context.active_pose_bone.motion_path
+ layout.separator()
+ layout.label(text="Motion Paths Extras:")
+
+ split = layout.split()
+
+ col = split.column(align=True)
+
+ if context.selected_pose_bones:
+ if mpath:
+ sub = col.row(align=True)
+ sub.operator(
+ "pose.paths_update", text="Update Path", icon="BONE_DATA")
+ sub.operator("pose.paths_clear", text="", icon="X")
+ else:
+ col.operator(
+ "pose.paths_calculate",
+ text="Calculate Path",
+ icon="BONE_DATA")
+ else:
+ col.label(text="Select Bones First", icon="ERROR")
+
+ col = split.column(align=True)
+ col.operator(
+ AMTH_POSE_OT_paths_frame_match.bl_idname,
+ text="Set Preview Frame Range" if scene.use_preview_range else "Set Frame Range",
+ icon="PREVIEW_RANGE" if scene.use_preview_range else "TIME")
+
+ col = layout.column()
+ row = col.row(align=True)
+
+ if avs.motion_path.type == "RANGE":
+ row.prop(avs.motion_path, "frame_start", text="Start")
+ row.prop(avs.motion_path, "frame_end", text="End")
+ else:
+ row.prop(avs.motion_path, "frame_before", text="Before")
+ row.prop(avs.motion_path, "frame_after", text="After")
+
+ layout.separator()
+ layout.operator(AMTH_POSE_OT_paths_clear_all.bl_idname, icon="X")
+
+
+def register():
+ bpy.utils.register_class(AMTH_POSE_OT_paths_clear_all)
+ bpy.utils.register_class(AMTH_POSE_OT_paths_frame_match)
+ bpy.types.DATA_PT_display.append(pose_motion_paths_ui)
+
+
+def unregister():
+ bpy.utils.unregister_class(AMTH_POSE_OT_paths_clear_all)
+ bpy.utils.unregister_class(AMTH_POSE_OT_paths_frame_match)
+ bpy.types.DATA_PT_display.remove(pose_motion_paths_ui)
diff --git a/amaranth/animation/timeline_extra_info.py b/amaranth/animation/timeline_extra_info.py
new file mode 100644
index 00000000..0e875b43
--- /dev/null
+++ b/amaranth/animation/timeline_extra_info.py
@@ -0,0 +1,67 @@
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+"""
+Timeline Extra Info
+
+Display amount of frames left until Frame End, very handy especially when
+rendering an animation or OpenGL preview.
+Display current/end time on SMPTE. Find it on the Timeline header.
+"""
+
+import bpy
+
+
+def label_timeline_extra_info(self, context):
+ get_addon = "amaranth" in context.preferences.addons.keys()
+ if not get_addon:
+ return
+
+ layout = self.layout
+ scene = context.scene
+
+ if context.preferences.addons["amaranth"].preferences.use_timeline_extra_info:
+ row = layout.row(align=True)
+
+ # Check for preview range
+ frame_start = scene.frame_preview_start if scene.use_preview_range else scene.frame_start
+ frame_end = scene.frame_preview_end if scene.use_preview_range else scene.frame_end
+
+ row.label(
+ text="%s / %s" %
+ (bpy.utils.smpte_from_frame(
+ scene.frame_current -
+ frame_start),
+ bpy.utils.smpte_from_frame(
+ frame_end -
+ frame_start)))
+
+ if (scene.frame_current > frame_end):
+ row.label(text="%s Frames Ahead" %
+ ((frame_end - scene.frame_current) * -1))
+ elif (scene.frame_current == frame_start):
+ row.label(text="Start Frame (%s left)" %
+ (frame_end - scene.frame_current))
+ elif (scene.frame_current == frame_end):
+ row.label(text="%s End Frame" % scene.frame_current)
+ else:
+ row.label(text="%s Frames Left" %
+ (frame_end - scene.frame_current))
+
+
+def register():
+ bpy.types.STATUSBAR_HT_header.append(label_timeline_extra_info)
+
+
+def unregister():
+ bpy.types.STATUSBAR_HT_header.remove(label_timeline_extra_info)