dc0b76645ae6e3e3494ed8956b5f65fad82ddb4b
[blender.git] / release / scripts / ui / properties_render.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
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.
7 #
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.
12 #
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.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 narrowui = bpy.context.user_preferences.view.properties_width_check
23
24
25 class RENDER_MT_presets(bpy.types.Menu):
26     bl_label = "Render Presets"
27     preset_subdir = "render"
28     preset_operator = "script.execute_preset"
29     draw = bpy.types.Menu.draw_preset
30
31
32 class RENDER_MT_ffmpeg_presets(bpy.types.Menu):
33     bl_label = "FFMPEG Presets"
34     preset_subdir = "ffmpeg"
35     preset_operator = "script.python_file_run"
36     draw = bpy.types.Menu.draw_preset
37
38
39 class RenderButtonsPanel():
40     bl_space_type = 'PROPERTIES'
41     bl_region_type = 'WINDOW'
42     bl_context = "render"
43     # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
44
45
46 class RENDER_PT_render(RenderButtonsPanel, bpy.types.Panel):
47     bl_label = "Render"
48     COMPAT_ENGINES = {'BLENDER_RENDER'}
49
50     @staticmethod
51     def poll(context):
52         rd = context.scene.render
53         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
54
55     def draw(self, context):
56         layout = self.layout
57
58         rd = context.scene.render
59         wide_ui = context.region.width > narrowui
60
61         split = layout.split()
62
63         col = split.column()
64         col.operator("render.render", text="Image", icon='RENDER_STILL')
65
66         if wide_ui:
67             col = split.column()
68         col.operator("render.render", text="Animation", icon='RENDER_ANIMATION').animation = True
69
70         layout.prop(rd, "display_mode", text="Display")
71
72
73 class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
74     bl_label = "Layers"
75     bl_default_closed = True
76     COMPAT_ENGINES = {'BLENDER_RENDER'}
77
78     @staticmethod
79     def poll(context):
80         rd = context.scene.render
81         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
82
83     def draw(self, context):
84         layout = self.layout
85
86         scene = context.scene
87         rd = scene.render
88         wide_ui = context.region.width > narrowui
89
90         row = layout.row()
91         row.template_list(rd, "layers", rd, "active_layer_index", rows=2)
92
93         col = row.column(align=True)
94         col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
95         col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
96
97         rl = rd.layers[rd.active_layer_index]
98
99         if rl:
100             layout.prop(rl, "name")
101
102         split = layout.split()
103
104         col = split.column()
105         col.prop(scene, "layers", text="Scene")
106         col.label(text="")
107         col.prop(rl, "light_override", text="Light")
108         col.prop(rl, "material_override", text="Material")
109         if wide_ui:
110             col = split.column()
111         col.prop(rl, "visible_layers", text="Layer")
112         col.label(text="Mask Layers:")
113         col.prop(rl, "zmask_layers", text="")
114
115
116         layout.separator()
117         layout.label(text="Include:")
118
119         split = layout.split()
120
121         col = split.column()
122         col.prop(rl, "zmask")
123         row = col.row()
124         row.prop(rl, "zmask_negate", text="Negate")
125         row.active = rl.zmask
126         col.prop(rl, "all_z")
127
128         col = split.column()
129         col.prop(rl, "solid")
130         col.prop(rl, "halo")
131         col.prop(rl, "ztransp")
132
133         col = split.column()
134         col.prop(rl, "sky")
135         col.prop(rl, "edge")
136         col.prop(rl, "strand")
137
138         layout.separator()
139
140         split = layout.split()
141
142         col = split.column()
143         col.label(text="Passes:")
144         col.prop(rl, "pass_combined")
145         col.prop(rl, "pass_z")
146         col.prop(rl, "pass_vector")
147         col.prop(rl, "pass_normal")
148         col.prop(rl, "pass_uv")
149         col.prop(rl, "pass_mist")
150         col.prop(rl, "pass_object_index")
151         col.prop(rl, "pass_color")
152
153         if wide_ui:
154             col = split.column()
155         col.label()
156         col.prop(rl, "pass_diffuse")
157         row = col.row()
158         row.prop(rl, "pass_specular")
159         row.prop(rl, "pass_specular_exclude", text="")
160         row = col.row()
161         row.prop(rl, "pass_shadow")
162         row.prop(rl, "pass_shadow_exclude", text="")
163         row = col.row()
164         row.prop(rl, "pass_emit")
165         row.prop(rl, "pass_emit_exclude", text="")
166         row = col.row()
167         row.prop(rl, "pass_ao")
168         row.prop(rl, "pass_ao_exclude", text="")
169         row = col.row()
170         row.prop(rl, "pass_environment")
171         row.prop(rl, "pass_environment_exclude", text="")
172         row = col.row()
173         row.prop(rl, "pass_indirect")
174         row.prop(rl, "pass_indirect_exclude", text="")
175         row = col.row()
176         row.prop(rl, "pass_reflection")
177         row.prop(rl, "pass_reflection_exclude", text="")
178         row = col.row()
179         row.prop(rl, "pass_refraction")
180         row.prop(rl, "pass_refraction_exclude", text="")
181
182
183 class RENDER_PT_shading(RenderButtonsPanel, bpy.types.Panel):
184     bl_label = "Shading"
185     COMPAT_ENGINES = {'BLENDER_RENDER'}
186
187     @staticmethod
188     def poll(context):
189         rd = context.scene.render
190         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
191
192     def draw(self, context):
193         layout = self.layout
194
195         rd = context.scene.render
196         wide_ui = context.region.width > narrowui
197
198         split = layout.split()
199
200         col = split.column()
201         col.prop(rd, "use_textures", text="Textures")
202         col.prop(rd, "use_shadows", text="Shadows")
203         col.prop(rd, "use_sss", text="Subsurface Scattering")
204         col.prop(rd, "use_envmaps", text="Environment Map")
205
206         if wide_ui:
207             col = split.column()
208         col.prop(rd, "use_raytracing", text="Ray Tracing")
209         col.prop(rd, "color_management")
210         col.prop(rd, "alpha_mode", text="Alpha")
211
212
213 class RENDER_PT_performance(RenderButtonsPanel, bpy.types.Panel):
214     bl_label = "Performance"
215     bl_default_closed = True
216     COMPAT_ENGINES = {'BLENDER_RENDER'}
217
218     @staticmethod
219     def poll(context):
220         rd = context.scene.render
221         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
222
223     def draw(self, context):
224         layout = self.layout
225
226         rd = context.scene.render
227         wide_ui = context.region.width > narrowui
228
229         split = layout.split()
230
231         col = split.column()
232         col.label(text="Threads:")
233         col.row().prop(rd, "threads_mode", expand=True)
234         sub = col.column()
235         sub.enabled = rd.threads_mode == 'FIXED'
236         sub.prop(rd, "threads")
237         sub = col.column(align=True)
238         sub.label(text="Tiles:")
239         sub.prop(rd, "parts_x", text="X")
240         sub.prop(rd, "parts_y", text="Y")
241
242         if wide_ui:
243             col = split.column()
244         col.label(text="Memory:")
245         sub = col.column()
246         sub.enabled = not (rd.use_border or rd.full_sample)
247         sub.prop(rd, "save_buffers")
248         sub = col.column()
249         sub.active = rd.use_compositing
250         sub.prop(rd, "free_image_textures")
251         sub = col.column()
252         sub.active = rd.use_raytracing
253         sub.label(text="Acceleration structure:")
254         sub.prop(rd, "raytrace_structure", text="")
255         if rd.raytrace_structure == 'OCTREE':
256             sub.prop(rd, "octree_resolution", text="Resolution")
257         else:
258             sub.prop(rd, "use_instances", text="Instances")
259         sub.prop(rd, "use_local_coords", text="Local Coordinates")
260
261
262 class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
263     bl_label = "Post Processing"
264     bl_default_closed = True
265     COMPAT_ENGINES = {'BLENDER_RENDER'}
266
267     @staticmethod
268     def poll(context):
269         rd = context.scene.render
270         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
271
272     def draw(self, context):
273         layout = self.layout
274
275         rd = context.scene.render
276         wide_ui = context.region.width > narrowui
277
278         split = layout.split()
279
280         col = split.column()
281         col.prop(rd, "use_compositing")
282         col.prop(rd, "use_sequencer")
283
284         if wide_ui:
285             col = split.column()
286         col.prop(rd, "dither_intensity", text="Dither", slider=True)
287
288         layout.separator()
289
290         split = layout.split()
291
292         col = split.column()
293         col.prop(rd, "fields", text="Fields")
294         sub = col.column()
295         sub.active = rd.fields
296         sub.row().prop(rd, "field_order", expand=True)
297         sub.prop(rd, "fields_still", text="Still")
298
299
300         if wide_ui:
301             col = split.column()
302         else:
303             col.separator()
304         col.prop(rd, "edge")
305         sub = col.column()
306         sub.active = rd.edge
307         sub.prop(rd, "edge_threshold", text="Threshold", slider=True)
308         sub.prop(rd, "edge_color", text="")
309
310
311 class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
312     bl_label = "Output"
313     COMPAT_ENGINES = {'BLENDER_RENDER'}
314
315     @staticmethod
316     def poll(context):
317         rd = context.scene.render
318         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
319
320     def draw(self, context):
321         layout = self.layout
322
323         rd = context.scene.render
324         file_format = rd.file_format
325         wide_ui = context.region.width > narrowui
326
327         layout.prop(rd, "output_path", text="")
328
329         split = layout.split()
330         col = split.column()
331         col.prop(rd, "file_format", text="")
332         col.row().prop(rd, "color_mode", text="Color", expand=True)
333
334         if wide_ui:
335             col = split.column()
336         col.prop(rd, "use_file_extension")
337         col.prop(rd, "use_overwrite")
338         col.prop(rd, "use_placeholder")
339
340         if file_format in ('AVI_JPEG', 'JPEG'):
341             split = layout.split()
342             split.prop(rd, "file_quality", slider=True)
343         
344         if file_format == 'PNG':
345             split = layout.split()
346             split.prop(rd, "file_quality", slider=True, text="Compression")
347
348         elif file_format == 'MULTILAYER':
349             split = layout.split()
350
351             col = split.column()
352             col.label(text="Codec:")
353             col.prop(rd, "exr_codec", text="")
354             if wide_ui:
355                 col = split.column()
356
357         elif file_format == 'OPEN_EXR':
358             split = layout.split()
359
360             col = split.column()
361             col.label(text="Codec:")
362             col.prop(rd, "exr_codec", text="")
363
364             if wide_ui:
365                 subsplit = split.split()
366                 col = subsplit.column()
367             col.prop(rd, "exr_half")
368             col.prop(rd, "exr_zbuf")
369
370             if wide_ui:
371                 col = subsplit.column()
372             col.prop(rd, "exr_preview")
373
374         elif file_format == 'JPEG2000':
375             split = layout.split()
376             col = split.column()
377             col.label(text="Depth:")
378             col.row().prop(rd, "jpeg2k_depth", expand=True)
379
380             if wide_ui:
381                 col = split.column()
382             col.prop(rd, "jpeg2k_preset", text="")
383             col.prop(rd, "jpeg2k_ycc")
384
385         elif file_format in ('CINEON', 'DPX'):
386             split = layout.split()
387             col = split.column()
388             col.prop(rd, "cineon_log", text="Convert to Log")
389
390             if wide_ui:
391                 col = split.column(align=True)
392             col.active = rd.cineon_log
393             col.prop(rd, "cineon_black", text="Black")
394             col.prop(rd, "cineon_white", text="White")
395             col.prop(rd, "cineon_gamma", text="Gamma")
396
397         elif file_format == 'TIFF':
398             split = layout.split()
399             split.prop(rd, "tiff_bit")
400
401         elif file_format == 'QUICKTIME_CARBON':
402             split = layout.split()
403             split.operator("scene.render_data_set_quicktime_codec")
404
405         elif file_format == 'QUICKTIME_QTKIT':
406             split = layout.split()
407             col = split.column()
408             col.prop(rd, "quicktime_codec_type", text="Video Codec")
409             col.prop(rd, "quicktime_codec_spatial_quality", text="Quality")
410
411             # Audio
412             col.prop(rd, "quicktime_audiocodec_type", text="Audio Codec")
413             if rd.quicktime_audiocodec_type != 'No audio':
414                 split = layout.split()
415                 col = split.column()
416                 if rd.quicktime_audiocodec_type == 'LPCM':
417                     col.prop(rd, "quicktime_audio_bitdepth", text="")
418                 if wide_ui:
419                     col = split.column()
420                 col.prop(rd, "quicktime_audio_samplerate", text="")
421
422                 split = layout.split()
423                 col = split.column()
424                 if rd.quicktime_audiocodec_type == 'AAC':
425                     col.prop(rd, "quicktime_audio_bitrate")
426                 if wide_ui:
427                     subsplit = split.split()
428                     col = subsplit.column()
429                 if rd.quicktime_audiocodec_type == 'AAC':
430                     col.prop(rd, "quicktime_audio_codec_isvbr")
431                 if wide_ui:
432                     col = subsplit.column()
433                 col.prop(rd, "quicktime_audio_resampling_hq")
434
435
436 class RENDER_PT_encoding(RenderButtonsPanel, bpy.types.Panel):
437     bl_label = "Encoding"
438     bl_default_closed = True
439     COMPAT_ENGINES = {'BLENDER_RENDER'}
440
441     @staticmethod
442     def poll(context):
443         rd = context.scene.render
444         return rd.file_format in ('FFMPEG', 'XVID', 'H264', 'THEORA')
445
446     def draw(self, context):
447         layout = self.layout
448
449         rd = context.scene.render
450         wide_ui = context.region.width > narrowui
451
452         layout.menu("RENDER_MT_ffmpeg_presets", text="Presets")
453
454         split = layout.split()
455
456         col = split.column()
457         col.prop(rd, "ffmpeg_format")
458         if rd.ffmpeg_format in ('AVI', 'QUICKTIME', 'MKV', 'OGG'):
459             if wide_ui:
460                 col = split.column()
461             col.prop(rd, "ffmpeg_codec")
462         else:
463             if wide_ui:
464                 split.label()
465
466         split = layout.split()
467
468         col = split.column()
469         col.prop(rd, "ffmpeg_video_bitrate")
470         if wide_ui:
471             col = split.column()
472         col.prop(rd, "ffmpeg_gopsize")
473
474         split = layout.split()
475
476         col = split.column()
477         col.label(text="Rate:")
478         col.prop(rd, "ffmpeg_minrate", text="Minimum")
479         col.prop(rd, "ffmpeg_maxrate", text="Maximum")
480         col.prop(rd, "ffmpeg_buffersize", text="Buffer")
481
482         if wide_ui:
483             col = split.column()
484
485         col.prop(rd, "ffmpeg_autosplit")
486         col.label(text="Mux:")
487         col.prop(rd, "ffmpeg_muxrate", text="Rate")
488         col.prop(rd, "ffmpeg_packetsize", text="Packet Size")
489
490         # Audio:
491         sub = layout.column()
492
493         if rd.ffmpeg_format not in ('MP3'):
494             sub.prop(rd, "ffmpeg_audio_codec", text="Audio Codec")
495
496         sub.separator()
497
498         split = sub.split()
499
500         col = split.column()
501         col.prop(rd, "ffmpeg_audio_bitrate")
502         col.prop(rd, "ffmpeg_audio_mixrate")
503
504         if wide_ui:
505             col = split.column()
506         col.prop(rd, "ffmpeg_audio_volume", slider=True)
507
508
509 class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
510     bl_label = "Anti-Aliasing"
511     COMPAT_ENGINES = {'BLENDER_RENDER'}
512
513     @staticmethod
514     def poll(context):
515         rd = context.scene.render
516         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
517
518     def draw_header(self, context):
519         rd = context.scene.render
520
521         self.layout.prop(rd, "render_antialiasing", text="")
522
523     def draw(self, context):
524         layout = self.layout
525
526         rd = context.scene.render
527         wide_ui = context.region.width > narrowui
528         layout.active = rd.render_antialiasing
529
530         split = layout.split()
531
532         col = split.column()
533         col.row().prop(rd, "antialiasing_samples", expand=True)
534         sub = col.row()
535         sub.enabled = not rd.use_border
536         sub.prop(rd, "full_sample")
537
538         if wide_ui:
539             col = split.column()
540         col.prop(rd, "pixel_filter", text="")
541         col.prop(rd, "filter_size", text="Size")
542
543
544 class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
545     bl_label = "Full Sample Motion Blur"
546     bl_default_closed = True
547     COMPAT_ENGINES = {'BLENDER_RENDER'}
548
549     @staticmethod
550     def poll(context):
551         rd = context.scene.render
552         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
553
554     def draw_header(self, context):
555         rd = context.scene.render
556
557         self.layout.prop(rd, "motion_blur", text="")
558
559     def draw(self, context):
560         layout = self.layout
561
562         rd = context.scene.render
563         layout.active = rd.motion_blur
564
565         row = layout.row()
566         row.prop(rd, "motion_blur_samples")
567         row.prop(rd, "motion_blur_shutter")
568
569 class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
570     bl_label = "Dimensions"
571     COMPAT_ENGINES = {'BLENDER_RENDER'}
572
573     @staticmethod
574     def poll(context):
575         rd = context.scene.render
576         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
577
578     def draw(self, context):
579         layout = self.layout
580
581         scene = context.scene
582         rd = scene.render
583         wide_ui = context.region.width > narrowui
584
585         row = layout.row(align=True)
586         row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
587         row.operator("render.preset_add", text="", icon="ZOOMIN")
588
589         split = layout.split()
590
591         col = split.column()
592         sub = col.column(align=True)
593         sub.label(text="Resolution:")
594         sub.prop(rd, "resolution_x", text="X")
595         sub.prop(rd, "resolution_y", text="Y")
596         sub.prop(rd, "resolution_percentage", text="")
597
598         sub.label(text="Aspect Ratio:")
599         sub.prop(rd, "pixel_aspect_x", text="X")
600         sub.prop(rd, "pixel_aspect_y", text="Y")
601
602         row = col.row()
603         row.prop(rd, "use_border", text="Border")
604         sub = row.row()
605         sub.active = rd.use_border
606         sub.prop(rd, "crop_to_border", text="Crop")
607
608         if wide_ui:
609             col = split.column()
610         sub = col.column(align=True)
611         sub.label(text="Frame Range:")
612         sub.prop(scene, "frame_start", text="Start")
613         sub.prop(scene, "frame_end", text="End")
614         sub.prop(scene, "frame_step", text="Step")
615
616         sub.label(text="Frame Rate:")
617         sub.prop(rd, "fps")
618         sub.prop(rd, "fps_base", text="/")
619
620
621 class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
622     bl_label = "Stamp"
623     bl_default_closed = True
624     COMPAT_ENGINES = {'BLENDER_RENDER'}
625
626     @staticmethod
627     def poll(context):
628         rd = context.scene.render
629         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
630
631     def draw_header(self, context):
632         rd = context.scene.render
633
634         self.layout.prop(rd, "render_stamp", text="")
635
636     def draw(self, context):
637         layout = self.layout
638
639         rd = context.scene.render
640         wide_ui = context.region.width > narrowui
641
642         layout.active = rd.render_stamp
643
644         split = layout.split()
645
646         col = split.column()
647         col.prop(rd, "stamp_time", text="Time")
648         col.prop(rd, "stamp_date", text="Date")
649         col.prop(rd, "stamp_render_time", text="RenderTime")
650         col.prop(rd, "stamp_frame", text="Frame")
651         col.prop(rd, "stamp_scene", text="Scene")
652         col.prop(rd, "stamp_camera", text="Camera")
653         col.prop(rd, "stamp_filename", text="Filename")
654         col.prop(rd, "stamp_marker", text="Marker")
655         col.prop(rd, "stamp_sequencer_strip", text="Seq. Strip")
656
657         if wide_ui:
658             col = split.column()
659         col.active = rd.render_stamp
660         col.prop(rd, "stamp_foreground", slider=True)
661         col.prop(rd, "stamp_background", slider=True)
662         col.separator()
663         col.prop(rd, "stamp_font_size", text="Font Size")
664
665         row = layout.split(percentage=0.2)
666         row.prop(rd, "stamp_note", text="Note")
667         sub = row.row()
668         sub.active = rd.stamp_note
669         sub.prop(rd, "stamp_note_text", text="")
670
671
672 class RENDER_PT_bake(RenderButtonsPanel, bpy.types.Panel):
673     bl_label = "Bake"
674     bl_default_closed = True
675     COMPAT_ENGINES = {'BLENDER_RENDER'}
676
677     @staticmethod
678     def poll(context):
679         rd = context.scene.render
680         return (context.scene and rd.use_game_engine is False) and (rd.engine in __class__.COMPAT_ENGINES)
681
682     def draw(self, context):
683         layout = self.layout
684
685         rd = context.scene.render
686         wide_ui = context.region.width > narrowui
687
688         layout.operator("object.bake_image", icon='RENDER_STILL')
689
690         if wide_ui:
691             layout.prop(rd, "bake_type")
692         else:
693             layout.prop(rd, "bake_type", text="")
694
695         if rd.bake_type == 'NORMALS':
696             if wide_ui:
697                 layout.prop(rd, "bake_normal_space")
698             else:
699                 layout.prop(rd, "bake_normal_space", text="")
700         elif rd.bake_type in ('DISPLACEMENT', 'AO'):
701             layout.prop(rd, "bake_normalized")
702
703         # col.prop(rd, "bake_aa_mode")
704         # col.prop(rd, "bake_enable_aa")
705
706         layout.separator()
707
708         split = layout.split()
709
710         col = split.column()
711         col.prop(rd, "bake_clear")
712         col.prop(rd, "bake_margin")
713         col.prop(rd, "bake_quad_split", text="Split")
714
715         if wide_ui:
716             col = split.column()
717         col.prop(rd, "bake_active")
718         sub = col.column()
719         sub.active = rd.bake_active
720         sub.prop(rd, "bake_distance")
721         sub.prop(rd, "bake_bias")
722
723
724 def register():
725     pass
726
727
728 def unregister():
729     pass
730
731 if __name__ == "__main__":
732     register()