Avoid writing redundant zeros
[blender-addons.git] / system_demo_mode / __init__.py
blob5555713495d04bc548d592e2b90b129e80b28f5b
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 # <pep8 compliant>
21 bl_info = {
22 "name": "Demo Mode",
23 "author": "Campbell Barton",
24 "blender": (2, 57, 0),
25 "location": "Demo Menu",
26 "description": "Demo mode lets you select multiple blend files and loop over them.",
27 "warning": "",
28 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
29 "Scripts/System/Demo_Mode#Running_Demo_Mode",
30 "support": 'OFFICIAL',
31 "category": "System"}
33 # To support reload properly, try to access a package var, if it's there, reload everything
34 if "bpy" in locals():
35 import importlib
36 if "config" in locals():
37 importlib.reload(config)
40 import bpy
41 from bpy.props import (
42 StringProperty,
43 BoolProperty,
44 IntProperty,
45 FloatProperty,
46 EnumProperty,
50 class DemoModeSetup(bpy.types.Operator):
51 """Create a demo script and optionally execute it"""
52 bl_idname = "wm.demo_mode_setup"
53 bl_label = "Demo Mode (Setup)"
54 bl_options = {'PRESET'}
56 # List of operator properties, the attributes will be assigned
57 # to the class instance from the operator settings before calling.
59 # these are used to create the file list.
60 directory = StringProperty(
61 name="Search Path",
62 description="Directory used for importing the file",
63 maxlen=1024,
64 subtype='DIR_PATH',
66 random_order = BoolProperty(
67 name="Random Order",
68 description="Select files randomly",
69 default=False,
71 mode = EnumProperty(
72 name="Method",
73 items=(('AUTO', "Auto", ""),
74 ('PLAY', "Play", ""),
75 ('RENDER', "Render", ""),
79 run = BoolProperty(
80 name="Run Immediately!",
81 description="Run demo immediately",
82 default=True,
84 exit = BoolProperty(
85 name="Exit",
86 description="Run once and exit",
87 default=False,
90 # these are mapped directly to the config!
92 # anim
93 # ====
94 anim_cycles = IntProperty(
95 name="Cycles",
96 description="Number of times to play the animation",
97 min=1, max=1000,
98 default=2,
100 anim_time_min = FloatProperty(
101 name="Time Min",
102 description="Minimum number of seconds to show the animation for "
103 "(for small loops)",
104 min=0.0, max=1000.0,
105 soft_min=1.0, soft_max=1000.0,
106 default=4.0,
108 anim_time_max = FloatProperty(
109 name="Time Max",
110 description="Maximum number of seconds to show the animation for "
111 "(in case the end frame is very high for no reason)",
112 min=0.0, max=100000000.0,
113 soft_min=1.0, soft_max=100000000.0,
114 default=8.0,
116 anim_screen_switch = FloatProperty(
117 name="Screen Switch",
118 description="Time between switching screens (in seconds) "
119 "or 0 to disable",
120 min=0.0, max=100000000.0,
121 soft_min=1.0, soft_max=60.0,
122 default=0.0,
125 # render
126 # ======
127 display_render = FloatProperty(
128 name="Render Delay",
129 description="Time to display the rendered image before moving on "
130 "(in seconds)",
131 min=0.0, max=60.0,
132 default=4.0,
134 anim_render = BoolProperty(
135 name="Render Anim",
136 description="Render entire animation (render mode only)",
137 default=False,
140 def execute(self, context):
141 from . import config
143 keywords = self.as_keywords(ignore=("directory", "random_order", "run", "exit"))
144 cfg_str, dirpath = config.as_string(self.directory,
145 self.random_order,
146 self.exit,
147 **keywords)
148 text = bpy.data.texts.get("demo.py")
149 if text:
150 text.name += ".back"
152 text = bpy.data.texts.new("demo.py")
153 text.from_string(cfg_str)
155 if self.run:
156 extern_demo_mode_run()
158 return {'FINISHED'}
160 def invoke(self, context, event):
161 context.window_manager.fileselect_add(self)
162 return {'RUNNING_MODAL'}
164 def check(self, context):
165 return True # lazy
167 def draw(self, context):
168 layout = self.layout
170 box = layout.box()
171 box.label("Search *.blend recursively")
172 box.label("Writes: demo.py config text")
174 layout.prop(self, "run")
175 layout.prop(self, "exit")
177 layout.label("Generate Settings:")
178 row = layout.row()
179 row.prop(self, "mode", expand=True)
180 layout.prop(self, "random_order")
182 mode = self.mode
184 layout.separator()
185 sub = layout.column()
186 sub.active = (mode in {'AUTO', 'PLAY'})
187 sub.label("Animate Settings:")
188 sub.prop(self, "anim_cycles")
189 sub.prop(self, "anim_time_min")
190 sub.prop(self, "anim_time_max")
191 sub.prop(self, "anim_screen_switch")
193 layout.separator()
194 sub = layout.column()
195 sub.active = (mode in {'AUTO', 'RENDER'})
196 sub.label("Render Settings:")
197 sub.prop(self, "display_render")
200 class DemoModeRun(bpy.types.Operator):
201 bl_idname = "wm.demo_mode_run"
202 bl_label = "Demo Mode (Start)"
204 def execute(self, context):
205 if extern_demo_mode_run():
206 return {'FINISHED'}
207 else:
208 self.report({'ERROR'}, "Cant load demo.py config, run: File -> Demo Mode (Setup)")
209 return {'CANCELLED'}
212 # --- call demo_mode.py funcs
213 def extern_demo_mode_run():
214 # this accesses demo_mode.py which is kept standalone
215 # and can be run direct.
216 from . import demo_mode
217 if demo_mode.load_config():
218 demo_mode.demo_mode_load_file() # kick starts the modal operator
219 return True
220 else:
221 return False
224 def extern_demo_mode_register():
225 # this accesses demo_mode.py which is kept standalone
226 # and can be run direct.
227 from . import demo_mode
228 demo_mode.register()
231 def extern_demo_mode_unregister():
232 # this accesses demo_mode.py which is kept standalone
233 # and can be run direct.
234 from . import demo_mode
235 demo_mode.unregister()
237 # --- intergration
240 def menu_func(self, context):
241 layout = self.layout
242 layout.operator(DemoModeSetup.bl_idname, icon='PREFERENCES')
243 layout.operator(DemoModeRun.bl_idname, icon='PLAY')
244 layout.separator()
247 def register():
248 bpy.utils.register_class(DemoModeSetup)
249 bpy.utils.register_class(DemoModeRun)
251 bpy.types.INFO_MT_file.prepend(menu_func)
253 extern_demo_mode_register()
256 def unregister():
257 bpy.utils.unregister_class(DemoModeSetup)
258 bpy.utils.unregister_class(DemoModeRun)
260 bpy.types.INFO_MT_file.remove(menu_func)
262 extern_demo_mode_unregister()
264 if __name__ == "__main__":
265 register()