UI: Move Extensions repositories popover to header
[blender-addons-contrib.git] / space_view3d_render_settings.py
blobe14ca686c6522dbcc6d3994a85226d68d939106f
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 bl_info = {
20 "name": "Render Settings",
21 "author": "meta-androcto, Saidenka",
22 "version": (0, 1, 1),
23 "blender": (2, 80, 0),
24 "location": "Render Menu, UV Editor Render Tab",
25 "description": "Render Settings BI & Cycles",
26 "warning": "",
27 "doc_url": "https://github.com/meta-androcto/blenderpython/wiki/AF_Render_Settings",
28 "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
29 "category": "Render"
32 import bpy
33 import sys
34 import subprocess
37 class RenderBackground(bpy.types.Operator):
38 bl_idname = "render.render_background"
39 bl_label = "Background Render"
40 bl_description = "Render From The Commandline"
41 bl_options = {'REGISTER'}
43 is_quit: bpy.props.BoolProperty(name="Quit Blender", default=True)
44 items = [
45 ('IMAGE', "Image", "", 1),
46 ('ANIME', "Animation", "", 2),
48 mode: bpy.props.EnumProperty(items=items, name="Mode", default='IMAGE')
49 thread: bpy.props.IntProperty(name="Threads", default=2, min=1, max=16, soft_min=1, soft_max=16)
51 def execute(self, context):
52 blend_path = bpy.data.filepath
53 if (not blend_path):
54 self.report(type={'ERROR'}, message="Save File First")
55 return {'CANCELLED'}
56 if (self.mode == 'IMAGE'):
57 subprocess.Popen([sys.argv[0], '-b', blend_path, '-f', str(context.scene.frame_current), '-t', str(self.thread)])
58 elif (self.mode == 'ANIME'):
59 subprocess.Popen([sys.argv[0], '-b', blend_path, '-a', '-t', str(self.thread)])
60 if (self.is_quit):
61 bpy.ops.wm.quit_blender()
62 return {'FINISHED'}
64 def invoke(self, context, event):
65 return context.window_manager.invoke_props_dialog(self)
68 class SetRenderResolutionPercentage(bpy.types.Operator):
69 bl_idname = "render.set_render_resolution_percentage"
70 bl_label = "Set Resolution"
71 bl_description = "Percent of the size of the resolution"
72 bl_options = {'REGISTER', 'UNDO'}
74 size: bpy.props.IntProperty(name="Rendering size (%)", default=100, min=1, max=1000, soft_min=1, soft_max=1000, step=1)
76 def execute(self, context):
77 context.scene.render.resolution_percentage = self.size
78 return {'FINISHED'}
81 class ToggleThreadsMode(bpy.types.Operator):
82 bl_idname = "render.toggle_threads_mode"
83 bl_label = "Set Threads"
84 bl_description = "I will switch the number of threads in the CPU to be used for rendering"
85 bl_options = {'REGISTER', 'UNDO'}
87 threads: bpy.props.IntProperty(name="Number of threads", default=1, min=1, max=16, soft_min=1, soft_max=16, step=1)
89 def execute(self, context):
90 if (context.scene.render.threads_mode == 'AUTO'):
91 context.scene.render.threads_mode = 'FIXED'
92 context.scene.render.threads = self.threads
93 else:
94 context.scene.render.threads_mode = 'AUTO'
95 return {'FINISHED'}
97 def invoke(self, context, event):
98 if (context.scene.render.threads_mode == 'AUTO'):
99 self.threads = context.scene.render.threads
100 return context.window_manager.invoke_props_dialog(self)
101 else:
102 return self.execute(context)
105 class SetAllSubsurfRenderLevels(bpy.types.Operator):
106 bl_idname = "render.set_all_subsurf_render_levels"
107 bl_label = "Set Global Subsurf"
108 bl_description = "Level of Subsurf to apply when rendering"
109 bl_options = {'REGISTER', 'UNDO'}
111 items = [
112 ('ABSOLUTE', "Absolute value", "", 1),
113 ('RELATIVE', "Relative value", "", 2),
115 mode: bpy.props.EnumProperty(items=items, name="Mode")
116 levels: bpy.props.IntProperty(name="Level", default=2, min=-20, max=20, soft_min=-20, soft_max=20, step=1)
118 def execute(self, context):
119 for obj in bpy.data.objects:
120 if (obj.type != 'MESH' and obj.type != 'CURVE'):
121 continue
122 for mod in obj.modifiers:
123 if (mod.type == 'SUBSURF'):
124 if (self.mode == 'ABSOLUTE'):
125 mod.render_levels = self.levels
126 elif (self.mode == 'RELATIVE'):
127 mod.render_levels += self.levels
128 else:
129 self.report(type={'ERROR'}, message="Setting value is invalid")
130 return {'CANCELLED'}
131 for area in context.screen.areas:
132 area.tag_redraw()
133 return {'FINISHED'}
136 class SyncAllSubsurfRenderLevels(bpy.types.Operator):
137 bl_idname = "render.sync_all_subsurf_render_levels"
138 bl_label = "Sync All Subdivision Levels"
139 bl_description = "sync_all_subsurf_render_levels"
140 bl_options = {'REGISTER', 'UNDO'}
142 level_offset: bpy.props.IntProperty(name="Sync Levels", default=0, min=-20, max=20, soft_min=-20, soft_max=20, step=1)
144 def execute(self, context):
145 for obj in bpy.data.objects:
146 if (obj.type != 'MESH'):
147 continue
148 for mod in obj.modifiers:
149 if (mod.type == 'SUBSURF'):
150 mod.render_levels = mod.levels + self.level_offset
151 for area in context.screen.areas:
152 area.tag_redraw()
153 return {'FINISHED'}
155 def invoke(self, context, event):
156 return context.window_manager.invoke_props_dialog(self)
158 ################
159 # Render Size
160 ################
163 class RenderResolutionPercentageMenu(bpy.types.Menu):
164 bl_idname = "TOPBAR_MT_render_resolution_percentage"
165 bl_label = "Rendering size (%)"
166 bl_description = "Setting is set to either rendered in what percent of the size of the resolution"
168 def check(self, context):
169 return True
171 def draw(self, context):
172 x = bpy.context.scene.render.resolution_x
173 y = bpy.context.scene.render.resolution_y
174 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="10% (" + str(int(x * 0.1)) + "x" + str(int(y * 0.1)) + ")", icon="CAMERA_DATA").size = 10
175 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="20% (" + str(int(x * 0.2)) + "x" + str(int(y * 0.2)) + ")", icon="CAMERA_DATA").size = 20
176 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="30% (" + str(int(x * 0.3)) + "x" + str(int(y * 0.3)) + ")", icon="CAMERA_DATA").size = 30
177 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="40% (" + str(int(x * 0.4)) + "x" + str(int(y * 0.4)) + ")", icon="CAMERA_DATA").size = 40
178 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="50% (" + str(int(x * 0.5)) + "x" + str(int(y * 0.5)) + ")", icon="CAMERA_DATA").size = 50
179 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="60% (" + str(int(x * 0.6)) + "x" + str(int(y * 0.6)) + ")", icon="CAMERA_DATA").size = 60
180 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="70% (" + str(int(x * 0.7)) + "x" + str(int(y * 0.7)) + ")", icon="CAMERA_DATA").size = 70
181 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="80% (" + str(int(x * 0.8)) + "x" + str(int(y * 0.8)) + ")", icon="CAMERA_DATA").size = 80
182 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="90% (" + str(int(x * 0.9)) + "x" + str(int(y * 0.9)) + ")", icon="CAMERA_DATA").size = 90
183 self.layout.separator()
184 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="100% (" + str(int(x)) + "x" + str(int(y)) + ")", icon="CAMERA_DATA").size = 100
185 self.layout.separator()
186 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="150% (" + str(int(x * 1.5)) + "x" + str(int(y * 1.5)) + ")", icon="CAMERA_DATA").size = 150
187 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="200% (" + str(int(x * 2.0)) + "x" + str(int(y * 2.0)) + ")", icon="CAMERA_DATA").size = 200
188 self.layout.operator(SetRenderResolutionPercentage.bl_idname, text="300% (" + str(int(x * 3.0)) + "x" + str(int(y * 3.0)) + ")", icon="CAMERA_DATA").size = 300
191 class SimplifyRenderMenu(bpy.types.Menu):
192 bl_idname = "TOPBAR_MT_render_simplify"
193 bl_label = "Simplify Render"
194 bl_description = "I simplified set of rendering"
196 def draw(self, context):
197 self.layout.prop(context.scene.render, "use_simplify")
198 self.layout.separator()
199 self.layout.prop(context.scene.render, "simplify_subdivision")
200 self.layout.prop(context.scene.render, "simplify_shadow_samples")
201 self.layout.prop(context.scene.render, "simplify_child_particles")
202 self.layout.prop(context.scene.render, "simplify_ao_sss")
203 self.layout.prop(context.scene.render, "use_simplify_triangulate")
206 class ShadeingMenu(bpy.types.Menu):
207 bl_idname = "TOPBAR_MT_render_shadeing"
208 bl_label = "Use shading"
209 bl_description = "Shading on / off"
211 def draw(self, context):
212 self.layout.prop(context.scene.render, 'use_textures')
213 self.layout.prop(context.scene.render, 'use_shadows')
214 self.layout.prop(context.scene.render, 'use_sss')
215 self.layout.prop(context.scene.render, 'use_envmaps')
216 self.layout.prop(context.scene.render, 'use_raytrace')
219 class SubsurfMenu(bpy.types.Menu):
220 bl_idname = "TOPBAR_MT_render_subsurf"
221 bl_label = "Subsurf Level All"
222 bl_description = "Subsurf subdivision level of all objects"
224 def draw(self, context):
225 operator = self.layout.operator(SetAllSubsurfRenderLevels.bl_idname, text="Subdivision + 1", icon="MOD_SUBSURF")
226 operator.mode = 'RELATIVE'
227 operator.levels = 1
228 operator = self.layout.operator(SetAllSubsurfRenderLevels.bl_idname, text="Subdivision - 1", icon="MOD_SUBSURF")
229 operator.mode = 'RELATIVE'
230 operator.levels = -1
231 self.layout.separator()
232 operator = self.layout.operator(SetAllSubsurfRenderLevels.bl_idname, text="Subdivision = 0", icon="MOD_SUBSURF")
233 operator.mode = 'ABSOLUTE'
234 operator.levels = 0
235 operator = self.layout.operator(SetAllSubsurfRenderLevels.bl_idname, text="Subdivision = 1", icon="MOD_SUBSURF")
236 operator.mode = 'ABSOLUTE'
237 operator.levels = 1
238 operator = self.layout.operator(SetAllSubsurfRenderLevels.bl_idname, text="Subdivision = 2", icon="MOD_SUBSURF")
239 operator.mode = 'ABSOLUTE'
240 operator.levels = 2
241 operator = self.layout.operator(SetAllSubsurfRenderLevels.bl_idname, text="Subdivision = 3", icon="MOD_SUBSURF")
242 operator.mode = 'ABSOLUTE'
243 operator.levels = 3
244 self.layout.separator()
245 self.layout.operator(SyncAllSubsurfRenderLevels.bl_idname, text="Sync Subsurf Render Levels", icon="MOD_SUBSURF")
248 class RenderToolsMenu(bpy.types.Operator):
249 bl_idname = "render.render_tools"
250 bl_label = "Render Settings"
251 bl_description = "Pop up Render Settings"
252 COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'CYCLES'}
253 def draw(self, context):
254 # Cycles
255 layout = self.layout
256 layout.operator_context = 'INVOKE_REGION_WIN'
257 scene = context.scene
258 cscene = scene.cycles
261 self.layout.label(text="Render Cycles")
262 self.layout.separator()
263 self.layout.operator("render.render", text="Render Image").use_viewport = True
264 self.layout.operator("render.render", text="Render Animation")
265 self.layout.separator()
266 self.layout.prop(context.scene.render, 'resolution_x', text="Resolution X")
267 self.layout.prop(context.scene.render, 'resolution_y', text="Resolution Y")
268 self.layout.prop(context.scene.render, "resolution_percentage", text="Render Resolution")
269 self.layout.menu(RenderResolutionPercentageMenu.bl_idname, text="Resolution Presets")
270 self.layout.prop_menu_enum(context.scene.render.image_settings, 'file_format', text="File Format")
271 self.layout.separator()
272 self.layout.menu(AnimateRenderMenu.bl_idname, text="Animation")
273 self.layout.separator()
274 self.layout.prop(context.scene.world.light_settings, 'use_ambient_occlusion', text="Use AO")
275 self.layout.prop(context.scene.world.light_settings, "ao_factor", text="AO Factor")
276 self.layout.separator()
277 self.layout.label(text="Samples:")
278 self.layout.prop(cscene, "samples", text="Render")
279 self.layout.prop(cscene, "preview_samples", text="Preview")
280 self.layout.separator()
281 self.layout.prop(context.scene.render, 'use_freestyle', text="Use Freestyle")
282 self.layout.separator()
283 self.layout.menu(SimplifyRenderMenu.bl_idname)
284 self.layout.menu(SubsurfMenu.bl_idname)
285 self.layout.separator()
286 self.layout.operator(ToggleThreadsMode.bl_idname, text='Set Threads')
287 self.layout.operator(RenderBackground.bl_idname)
290 def execute(self, context):
291 return {'FINISHED'}
293 def invoke(self, context, event):
294 return context.window_manager.invoke_popup(self, width=250)
295 # Menu
298 def menu(self, context):
300 self.layout.separator()
301 self.layout.operator(RenderToolsMenu.bl_idname)
304 class AnimateRenderMenu(bpy.types.Menu):
305 bl_idname = "TOPBAR_MT_render_animate_menu"
306 bl_label = "Animation"
307 bl_description = "Set Frames & Animation Length"
309 def draw(self, context):
310 self.layout.separator()
311 self.layout.prop(context.scene, 'frame_start', text="Start Frame")
312 self.layout.prop(context.scene, 'frame_end', text="End Frame")
313 self.layout.prop(context.scene, 'frame_step', text="Frame Step")
314 self.layout.prop(context.scene.render, 'fps', text="FPS")
317 class IMAGE_PT_RenderSettingsPanel(bpy.types.Panel):
318 """Render Settings Panel"""
319 bl_label = "Render settings"
320 bl_space_type = 'IMAGE_EDITOR'
321 bl_category = 'Render'
322 bl_region_type = 'UI'
323 COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'CYCLES'}
325 def draw(self, context):
326 # Cycles
327 layout = self.layout
328 layout.operator_context = 'INVOKE_REGION_WIN'
329 scene = context.scene
330 cscene = scene.cycles
332 self.layout.label(text="Render Settings")
333 self.layout.separator()
334 self.layout.operator("render.render", text="Render Image").use_viewport = True
335 self.layout.operator("render.render", text="Render Animation",)
336 self.layout.separator()
337 self.layout.prop(context.scene.render, 'resolution_x', text="Resolution X")
338 self.layout.prop(context.scene.render, 'resolution_y', text="Resolution Y")
339 self.layout.prop(context.scene.render, "resolution_percentage", text="Render Resolution")
340 self.layout.menu(RenderResolutionPercentageMenu.bl_idname, text="Resolution Presets")
341 self.layout.prop_menu_enum(context.scene.render.image_settings, 'file_format', text="File Format")
342 self.layout.separator()
343 self.layout.menu(AnimateRenderMenu.bl_idname, text="Animation")
344 self.layout.separator()
345 self.layout.prop(context.scene.world.light_settings, 'use_ambient_occlusion', text="Use AO")
346 self.layout.prop(context.scene.world.light_settings, "ao_factor", text="AO Factor")
347 self.layout.separator()
348 self.layout.label(text="Samples:")
349 self.layout.prop(cscene, "samples", text="Render")
350 self.layout.prop(cscene, "preview_samples", text="Preview")
351 self.layout.separator()
352 self.layout.prop(context.scene.render, 'use_freestyle', text="Use Freestyle")
353 self.layout.separator()
354 self.layout.menu(SimplifyRenderMenu.bl_idname)
355 self.layout.menu(SubsurfMenu.bl_idname)
356 self.layout.separator()
357 self.layout.operator(ToggleThreadsMode.bl_idname, text='Set Threads')
358 self.layout.operator(RenderBackground.bl_idname)
361 def execute(self, context):
362 return {'FINISHED'}
364 def invoke(self, context, event):
365 return context.window_manager.invoke_popup(self, width=250)
367 # Class List
368 classes = (
369 RenderBackground,
370 SetRenderResolutionPercentage,
371 ToggleThreadsMode,
372 SetAllSubsurfRenderLevels,
373 SyncAllSubsurfRenderLevels,
374 RenderResolutionPercentageMenu,
375 SimplifyRenderMenu,
376 ShadeingMenu,
377 SubsurfMenu,
378 RenderToolsMenu,
379 AnimateRenderMenu,
380 IMAGE_PT_RenderSettingsPanel
382 # register
384 def register():
385 for cls in classes:
386 bpy.utils.register_class(cls)
387 bpy.types.TOPBAR_MT_render.append(menu)
389 # unregister
391 def unregister():
392 bpy.types.TOPBAR_MT_render.remove(menu)
393 for cls in classes:
394 bpy.utils.unregister_class(cls)
396 if __name__ == "__main__":
397 register()