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 #####
20 "name": "Render Settings",
21 "author": "meta-androcto, Saidenka",
23 "blender": (2, 80, 0),
24 "location": "Render Menu, UV Editor Render Tab",
25 "description": "Render Settings BI & Cycles",
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/",
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)
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
54 self
.report(type={'ERROR'}, message
="Save File First")
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
)])
61 bpy
.ops
.wm
.quit_blender()
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
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
94 context
.scene
.render
.threads_mode
= 'AUTO'
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
)
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'}
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'):
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
129 self
.report(type={'ERROR'}, message
="Setting value is invalid")
131 for area
in context
.screen
.areas
:
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'):
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
:
155 def invoke(self
, context
, event
):
156 return context
.window_manager
.invoke_props_dialog(self
)
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
):
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'
228 operator
= self
.layout
.operator(SetAllSubsurfRenderLevels
.bl_idname
, text
="Subdivision - 1", icon
="MOD_SUBSURF")
229 operator
.mode
= 'RELATIVE'
231 self
.layout
.separator()
232 operator
= self
.layout
.operator(SetAllSubsurfRenderLevels
.bl_idname
, text
="Subdivision = 0", icon
="MOD_SUBSURF")
233 operator
.mode
= 'ABSOLUTE'
235 operator
= self
.layout
.operator(SetAllSubsurfRenderLevels
.bl_idname
, text
="Subdivision = 1", icon
="MOD_SUBSURF")
236 operator
.mode
= 'ABSOLUTE'
238 operator
= self
.layout
.operator(SetAllSubsurfRenderLevels
.bl_idname
, text
="Subdivision = 2", icon
="MOD_SUBSURF")
239 operator
.mode
= 'ABSOLUTE'
241 operator
= self
.layout
.operator(SetAllSubsurfRenderLevels
.bl_idname
, text
="Subdivision = 3", icon
="MOD_SUBSURF")
242 operator
.mode
= 'ABSOLUTE'
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
):
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
):
293 def invoke(self
, context
, event
):
294 return context
.window_manager
.invoke_popup(self
, width
=250)
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
):
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
):
364 def invoke(self
, context
, event
):
365 return context
.window_manager
.invoke_popup(self
, width
=250)
370 SetRenderResolutionPercentage
,
372 SetAllSubsurfRenderLevels
,
373 SyncAllSubsurfRenderLevels
,
374 RenderResolutionPercentageMenu
,
380 IMAGE_PT_RenderSettingsPanel
386 bpy
.utils
.register_class(cls
)
387 bpy
.types
.TOPBAR_MT_render
.append(menu
)
392 bpy
.types
.TOPBAR_MT_render
.remove(menu
)
394 bpy
.utils
.unregister_class(cls
)
396 if __name__
== "__main__":