[Bf-extensions-cvs] [654afac9] master: Add UI Animation Render addon

Luca Rood noreply at git.blender.org
Tue Mar 31 15:18:07 CEST 2020


Commit: 654afac96c1fd5a8831321d1d60d029ddf2b9ab3
Author: Luca Rood
Date:   Thu Mar 19 13:48:28 2020 +0100
Branches: master
https://developer.blender.org/rBA654afac96c1fd5a8831321d1d60d029ddf2b9ab3

Add UI Animation Render addon

UI Animation Render allows you to capture the Blender UI for each frame of an animation.
This enables you to neatly show how the UI and different values are changing during animation.

More info, and demo here: https://gitlab.com/LucaRood/screenrender

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D7180

===================================================================

A	render_ui_animation_render.py

===================================================================

diff --git a/render_ui_animation_render.py b/render_ui_animation_render.py
new file mode 100644
index 00000000..27d84a4a
--- /dev/null
+++ b/render_ui_animation_render.py
@@ -0,0 +1,223 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  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.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+import bpy
+
+bl_info = {
+    "name": "UI Animation Render",
+    "author": "Luca Rood",
+    "description": "Render animations of the Blender UI.",
+    "blender": (2, 80, 0),
+    "version": (0, 1, 0),
+    "location": "View3D > Sidebar > View Tab and Ctrl+Shift+F12",
+    "warning": "",
+    "category": "Render"
+}
+
+km = None
+
+
+def draw_ui(prefs, layout):
+    layout.prop(prefs, "delay")
+
+    col = layout.column(align=True)
+    col.label(text="Animation Highlight:")
+
+    row = col.row()
+    row.prop(prefs, "anim_highlight", expand=True)
+
+    if prefs.anim_highlight == "replace":
+        split = col.split(factor=0.2)
+        split.label(text="Color")
+        row = split.row(align=True)
+        row.prop(prefs, "highlight_color", text="")
+        row.prop(prefs, "highlight_blend", text="Blend")
+
+
+class UIAnimationRenderPreferences(bpy.types.AddonPreferences):
+    bl_idname = __name__
+
+    delay: bpy.props.FloatProperty(
+        name="Capture Delay",
+        description="How much time to wait (seconds) before capturing each frame, to allow the viewport to clean up",
+        default=0.5
+    )
+
+    anim_highlight: bpy.props.EnumProperty(
+        name="Animation Highlight",
+        description="What to do with the animated field highlight color",
+        items=[("keep", "Keep", "Keep the animated field highlight", 0),
+               ("hide", "Hide", "Hide the animated field highlight", 1),
+               ("replace", "Replace", "Replace the animated field highlight", 2)],
+        default="keep"
+    )
+
+    highlight_color: bpy.props.FloatVectorProperty(
+        name="Highlight Color",
+        description="Color to use for animated field highlights",
+        subtype='COLOR',
+        default=(1.0, 1.0, 1.0)
+    )
+
+    highlight_blend: bpy.props.FloatProperty(
+        name="Highlight Blend",
+        description="How much the highlight color influences the field color",
+        default=0.5
+    )
+
+    def draw(self, context):
+        draw_ui(self, self.layout)
+
+
+class RenderScreen(bpy.types.Operator):
+    bl_idname = "render.render_screen"
+    bl_label = "Render Screen"
+    bl_description = "Capture the screen for each animation frame and write to the render output path"
+
+    _timer = None
+    _f_initial = 1
+    _theme_blend = 0.0
+    _theme_key = (0, 0, 0)
+    _theme_key_sel = (0, 0, 0)
+    _theme_anim = (0, 0, 0)
+    _theme_anim_sel = (0, 0, 0)
+    _theme_driven = (0, 0, 0)
+    _theme_driven_sel = (0, 0, 0)
+
+    def modal(self, context, event):
+        if event.type in {'RIGHTMOUSE', 'ESC'}:
+            self.stop(context)
+            return {'CANCELLED'}
+
+        if event.type == 'TIMER':
+            scene = context.scene
+            f_curr = scene.frame_current
+
+            bpy.ops.screen.screenshot(filepath=context.scene.render.frame_path(frame=f_curr))
+
+            if f_curr < scene.frame_end:
+                scene.frame_set(f_curr + 1)
+            else:
+                self.stop(context)
+                return {'FINISHED'}
+
+        return {'RUNNING_MODAL'}
+
+    def execute(self, context):
+        # Adjust animation highlight (theme)
+        prefs = context.preferences
+        addon_prefs = prefs.addons[__name__].preferences
+        theme = prefs.themes[0].user_interface.wcol_state
+
+        if addon_prefs.anim_highlight == "hide":
+            self._theme_blend = theme.blend
+            theme.blend = 0.0
+        elif addon_prefs.anim_highlight == "replace":
+            self._theme_blend = theme.blend
+            self._theme_key = theme.inner_key.copy()
+            self._theme_key_sel = theme.inner_key_sel.copy()
+            self._theme_anim = theme.inner_anim.copy()
+            self._theme_anim_sel = theme.inner_anim_sel.copy()
+            self._theme_driven = theme.inner_driven.copy()
+            self._theme_driven_sel = theme.inner_driven_sel.copy()
+
+            theme.blend = addon_prefs.highlight_blend
+            theme.inner_key = addon_prefs.highlight_color
+            theme.inner_key_sel = addon_prefs.highlight_color
+            theme.inner_anim = addon_prefs.highlight_color
+            theme.inner_anim_sel = addon_prefs.highlight_color
+            theme.inner_driven = addon_prefs.highlight_color
+            theme.inner_driven_sel = addon_prefs.highlight_color
+
+        # Set frame
+        scene = context.scene
+        self._f_initial = scene.frame_current
+        scene.frame_set(scene.frame_start)
+
+        # Start timer
+        wm = context.window_manager
+        self._timer = wm.event_timer_add(addon_prefs.delay, window=context.window)
+        wm.modal_handler_add(self)
+        return {'RUNNING_MODAL'}
+
+    def stop(self, context):
+        # Stop timer
+        wm = context.window_manager
+        wm.event_timer_remove(self._timer)
+
+        # Reset frame
+        context.scene.frame_set(self._f_initial)
+
+        # Reset theme
+        prefs = context.preferences
+        addon_prefs = prefs.addons[__name__].preferences
+        theme = prefs.themes[0].user_interface.wcol_state
+
+        if addon_prefs.anim_highlight == "hide":
+            theme.blend = self._theme_blend
+        elif addon_prefs.anim_highlight == "replace":
+            theme.blend = self._theme_blend
+            theme.inner_key = self._theme_key
+            theme.inner_key_sel = self._theme_key_sel
+            theme.inner_anim = self._theme_anim
+            theme.inner_anim_sel = self._theme_anim_sel
+            theme.inner_driven = self._theme_driven
+            theme.inner_driven_sel = self._theme_driven_sel
+
+
+class VIEW3D_PT_ui_animation_render(bpy.types.Panel):
+    bl_space_type = 'VIEW_3D'
+    bl_region_type = 'UI'
+    bl_category = "View"
+    bl_label = "UI Animation Render"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = False
+
+        prefs = context.preferences
+        addon_prefs = prefs.addons[__name__].preferences
+
+        layout.operator(RenderScreen.bl_idname)
+        draw_ui(addon_prefs, layout)
+
+
+def register():
+    global km
+
+    bpy.utils.register_class(UIAnimationRenderPreferences)
+    bpy.utils.register_class(RenderScreen)
+    bpy.utils.register_class(VIEW3D_PT_ui_animation_render)
+
+    wm = bpy.context.window_manager
+    km = wm.keyconfigs.addon.keymaps.new(name='Screen', space_type='EMPTY')
+    km.keymap_items.new('render.render_screen', 'F12', 'PRESS', shift=True, ctrl=True)
+
+
+def unregister():
+    global km
+
+    bpy.utils.unregister_class(UIAnimationRenderPreferences)
+    bpy.utils.unregister_class(RenderScreen)
+    bpy.utils.unregister_class(VIEW3D_PT_ui_animation_render)
+
+    if km is not None:
+        wm = bpy.context.window_manager
+        wm.keyconfigs.addon.keymaps.remove(km)
+        km = None



More information about the Bf-extensions-cvs mailing list