Merge branch 'master' into blender2.8
[blender.git] / intern / cycles / blender / addon / ui.py
1 #
2 # Copyright 2011-2013 Blender Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17 # <pep8 compliant>
18
19 import bpy
20 from bpy_extras.node_utils import find_node_input
21 from bl_operators.presets import PresetMenu
22
23 from bpy.types import (
24     Panel,
25     Menu,
26     Operator,
27 )
28
29
30 class CYCLES_PT_sampling_presets(PresetMenu):
31     bl_label = "Sampling Presets"
32     preset_subdir = "cycles/sampling"
33     preset_operator = "script.execute_preset"
34     preset_add_operator = "render.cycles_sampling_preset_add"
35     COMPAT_ENGINES = {'CYCLES'}
36
37
38 class CYCLES_PT_integrator_presets(PresetMenu):
39     bl_label = "Integrator Presets"
40     preset_subdir = "cycles/integrator"
41     preset_operator = "script.execute_preset"
42     preset_add_operator = "render.cycles_integrator_preset_add"
43     COMPAT_ENGINES = {'CYCLES'}
44
45
46 class CyclesButtonsPanel:
47     bl_space_type = "PROPERTIES"
48     bl_region_type = "WINDOW"
49     bl_context = "render"
50     COMPAT_ENGINES = {'CYCLES'}
51
52     @classmethod
53     def poll(cls, context):
54         return context.engine in cls.COMPAT_ENGINES
55
56
57 def get_device_type(context):
58     return context.user_preferences.addons[__package__].preferences.compute_device_type
59
60
61 def use_cpu(context):
62     cscene = context.scene.cycles
63
64     return (get_device_type(context) == 'NONE' or cscene.device == 'CPU')
65
66
67 def use_opencl(context):
68     cscene = context.scene.cycles
69
70     return (get_device_type(context) == 'OPENCL' and cscene.device == 'GPU')
71
72
73 def use_cuda(context):
74     cscene = context.scene.cycles
75
76     return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU')
77
78
79 def use_branched_path(context):
80     cscene = context.scene.cycles
81
82     return (cscene.progressive == 'BRANCHED_PATH')
83
84
85 def use_sample_all_lights(context):
86     cscene = context.scene.cycles
87
88     return cscene.sample_all_lights_direct or cscene.sample_all_lights_indirect
89
90
91 def show_device_active(context):
92     cscene = context.scene.cycles
93     if cscene.device != 'GPU':
94         return True
95     return context.user_preferences.addons[__package__].preferences.has_active_device()
96
97
98 def draw_samples_info(layout, context):
99     cscene = context.scene.cycles
100     integrator = cscene.progressive
101
102     # Calculate sample values
103     if integrator == 'PATH':
104         aa = cscene.samples
105         if cscene.use_square_samples:
106             aa = aa * aa
107     else:
108         aa = cscene.aa_samples
109         d = cscene.diffuse_samples
110         g = cscene.glossy_samples
111         t = cscene.transmission_samples
112         ao = cscene.ao_samples
113         ml = cscene.mesh_light_samples
114         sss = cscene.subsurface_samples
115         vol = cscene.volume_samples
116
117         if cscene.use_square_samples:
118             aa = aa * aa
119             d = d * d
120             g = g * g
121             t = t * t
122             ao = ao * ao
123             ml = ml * ml
124             sss = sss * sss
125             vol = vol * vol
126
127     # Draw interface
128     # Do not draw for progressive, when Square Samples are disabled
129     if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'):
130         col = layout.column(align=True)
131         col.scale_y = 0.6
132         col.label(text="Total Samples:")
133         col.separator()
134         if integrator == 'PATH':
135             col.label(text="%s AA" % aa)
136         else:
137             col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
138                       (aa, d * aa, g * aa, t * aa))
139             col.separator()
140             col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
141                       (ao * aa, ml * aa, sss * aa, vol * aa))
142
143
144 class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
145     bl_label = "Sampling"
146     bl_options = {'DEFAULT_CLOSED'}
147
148     def draw_header_preset(self, context):
149         CYCLES_PT_sampling_presets.draw_panel_header(self.layout)
150
151     def draw(self, context):
152         layout = self.layout
153
154         scene = context.scene
155         cscene = scene.cycles
156
157         layout.use_property_split = True
158         layout.use_property_decorate = False
159
160         layout.prop(cscene, "progressive")
161
162         if cscene.progressive == 'PATH' or use_branched_path(context) is False:
163             col = layout.column(align=True)
164             col.prop(cscene, "samples", text="Render")
165             col.prop(cscene, "preview_samples", text="Viewport")
166
167             draw_samples_info(layout, context)
168         else:
169             col = layout.column(align=True)
170             col.prop(cscene, "aa_samples", text="Render")
171             col.prop(cscene, "preview_aa_samples", text="Viewport")
172
173
174 class CYCLES_RENDER_PT_sampling_light(CyclesButtonsPanel, Panel):
175     bl_label = "Light"
176     bl_parent_id = "CYCLES_RENDER_PT_sampling"
177     bl_options = {'DEFAULT_CLOSED'}
178
179     def draw(self, context):
180         layout = self.layout
181         layout.use_property_split = True
182         layout.use_property_decorate = False
183
184         scene = context.scene
185         cscene = scene.cycles
186
187         col = layout.column(align=True)
188         col.prop(cscene, "light_sampling_threshold", text="Light Threshold")
189
190         if cscene.progressive != 'PATH' and use_branched_path(context):
191             col = layout.column(align=True)
192             col.prop(cscene, "sample_all_lights_direct")
193             col.prop(cscene, "sample_all_lights_indirect")
194
195         col = layout.column(align=True)
196         col.prop(cscene, "sample_clamp_direct")
197         col.prop(cscene, "sample_clamp_indirect")
198
199
200 class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel):
201     bl_label = "Sub Samples"
202     bl_parent_id = "CYCLES_RENDER_PT_sampling"
203
204     @classmethod
205     def poll(self, context):
206         scene = context.scene
207         cscene = scene.cycles
208         return cscene.progressive != 'PATH' and use_branched_path(context)
209
210     def draw(self, context):
211         layout = self.layout
212         layout.use_property_split = True
213         layout.use_property_decorate = False
214
215         scene = context.scene
216         cscene = scene.cycles
217
218         col = layout.column(align=True)
219         col.prop(cscene, "diffuse_samples", text="Diffuse")
220         col.prop(cscene, "glossy_samples", text="Glossy")
221         col.prop(cscene, "transmission_samples", text="Transmission")
222         col.prop(cscene, "ao_samples", text="AO")
223
224         sub = col.row(align=True)
225         sub.active = use_sample_all_lights(context)
226         sub.prop(cscene, "mesh_light_samples", text="Mesh Light")
227         col.prop(cscene, "subsurface_samples", text="Subsurface")
228         col.prop(cscene, "volume_samples", text="Volume")
229
230         draw_samples_info(layout, context)
231
232
233 class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
234     bl_label = "Advanced"
235     bl_parent_id = "CYCLES_RENDER_PT_sampling"
236     bl_options = {'DEFAULT_CLOSED'}
237
238     def draw(self, context):
239         layout = self.layout
240         layout.use_property_split = True
241         layout.use_property_decorate = False
242
243         scene = context.scene
244         cscene = scene.cycles
245
246         row = layout.row(align=True)
247         row.prop(cscene, "seed")
248         row.prop(cscene, "use_animated_seed", text="", icon='TIME')
249
250         layout.prop(cscene, "sampling_pattern", text="Pattern")
251
252         layout.prop(cscene, "use_square_samples")
253
254
255 class CYCLES_RENDER_PT_sampling_total(CyclesButtonsPanel, Panel):
256     bl_label = "Total Samples"
257     bl_parent_id = "CYCLES_RENDER_PT_sampling"
258
259     @classmethod
260     def poll(self, context):
261         scene = context.scene
262         cscene = scene.cycles
263
264         if cscene.use_square_samples:
265             return True
266
267         return cscene.progressive != 'PATH' and use_branched_path(context)
268
269     def draw(self, context):
270         layout = self.layout
271         cscene = context.scene.cycles
272         integrator = cscene.progressive
273
274         # Calculate sample values
275         if integrator == 'PATH':
276             aa = cscene.samples
277             if cscene.use_square_samples:
278                 aa = aa * aa
279         else:
280             aa = cscene.aa_samples
281             d = cscene.diffuse_samples
282             g = cscene.glossy_samples
283             t = cscene.transmission_samples
284             ao = cscene.ao_samples
285             ml = cscene.mesh_light_samples
286             sss = cscene.subsurface_samples
287             vol = cscene.volume_samples
288
289             if cscene.use_square_samples:
290                 aa = aa * aa
291                 d = d * d
292                 g = g * g
293                 t = t * t
294                 ao = ao * ao
295                 ml = ml * ml
296                 sss = sss * sss
297                 vol = vol * vol
298
299         col = layout.column(align=True)
300         col.scale_y = 0.6
301         if integrator == 'PATH':
302             col.label(text="%s AA" % aa)
303         else:
304             col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
305                       (aa, d * aa, g * aa, t * aa))
306             col.separator()
307             col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
308                       (ao * aa, ml * aa, sss * aa, vol * aa))
309
310
311 class CYCLES_RENDER_PT_geometry(CyclesButtonsPanel, Panel):
312     bl_label = "Geometry"
313     bl_options = {'DEFAULT_CLOSED'}
314
315     def draw(self, context):
316         pass
317
318
319 class CYCLES_RENDER_PT_geometry_subdivision(CyclesButtonsPanel, Panel):
320     bl_label = "Subdivision"
321     bl_parent_id = "CYCLES_RENDER_PT_geometry"
322
323     @classmethod
324     def poll(self, context):
325         return context.scene.cycles.feature_set == 'EXPERIMENTAL'
326
327     def draw(self, context):
328         layout = self.layout
329         layout.use_property_split = True
330         layout.use_property_decorate = False
331
332         scene = context.scene
333         cscene = scene.cycles
334
335         col = layout.column()
336         sub = col.column(align=True)
337         sub.prop(cscene, "dicing_rate", text="Dicing Rate Render")
338         sub.prop(cscene, "preview_dicing_rate", text="Preview")
339
340         col.separator()
341
342         col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale")
343         col.prop(cscene, "max_subdivisions")
344
345         col.prop(cscene, "dicing_camera")
346
347
348 class CYCLES_RENDER_PT_geometry_volume(CyclesButtonsPanel, Panel):
349     bl_label = "Volume"
350     bl_parent_id = "CYCLES_RENDER_PT_geometry"
351
352     def draw(self, context):
353         layout = self.layout
354         layout.use_property_split = True
355         layout.use_property_decorate = False
356
357         scene = context.scene
358         cscene = scene.cycles
359         ccscene = scene.cycles_curves
360
361         col = layout.column()
362         col.prop(cscene, "volume_step_size", text="Step Size")
363         col.prop(cscene, "volume_max_steps", text="Max Steps")
364
365
366 class CYCLES_RENDER_PT_geometry_hair(CyclesButtonsPanel, Panel):
367     bl_label = "Hair"
368     bl_parent_id = "CYCLES_RENDER_PT_geometry"
369
370     def draw_header(self, context):
371         layout = self.layout
372         scene = context.scene
373         cscene = scene.cycles
374         ccscene = scene.cycles_curves
375
376         layout.prop(ccscene, "use_curves", text="")
377
378     def draw(self, context):
379         layout = self.layout
380         layout.use_property_split = True
381         layout.use_property_decorate = False
382
383         scene = context.scene
384         cscene = scene.cycles
385         ccscene = scene.cycles_curves
386
387         layout.active = ccscene.use_curves
388
389         col = layout.column()
390         col.prop(ccscene, "minimum_width", text="Min Pixels")
391         col.prop(ccscene, "maximum_width", text="Max Extension")
392         col.prop(ccscene, "shape", text="Shape")
393         if not (ccscene.primitive in {'CURVE_SEGMENTS', 'LINE_SEGMENTS'} and ccscene.shape == 'RIBBONS'):
394             col.prop(ccscene, "cull_backfacing", text="Cull back-faces")
395         col.prop(ccscene, "primitive", text="Primitive")
396
397         if ccscene.primitive == 'TRIANGLES' and ccscene.shape == 'THICK':
398             col.prop(ccscene, "resolution", text="Resolution")
399         elif ccscene.primitive == 'CURVE_SEGMENTS':
400             col.prop(ccscene, "subdivisions", text="Curve subdivisions")
401
402
403 class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel):
404     bl_label = "Light Paths"
405     bl_options = {'DEFAULT_CLOSED'}
406
407     def draw_header_preset(self, context):
408         CYCLES_PT_integrator_presets.draw_panel_header(self.layout)
409
410     def draw(self, context):
411         pass
412
413
414 class CYCLES_RENDER_PT_light_paths_max_bounces(CyclesButtonsPanel, Panel):
415     bl_label = "Max Bounces"
416     bl_parent_id = "CYCLES_RENDER_PT_light_paths"
417
418     def draw(self, context):
419         layout = self.layout
420         layout.use_property_split = True
421         layout.use_property_decorate = False
422
423         scene = context.scene
424         cscene = scene.cycles
425
426         col = layout.column(align=True)
427         col.prop(cscene, "max_bounces", text="Total")
428
429         col = layout.column(align=True)
430         col.prop(cscene, "diffuse_bounces", text="Diffuse")
431         col.prop(cscene, "glossy_bounces", text="Glossy")
432         col.prop(cscene, "transparent_max_bounces", text="Transparency")
433         col.prop(cscene, "transmission_bounces", text="Transmission")
434         col.prop(cscene, "volume_bounces", text="Volume")
435
436
437 class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
438     bl_label = "Caustics"
439     bl_parent_id = "CYCLES_RENDER_PT_light_paths"
440     bl_options = {'DEFAULT_CLOSED'}
441
442     def draw(self, context):
443         layout = self.layout
444         layout.use_property_split = True
445         layout.use_property_decorate = False
446
447         scene = context.scene
448         cscene = scene.cycles
449
450         col = layout.column()
451         col.prop(cscene, "blur_glossy")
452         col.prop(cscene, "caustics_reflective")
453         col.prop(cscene, "caustics_refractive")
454
455
456 class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
457     bl_label = "Motion Blur"
458     bl_options = {'DEFAULT_CLOSED'}
459
460     def draw_header(self, context):
461         rd = context.scene.render
462
463         self.layout.prop(rd, "use_motion_blur", text="")
464
465     def draw(self, context):
466         layout = self.layout
467         layout.use_property_split = True
468         layout.use_property_decorate = False
469
470         scene = context.scene
471         cscene = scene.cycles
472         rd = scene.render
473         layout.active = rd.use_motion_blur
474
475         col = layout.column()
476         col.prop(cscene, "motion_blur_position", text="Position")
477         col.prop(rd, "motion_blur_shutter")
478         col.separator()
479         col.prop(cscene, "rolling_shutter_type", text="Rolling Shutter")
480         sub = col.column()
481         sub.active = cscene.rolling_shutter_type != 'NONE'
482         sub.prop(cscene, "rolling_shutter_duration")
483
484
485 class CYCLES_RENDER_PT_motion_blur_curve(CyclesButtonsPanel, Panel):
486     bl_label = "Shutter Curve"
487     bl_parent_id = "CYCLES_RENDER_PT_motion_blur"
488     bl_options = {'DEFAULT_CLOSED'}
489
490     def draw(self, context):
491         layout = self.layout
492         layout.use_property_split = True
493         layout.use_property_decorate = False
494
495         scene = context.scene
496         cscene = scene.cycles
497         rd = scene.render
498         layout.active = rd.use_motion_blur
499
500         col = layout.column()
501
502         col.template_curve_mapping(rd, "motion_blur_shutter_curve")
503
504         col = layout.column(align=True)
505         row = col.row(align=True)
506         row.operator("render.shutter_curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
507         row.operator("render.shutter_curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
508         row.operator("render.shutter_curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
509         row.operator("render.shutter_curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
510         row.operator("render.shutter_curve_preset", icon='LINCURVE', text="").shape = 'LINE'
511         row.operator("render.shutter_curve_preset", icon='NOCURVE', text="").shape = 'MAX'
512
513
514 class CYCLES_RENDER_PT_film(CyclesButtonsPanel, Panel):
515     bl_label = "Film"
516     bl_options = {'DEFAULT_CLOSED'}
517
518     def draw(self, context):
519         layout = self.layout
520         layout.use_property_split = True
521         layout.use_property_decorate = False
522         scene = context.scene
523         cscene = scene.cycles
524
525         col = layout.column()
526         col.prop(cscene, "film_exposure")
527
528
529 class CYCLES_RENDER_PT_film_transparency(CyclesButtonsPanel, Panel):
530     bl_label = "Transparency"
531     bl_parent_id = "CYCLES_RENDER_PT_film"
532
533     def draw_header(self, context):
534         layout = self.layout
535         rd = context.scene.render
536
537         scene = context.scene
538         cscene = scene.cycles
539
540         layout.prop(cscene, "film_transparent", text="")
541
542     def draw(self, context):
543         layout = self.layout
544         layout.use_property_split = True
545         layout.use_property_decorate = False
546         scene = context.scene
547         cscene = scene.cycles
548
549         layout.active = cscene.film_transparent
550
551         col = layout.column()
552         col.prop(cscene, "film_transparent_glass", text="Transparent Glass")
553
554         sub = col.column()
555         sub.active = cscene.film_transparent and cscene.film_transparent_glass
556         sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold")
557
558
559 class CYCLES_RENDER_PT_film_pixel_filter(CyclesButtonsPanel, Panel):
560     bl_label = "Pixel Filter"
561     bl_parent_id = "CYCLES_RENDER_PT_film"
562     bl_options = {'DEFAULT_CLOSED'}
563
564     def draw(self, context):
565         layout = self.layout
566         layout.use_property_split = True
567         layout.use_property_decorate = False
568         scene = context.scene
569         cscene = scene.cycles
570
571         col = layout.column()
572         col.prop(cscene, "pixel_filter_type", text="Type")
573         if cscene.pixel_filter_type != 'BOX':
574             col.prop(cscene, "filter_width", text="Width")
575
576
577 class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel):
578     bl_label = "Performance"
579     bl_options = {'DEFAULT_CLOSED'}
580
581     def draw(self, context):
582         layout = self.layout
583         layout.use_property_split = True
584         layout.use_property_decorate = False
585
586         scene = context.scene
587         rd = scene.render
588         cscene = scene.cycles
589
590         col = layout.column()
591         col.active = show_device_active(context)
592         col.prop(cscene, "device")
593
594         from . import engine
595         if engine.with_osl() and use_cpu(context):
596             col.prop(cscene, "shading_system")
597
598
599 class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel):
600     bl_label = "Threads"
601     bl_parent_id = "CYCLES_RENDER_PT_performance"
602
603     def draw(self, context):
604         layout = self.layout
605         layout.use_property_split = True
606         layout.use_property_decorate = False
607
608         scene = context.scene
609         rd = scene.render
610         cscene = scene.cycles
611
612         col = layout.column()
613
614         col.prop(rd, "threads_mode")
615         sub = col.column(align=True)
616         sub.enabled = rd.threads_mode == 'FIXED'
617         sub.prop(rd, "threads")
618
619
620 class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
621     bl_label = "Tiles"
622     bl_parent_id = "CYCLES_RENDER_PT_performance"
623
624     def draw(self, context):
625         layout = self.layout
626         layout.use_property_split = True
627         layout.use_property_decorate = False
628
629         scene = context.scene
630         rd = scene.render
631         cscene = scene.cycles
632
633         col = layout.column()
634
635         sub = col.column(align=True)
636         sub.prop(rd, "tile_x", text="Tiles X")
637         sub.prop(rd, "tile_y", text="Y")
638         col.prop(cscene, "tile_order", text="Order")
639
640         sub = col.column()
641         sub.active = not rd.use_save_buffers
642         for view_layer in scene.view_layers:
643             if view_layer.cycles.use_denoising:
644                 sub.active = False
645         sub.prop(cscene, "use_progressive_refine")
646
647
648 class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Panel):
649     bl_label = "Acceleration Structure"
650     bl_parent_id = "CYCLES_RENDER_PT_performance"
651     bl_options = {'DEFAULT_CLOSED'}
652
653     def draw(self, context):
654         layout = self.layout
655         layout.use_property_split = True
656         layout.use_property_decorate = False
657
658         scene = context.scene
659         rd = scene.render
660         cscene = scene.cycles
661
662         col = layout.column()
663
664         col.prop(cscene, "debug_use_spatial_splits")
665         col.prop(cscene, "debug_use_hair_bvh")
666         sub = col.column()
667         sub.active = not cscene.debug_use_spatial_splits
668         sub.prop(cscene, "debug_bvh_time_steps")
669
670
671 class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
672     bl_label = "Final Render"
673     bl_parent_id = "CYCLES_RENDER_PT_performance"
674     bl_options = {'DEFAULT_CLOSED'}
675
676     def draw(self, context):
677         layout = self.layout
678         layout.use_property_split = True
679         layout.use_property_decorate = False
680
681         scene = context.scene
682         rd = scene.render
683         cscene = scene.cycles
684
685         col = layout.column()
686
687         col.prop(rd, "use_save_buffers")
688         col.prop(rd, "use_persistent_data", text="Persistent Images")
689
690
691 class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
692     bl_label = "Viewport"
693     bl_parent_id = "CYCLES_RENDER_PT_performance"
694     bl_options = {'DEFAULT_CLOSED'}
695
696     def draw(self, context):
697         layout = self.layout
698         layout.use_property_split = True
699         layout.use_property_decorate = False
700
701         scene = context.scene
702         rd = scene.render
703         cscene = scene.cycles
704
705         col = layout.column()
706         col.prop(rd, "preview_pixel_size", text="Pixel Size")
707         col.prop(cscene, "preview_start_resolution", text="Start Pixels")
708
709
710 class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
711     bl_label = "Filter"
712     bl_options = {'DEFAULT_CLOSED'}
713     bl_context = "view_layer"
714
715     def draw(self, context):
716         layout = self.layout
717         layout.use_property_split = True
718         layout.use_property_decorate = False
719
720         with_freestyle = bpy.app.build_options.freestyle
721
722         scene = context.scene
723         rd = scene.render
724         view_layer = context.view_layer
725
726         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
727
728         col = flow.column()
729         col.prop(view_layer, "use_sky", text="Use Environment")
730         col = flow.column()
731         col.prop(view_layer, "use_ao", text="Use Ambient Occlusion")
732         col = flow.column()
733         col.prop(view_layer, "use_solid", text="Use Surfaces")
734         col = flow.column()
735         col.prop(view_layer, "use_strand", text="Use Hair")
736         if with_freestyle:
737             col = flow.column()
738             col.prop(view_layer, "use_freestyle", text="Use Freestyle")
739             col.active = rd.use_freestyle
740
741
742 class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel):
743     bl_label = "Passes"
744     bl_context = "view_layer"
745     bl_options = {'DEFAULT_CLOSED'}
746
747     def draw(self, context):
748         import _cycles
749
750         layout = self.layout
751
752         scene = context.scene
753         rd = scene.render
754         view_layer = context.view_layer
755         cycles_view_layer = view_layer.cycles
756
757         split = layout.split()
758
759         col = split.column()
760         col.prop(view_layer, "use_pass_combined")
761         col.prop(view_layer, "use_pass_z")
762         col.prop(view_layer, "use_pass_mist")
763         col.prop(view_layer, "use_pass_normal")
764         row = col.row()
765         row.prop(view_layer, "use_pass_vector")
766         row.active = not rd.use_motion_blur
767         col.prop(view_layer, "use_pass_uv")
768         col.prop(view_layer, "use_pass_object_index")
769         col.prop(view_layer, "use_pass_material_index")
770         col.separator()
771         col.prop(view_layer, "use_pass_shadow")
772         col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
773         col.separator()
774         col.prop(cycles_view_layer, "denoising_store_passes", text="Denoising Data")
775         col.separator()
776         col.prop(view_layer, "pass_alpha_threshold")
777
778         col = split.column()
779         col.label(text="Diffuse:")
780         row = col.row(align=True)
781         row.prop(view_layer, "use_pass_diffuse_direct", text="Direct", toggle=True)
782         row.prop(view_layer, "use_pass_diffuse_indirect", text="Indirect", toggle=True)
783         row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True)
784         col.label(text="Glossy:")
785         row = col.row(align=True)
786         row.prop(view_layer, "use_pass_glossy_direct", text="Direct", toggle=True)
787         row.prop(view_layer, "use_pass_glossy_indirect", text="Indirect", toggle=True)
788         row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True)
789         col.label(text="Transmission:")
790         row = col.row(align=True)
791         row.prop(view_layer, "use_pass_transmission_direct", text="Direct", toggle=True)
792         row.prop(view_layer, "use_pass_transmission_indirect", text="Indirect", toggle=True)
793         row.prop(view_layer, "use_pass_transmission_color", text="Color", toggle=True)
794         col.label(text="Subsurface:")
795         row = col.row(align=True)
796         row.prop(view_layer, "use_pass_subsurface_direct", text="Direct", toggle=True)
797         row.prop(view_layer, "use_pass_subsurface_indirect", text="Indirect", toggle=True)
798         row.prop(view_layer, "use_pass_subsurface_color", text="Color", toggle=True)
799         col.label(text="Volume:")
800         row = col.row(align=True)
801         row.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct", toggle=True)
802         row.prop(cycles_view_layer, "use_pass_volume_indirect", text="Indirect", toggle=True)
803
804         col.separator()
805         col.prop(view_layer, "use_pass_emit", text="Emission")
806         col.prop(view_layer, "use_pass_environment")
807
808         col = layout.column()
809         col.prop(cycles_view_layer, "pass_debug_render_time")
810         if _cycles.with_cycles_debug:
811             col.prop(cycles_view_layer, "pass_debug_bvh_traversed_nodes")
812             col.prop(cycles_view_layer, "pass_debug_bvh_traversed_instances")
813             col.prop(cycles_view_layer, "pass_debug_bvh_intersections")
814             col.prop(cycles_view_layer, "pass_debug_ray_bounces")
815
816         layout.label(text="Cryptomatte:")
817         row = layout.row(align=True)
818         row.prop(cycles_view_layer, "use_pass_crypto_object", text="Object", toggle=True)
819         row.prop(cycles_view_layer, "use_pass_crypto_material", text="Material", toggle=True)
820         row.prop(cycles_view_layer, "use_pass_crypto_asset", text="Asset", toggle=True)
821         row = layout.row(align=True)
822         row.prop(cycles_view_layer, "pass_crypto_depth")
823         row = layout.row(align=True)
824         row.active = use_cpu(context)
825         row.prop(cycles_view_layer, "pass_crypto_accurate", text="Accurate Mode")
826
827
828 class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
829     bl_label = "Denoising"
830     bl_context = "view_layer"
831     bl_options = {'DEFAULT_CLOSED'}
832
833     def draw_header(self, context):
834         scene = context.scene
835         view_layer = context.view_layer
836         cycles_view_layer = view_layer.cycles
837         cscene = scene.cycles
838         layout = self.layout
839
840         layout.prop(cycles_view_layer, "use_denoising", text="")
841
842     def draw(self, context):
843         layout = self.layout
844         layout.use_property_split = True
845         layout.use_property_decorate = False
846
847         scene = context.scene
848         cscene = scene.cycles
849         view_layer = context.view_layer
850         cycles_view_layer = view_layer.cycles
851
852         split = layout.split()
853         split.active = cycles_view_layer.use_denoising
854
855         layout = layout.column(align=True)
856         layout.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
857         layout.prop(cycles_view_layer, "denoising_relative_pca")
858
859         layout.separator()
860
861         row = layout.row(align=True)
862         row.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
863         row.label(text="Diffuse")
864         row.use_property_split = False
865         row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True)
866         row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True)
867
868         row = layout.row(align=True)
869         row.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
870         row.label(text="Glossy")
871         row.use_property_split = False
872         row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True)
873         row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True)
874
875         row = layout.row(align=True)
876         row.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
877         row.label(text="Transmission")
878         row.use_property_split = False
879         row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True)
880         row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True)
881
882         row = layout.row(align=True)
883         row.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
884         row.label(text="Subsurface")
885         row.use_property_split = False
886         row.prop(cycles_view_layer, "denoising_subsurface_direct", text="Direct", toggle=True)
887         row.prop(cycles_view_layer, "denoising_subsurface_indirect", text="Indirect", toggle=True)
888
889
890 class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
891     bl_label = "Post Processing"
892     bl_options = {'DEFAULT_CLOSED'}
893
894     def draw(self, context):
895         layout = self.layout
896         layout.use_property_split = True
897         layout.use_property_decorate = False
898
899         rd = context.scene.render
900
901         col = layout.column(align=True)
902         col.prop(rd, "use_compositing")
903         col.prop(rd, "use_sequencer")
904
905         layout.prop(rd, "dither_intensity", text="Dither", slider=True)
906
907
908 class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel):
909     bl_label = "Depth of Field"
910     bl_context = "data"
911
912     @classmethod
913     def poll(cls, context):
914         return context.camera and CyclesButtonsPanel.poll(context)
915
916     def draw(self, context):
917         layout = self.layout
918         layout.use_property_split = True
919
920         cam = context.camera
921         ccam = cam.cycles
922         dof_options = cam.gpu_dof
923
924         split = layout.split()
925
926         col = split.column()
927         col.prop(cam, "dof_object", text="Focus Object")
928
929         sub = col.row()
930         sub.active = cam.dof_object is None
931         sub.prop(cam, "dof_distance", text="Distance")
932
933
934 class CYCLES_CAMERA_PT_dof_aperture(CyclesButtonsPanel, Panel):
935     bl_label = "Aperture"
936     bl_parent_id = "CYCLES_CAMERA_PT_dof"
937
938     @classmethod
939     def poll(cls, context):
940         return context.camera and CyclesButtonsPanel.poll(context)
941
942     def draw(self, context):
943         layout = self.layout
944         layout.use_property_split = True
945         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
946
947         cam = context.camera
948         ccam = cam.cycles
949         dof_options = cam.gpu_dof
950
951         col = flow.column()
952         col.prop(ccam, "aperture_type")
953         if ccam.aperture_type == 'RADIUS':
954             col.prop(ccam, "aperture_size", text="Size")
955         elif ccam.aperture_type == 'FSTOP':
956             col.prop(ccam, "aperture_fstop", text="Number")
957         col.separator()
958
959         col = flow.column()
960         col.prop(ccam, "aperture_blades", text="Blades")
961         col.prop(ccam, "aperture_rotation", text="Rotation")
962         col.prop(ccam, "aperture_ratio", text="Ratio")
963
964
965 class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel):
966     bl_label = "Viewport"
967     bl_parent_id = "CYCLES_CAMERA_PT_dof"
968
969     @classmethod
970     def poll(cls, context):
971         return context.camera and CyclesButtonsPanel.poll(context)
972
973     def draw(self, context):
974         layout = self.layout
975         layout.use_property_split = True
976         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
977
978         cam = context.camera
979         dof_options = cam.gpu_dof
980
981         sub = flow.column(align=True)
982         sub.prop(dof_options, "fstop")
983         sub.prop(dof_options, "blades")
984
985
986 class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
987     bl_label = ""
988     bl_context = "material"
989     bl_options = {'HIDE_HEADER'}
990
991     @classmethod
992     def poll(cls, context):
993         if context.active_object and context.active_object.type == 'GPENCIL':
994             return False
995         else:
996             return (context.material or context.object) and CyclesButtonsPanel.poll(context)
997
998     def draw(self, context):
999         layout = self.layout
1000
1001         mat = context.material
1002         ob = context.object
1003         slot = context.material_slot
1004         space = context.space_data
1005
1006         if ob:
1007             is_sortable = len(ob.material_slots) > 1
1008             rows = 1
1009             if (is_sortable):
1010                 rows = 4
1011
1012             row = layout.row()
1013
1014             row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
1015
1016             col = row.column(align=True)
1017             col.operator("object.material_slot_add", icon='ADD', text="")
1018             col.operator("object.material_slot_remove", icon='REMOVE', text="")
1019
1020             col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
1021
1022             if is_sortable:
1023                 col.separator()
1024
1025                 col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
1026                 col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
1027
1028             if ob.mode == 'EDIT':
1029                 row = layout.row(align=True)
1030                 row.operator("object.material_slot_assign", text="Assign")
1031                 row.operator("object.material_slot_select", text="Select")
1032                 row.operator("object.material_slot_deselect", text="Deselect")
1033
1034         split = layout.split(factor=0.65)
1035
1036         if ob:
1037             split.template_ID(ob, "active_material", new="material.new")
1038             row = split.row()
1039
1040             if slot:
1041                 row.prop(slot, "link", text="")
1042             else:
1043                 row.label()
1044         elif mat:
1045             split.template_ID(space, "pin_id")
1046             split.separator()
1047
1048
1049 class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
1050     bl_label = "Motion Blur"
1051     bl_context = "object"
1052     bl_options = {'DEFAULT_CLOSED'}
1053
1054     @classmethod
1055     def poll(cls, context):
1056         ob = context.object
1057         if CyclesButtonsPanel.poll(context) and ob:
1058             if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA'}:
1059                 return True
1060             if ob.dupli_type == 'COLLECTION' and ob.dupli_group:
1061                 return True
1062             # TODO(sergey): More duplicator types here?
1063         return False
1064
1065     def draw_header(self, context):
1066         layout = self.layout
1067
1068         rd = context.scene.render
1069         # scene = context.scene
1070
1071         layout.active = rd.use_motion_blur
1072
1073         ob = context.object
1074         cob = ob.cycles
1075
1076         layout.prop(cob, "use_motion_blur", text="")
1077
1078     def draw(self, context):
1079         layout = self.layout
1080
1081         rd = context.scene.render
1082         # scene = context.scene
1083
1084         ob = context.object
1085         cob = ob.cycles
1086
1087         layout.active = (rd.use_motion_blur and cob.use_motion_blur)
1088
1089         row = layout.row()
1090         if ob.type != 'CAMERA':
1091             row.prop(cob, "use_deform_motion", text="Deformation")
1092         row.prop(cob, "motion_steps", text="Steps")
1093
1094
1095 class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel):
1096     bl_label = "Cycles Settings"
1097     bl_context = "object"
1098     bl_options = {'DEFAULT_CLOSED'}
1099
1100     @classmethod
1101     def poll(cls, context):
1102         ob = context.object
1103         return (CyclesButtonsPanel.poll(context) and
1104                 ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or
1105                         (ob.dupli_type == 'COLLECTION' and ob.dupli_group)))
1106
1107     def draw(self, context):
1108         pass
1109
1110
1111 class CYCLES_OBJECT_PT_cycles_settings_ray_visibility(CyclesButtonsPanel, Panel):
1112     bl_label = "Ray Visibility"
1113     bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings"
1114     bl_context = "object"
1115
1116     def draw(self, context):
1117         layout = self.layout
1118         layout.use_property_split = True
1119         layout.use_property_decorate = False
1120
1121         scene = context.scene
1122         cscene = scene.cycles
1123         ob = context.object
1124         cob = ob.cycles
1125         visibility = ob.cycles_visibility
1126
1127         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1128
1129         col = flow.column()
1130         col.prop(visibility, "camera")
1131         col = flow.column()
1132         col.prop(visibility, "diffuse")
1133         col = flow.column()
1134         col.prop(visibility, "glossy")
1135         col = flow.column()
1136         col.prop(visibility, "transmission")
1137         col = flow.column()
1138         col.prop(visibility, "scatter")
1139
1140         if ob.type != 'LIGHT':
1141             col = flow.column()
1142             col.prop(visibility, "shadow")
1143
1144         layout.separator()
1145
1146         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1147
1148         col = flow.column()
1149         col.prop(cob, "is_shadow_catcher")
1150         col = flow.column()
1151         col.prop(cob, "is_holdout")
1152
1153
1154 class CYCLES_OBJECT_PT_cycles_settings_performance(CyclesButtonsPanel, Panel):
1155     bl_label = "Performance"
1156     bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings"
1157     bl_context = "object"
1158
1159
1160     def draw(self, context):
1161         layout = self.layout
1162         layout.use_property_split = True
1163         layout.use_property_decorate = False
1164
1165         scene = context.scene
1166         cscene = scene.cycles
1167         ob = context.object
1168         cob = ob.cycles
1169         visibility = ob.cycles_visibility
1170
1171         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1172
1173         col = flow.column()
1174         col.active = scene.render.use_simplify and cscene.use_camera_cull
1175         col.prop(cob, "use_camera_cull")
1176
1177         col = flow.column()
1178         col.active = scene.render.use_simplify and cscene.use_distance_cull
1179         col.prop(cob, "use_distance_cull")
1180
1181
1182 class CYCLES_OT_use_shading_nodes(Operator):
1183     """Enable nodes on a material, world or light"""
1184     bl_idname = "cycles.use_shading_nodes"
1185     bl_label = "Use Nodes"
1186
1187     @classmethod
1188     def poll(cls, context):
1189         return (getattr(context, "material", False) or getattr(context, "world", False) or
1190                 getattr(context, "light", False))
1191
1192     def execute(self, context):
1193         if context.material:
1194             context.material.use_nodes = True
1195         elif context.world:
1196             context.world.use_nodes = True
1197         elif context.light:
1198             context.light.use_nodes = True
1199
1200         return {'FINISHED'}
1201
1202
1203 def panel_node_draw(layout, id_data, output_type, input_name):
1204     if not id_data.use_nodes:
1205         layout.operator("cycles.use_shading_nodes", icon='NODETREE')
1206         return False
1207
1208     ntree = id_data.node_tree
1209
1210     node = ntree.get_output_node('CYCLES')
1211     if node:
1212         input = find_node_input(node, input_name)
1213         if input:
1214             layout.template_node_view(ntree, node, input)
1215         else:
1216             layout.label(text="Incompatible output node")
1217     else:
1218         layout.label(text="No output node")
1219
1220     return True
1221
1222
1223 class CYCLES_LIGHT_PT_preview(CyclesButtonsPanel, Panel):
1224     bl_label = "Preview"
1225     bl_context = "data"
1226     bl_options = {'DEFAULT_CLOSED'}
1227
1228     @classmethod
1229     def poll(cls, context):
1230         return (
1231             context.light and
1232             not (
1233                 context.light.type == 'AREA' and
1234                 context.light.cycles.is_portal
1235             ) and
1236             CyclesButtonsPanel.poll(context)
1237         )
1238
1239     def draw(self, context):
1240         self.layout.template_preview(context.light)
1241
1242
1243 class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
1244     bl_label = "Light"
1245     bl_context = "data"
1246
1247     @classmethod
1248     def poll(cls, context):
1249         return context.light and CyclesButtonsPanel.poll(context)
1250
1251     def draw(self, context):
1252         layout = self.layout
1253
1254         light = context.light
1255         clamp = light.cycles
1256         # cscene = context.scene.cycles
1257
1258         layout.prop(light, "type", expand=True)
1259
1260         layout.use_property_split = True
1261         layout.use_property_decorate = False
1262
1263         col = layout.column()
1264
1265         if light.type in {'POINT', 'SUN', 'SPOT'}:
1266             col.prop(light, "shadow_soft_size", text="Size")
1267         elif light.type == 'AREA':
1268             col.prop(light, "shape", text="Shape")
1269             sub = col.column(align=True)
1270
1271             if light.shape in {'SQUARE', 'DISK'}:
1272                 sub.prop(light, "size")
1273             elif light.shape in {'RECTANGLE', 'ELLIPSE'}:
1274                 sub.prop(light, "size", text="Size X")
1275                 sub.prop(light, "size_y", text="Y")
1276
1277         if not (light.type == 'AREA' and clamp.is_portal):
1278             sub = col.column()
1279             if use_branched_path(context):
1280                 subsub = sub.row(align=True)
1281                 subsub.active = use_sample_all_lights(context)
1282                 subsub.prop(clamp, "samples")
1283             sub.prop(clamp, "max_bounces")
1284
1285         sub = col.column(align=True)
1286         sub.active = not (light.type == 'AREA' and clamp.is_portal)
1287         sub.prop(clamp, "cast_shadow")
1288         sub.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance")
1289
1290         if light.type == 'AREA':
1291             col.prop(clamp, "is_portal", text="Portal")
1292
1293         if light.type == 'HEMI':
1294             layout.label(text="Not supported, interpreted as sun light")
1295
1296
1297 class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
1298     bl_label = "Nodes"
1299     bl_context = "data"
1300
1301     @classmethod
1302     def poll(cls, context):
1303         return context.light and not (context.light.type == 'AREA' and
1304                                       context.light.cycles.is_portal) and \
1305             CyclesButtonsPanel.poll(context)
1306
1307     def draw(self, context):
1308         layout = self.layout
1309
1310         light = context.light
1311         if not panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface'):
1312             layout.prop(light, "color")
1313
1314
1315 class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
1316     bl_label = "Spot Shape"
1317     bl_context = "data"
1318
1319     @classmethod
1320     def poll(cls, context):
1321         light = context.light
1322         return (light and light.type == 'SPOT') and CyclesButtonsPanel.poll(context)
1323
1324     def draw(self, context):
1325         layout = self.layout
1326         light = context.light
1327         layout.use_property_split = True
1328         layout.use_property_decorate = False
1329
1330         col = layout.column()
1331         col.prop(light, "spot_size", text="Size")
1332         col.prop(light, "spot_blend", text="Blend", slider=True)
1333         col.prop(light, "show_cone")
1334
1335
1336 class CYCLES_WORLD_PT_preview(CyclesButtonsPanel, Panel):
1337     bl_label = "Preview"
1338     bl_context = "world"
1339     bl_options = {'DEFAULT_CLOSED'}
1340
1341     @classmethod
1342     def poll(cls, context):
1343         return context.world and CyclesButtonsPanel.poll(context)
1344
1345     def draw(self, context):
1346         self.layout.template_preview(context.world)
1347
1348
1349 class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
1350     bl_label = "Surface"
1351     bl_context = "world"
1352
1353     @classmethod
1354     def poll(cls, context):
1355         return context.world and CyclesButtonsPanel.poll(context)
1356
1357     def draw(self, context):
1358         layout = self.layout
1359
1360         world = context.world
1361
1362         if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
1363             layout.prop(world, "color")
1364
1365
1366 class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
1367     bl_label = "Volume"
1368     bl_context = "world"
1369     bl_options = {'DEFAULT_CLOSED'}
1370
1371     @classmethod
1372     def poll(cls, context):
1373         world = context.world
1374         return world and world.node_tree and CyclesButtonsPanel.poll(context)
1375
1376     def draw(self, context):
1377         layout = self.layout
1378
1379         world = context.world
1380         panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
1381
1382
1383 class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
1384     bl_label = "Ambient Occlusion"
1385     bl_context = "world"
1386     bl_options = {'DEFAULT_CLOSED'}
1387
1388     @classmethod
1389     def poll(cls, context):
1390         return context.world and CyclesButtonsPanel.poll(context)
1391
1392     def draw_header(self, context):
1393         light = context.world.light_settings
1394         self.layout.prop(light, "use_ambient_occlusion", text="")
1395
1396     def draw(self, context):
1397         layout = self.layout
1398         layout.use_property_split = True
1399         layout.use_property_decorate = False
1400
1401         light = context.world.light_settings
1402         scene = context.scene
1403
1404         col = layout.column()
1405         sub = col.column()
1406         sub.active = light.use_ambient_occlusion or scene.render.use_simplify
1407         sub.prop(light, "ao_factor", text="Factor")
1408         col.prop(light, "distance", text="Distance")
1409
1410
1411 class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
1412     bl_label = "Mist Pass"
1413     bl_context = "world"
1414     bl_options = {'DEFAULT_CLOSED'}
1415
1416     @classmethod
1417     def poll(cls, context):
1418         if CyclesButtonsPanel.poll(context):
1419             if context.world:
1420                 for view_layer in context.scene.view_layers:
1421                     if view_layer.use_pass_mist:
1422                         return True
1423
1424         return False
1425
1426     def draw(self, context):
1427         layout = self.layout
1428
1429         world = context.world
1430
1431         split = layout.split(align=True)
1432         split.prop(world.mist_settings, "start")
1433         split.prop(world.mist_settings, "depth")
1434
1435         layout.prop(world.mist_settings, "falloff")
1436
1437
1438 class CYCLES_WORLD_PT_ray_visibility(CyclesButtonsPanel, Panel):
1439     bl_label = "Ray Visibility"
1440     bl_context = "world"
1441     bl_options = {'DEFAULT_CLOSED'}
1442
1443     @classmethod
1444     def poll(cls, context):
1445         return CyclesButtonsPanel.poll(context) and context.world
1446
1447     def draw(self, context):
1448         layout = self.layout
1449
1450         world = context.world
1451         visibility = world.cycles_visibility
1452
1453         flow = layout.column_flow()
1454
1455         flow.prop(visibility, "camera")
1456         flow.prop(visibility, "diffuse")
1457         flow.prop(visibility, "glossy")
1458         flow.prop(visibility, "transmission")
1459         flow.prop(visibility, "scatter")
1460
1461
1462 class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel):
1463     bl_label = "Settings"
1464     bl_context = "world"
1465     bl_options = {'DEFAULT_CLOSED'}
1466
1467     @classmethod
1468     def poll(cls, context):
1469         return context.world and CyclesButtonsPanel.poll(context)
1470
1471     def draw(self, context):
1472         layout = self.layout
1473         layout.use_property_split = True
1474         layout.use_property_decorate = False
1475
1476         world = context.world
1477         cworld = world.cycles
1478         # cscene = context.scene.cycles
1479
1480         col = layout.column()
1481
1482
1483 class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
1484     bl_label = "Surface"
1485     bl_parent_id = "CYCLES_WORLD_PT_settings"
1486     bl_context = "world"
1487
1488     @classmethod
1489     def poll(cls, context):
1490         return context.world and CyclesButtonsPanel.poll(context)
1491
1492     def draw(self, context):
1493         layout = self.layout
1494         layout.use_property_split = True
1495         layout.use_property_decorate = False
1496
1497         world = context.world
1498         cworld = world.cycles
1499
1500         col = layout.column()
1501         col.prop(cworld, "sampling_method", text="Sampling")
1502
1503         sub = col.column()
1504         sub.active = cworld.sampling_method != 'NONE'
1505         subsub = sub.row(align=True)
1506         subsub.active = cworld.sampling_method == 'MANUAL'
1507         subsub.prop(cworld, "sample_map_resolution")
1508         if use_branched_path(context):
1509             subsub = sub.column(align=True)
1510             subsub.active = use_sample_all_lights(context)
1511             subsub.prop(cworld, "samples")
1512         sub.prop(cworld, "max_bounces")
1513
1514
1515 class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
1516     bl_label = "Volume"
1517     bl_parent_id = "CYCLES_WORLD_PT_settings"
1518     bl_context = "world"
1519
1520     @classmethod
1521     def poll(cls, context):
1522         return context.world and CyclesButtonsPanel.poll(context)
1523
1524     def draw(self, context):
1525         layout = self.layout
1526         layout.use_property_split = True
1527         layout.use_property_decorate = False
1528
1529         world = context.world
1530         cworld = world.cycles
1531
1532         col = layout.column()
1533
1534         sub = col.column()
1535         sub.active = use_cpu(context)
1536         sub.prop(cworld, "volume_sampling", text="Sampling")
1537         col.prop(cworld, "volume_interpolation", text="Interpolation")
1538         col.prop(cworld, "homogeneous_volume", text="Homogeneous")
1539
1540
1541 class CYCLES_MATERIAL_PT_preview(CyclesButtonsPanel, Panel):
1542     bl_label = "Preview"
1543     bl_context = "material"
1544     bl_options = {'DEFAULT_CLOSED'}
1545
1546     @classmethod
1547     def poll(cls, context):
1548         return context.material and CyclesButtonsPanel.poll(context)
1549
1550     def draw(self, context):
1551         self.layout.template_preview(context.material)
1552
1553
1554 class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel):
1555     bl_label = "Surface"
1556     bl_context = "material"
1557
1558     @classmethod
1559     def poll(cls, context):
1560         return context.material and CyclesButtonsPanel.poll(context)
1561
1562     def draw(self, context):
1563         layout = self.layout
1564
1565         mat = context.material
1566         if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
1567             layout.prop(mat, "diffuse_color")
1568
1569
1570 class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel):
1571     bl_label = "Volume"
1572     bl_context = "material"
1573     bl_options = {'DEFAULT_CLOSED'}
1574
1575     @classmethod
1576     def poll(cls, context):
1577         mat = context.material
1578         return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
1579
1580     def draw(self, context):
1581         layout = self.layout
1582
1583         mat = context.material
1584         # cmat = mat.cycles
1585
1586         panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
1587
1588
1589 class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
1590     bl_label = "Displacement"
1591     bl_context = "material"
1592
1593     @classmethod
1594     def poll(cls, context):
1595         mat = context.material
1596         return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
1597
1598     def draw(self, context):
1599         layout = self.layout
1600
1601         mat = context.material
1602         panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
1603
1604
1605 class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
1606     bl_label = "Settings"
1607     bl_context = "material"
1608     bl_options = {'DEFAULT_CLOSED'}
1609
1610     @classmethod
1611     def poll(cls, context):
1612         return context.material and CyclesButtonsPanel.poll(context)
1613
1614     def draw(self, context):
1615         layout = self.layout
1616         layout.use_property_split = True
1617         layout.use_property_decorate = False
1618
1619         mat = context.material
1620         cmat = mat.cycles
1621
1622         layout.prop(mat, "pass_index")
1623
1624
1625 class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
1626     bl_label = "Surface"
1627     bl_parent_id = "CYCLES_MATERIAL_PT_settings"
1628     bl_context = "material"
1629
1630     @classmethod
1631     def poll(cls, context):
1632         return context.material and CyclesButtonsPanel.poll(context)
1633
1634     def draw(self, context):
1635         layout = self.layout
1636         layout.use_property_split = True
1637         layout.use_property_decorate = False
1638
1639         mat = context.material
1640         cmat = mat.cycles
1641
1642         col = layout.column()
1643         col.prop(cmat, "sample_as_light", text="Multiple Importance")
1644         col.prop(cmat, "use_transparent_shadow")
1645         col.prop(cmat, "displacement_method", text="Displacement Method")
1646
1647
1648 class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
1649     bl_label = "Volume"
1650     bl_parent_id = "CYCLES_MATERIAL_PT_settings"
1651     bl_context = "material"
1652
1653     @classmethod
1654     def poll(cls, context):
1655         return context.material and CyclesButtonsPanel.poll(context)
1656
1657     def draw(self, context):
1658         layout = self.layout
1659         layout.use_property_split = True
1660         layout.use_property_decorate = False
1661
1662         mat = context.material
1663         cmat = mat.cycles
1664
1665         col = layout.column()
1666         sub = col.column()
1667         sub.active = use_cpu(context)
1668         sub.prop(cmat, "volume_sampling", text="Sampling")
1669         col.prop(cmat, "volume_interpolation", text="Interpolation")
1670         col.prop(cmat, "homogeneous_volume", text="Homogeneous")
1671
1672
1673 class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
1674     bl_label = "Bake"
1675     bl_context = "render"
1676     bl_options = {'DEFAULT_CLOSED'}
1677     COMPAT_ENGINES = {'CYCLES'}
1678
1679     def draw(self, context):
1680         layout = self.layout
1681         layout.use_property_split = True
1682         layout.use_property_decorate = False  # No animation.
1683
1684         scene = context.scene
1685         cscene = scene.cycles
1686         cbk = scene.render.bake
1687         rd = scene.render
1688
1689         col = layout.column()
1690         col.prop(rd, "use_bake_multires")
1691         if rd.use_bake_multires:
1692             col.prop(rd, "bake_type")
1693
1694             col = layout.column()
1695             col.prop(rd, "bake_margin")
1696             col.prop(rd, "use_bake_clear")
1697
1698             if rd.bake_type == 'DISPLACEMENT':
1699                 col.prop(rd, "use_bake_lores_mesh")
1700
1701             col.operator("object.bake_image", icon='RENDER_STILL')
1702
1703         else:
1704             col.prop(cscene, "bake_type")
1705
1706             col = layout.column()
1707
1708             if cscene.bake_type == 'NORMAL':
1709                 col.prop(cbk, "normal_space", text="Space")
1710
1711                 sub = col.column(align=True)
1712                 sub.prop(cbk, "normal_r", text="Swizzle R")
1713                 sub.prop(cbk, "normal_g", text="G")
1714                 sub.prop(cbk, "normal_b", text="B")
1715
1716             elif cscene.bake_type == 'COMBINED':
1717                 row = col.row(align=True)
1718                 row.use_property_split = False
1719                 row.prop(cbk, "use_pass_direct", toggle=True)
1720                 row.prop(cbk, "use_pass_indirect", toggle=True)
1721
1722                 col = col.column()
1723                 col.active = cbk.use_pass_direct or cbk.use_pass_indirect
1724                 col.prop(cbk, "use_pass_diffuse")
1725                 col.prop(cbk, "use_pass_glossy")
1726                 col.prop(cbk, "use_pass_transmission")
1727                 col.prop(cbk, "use_pass_subsurface")
1728                 col.prop(cbk, "use_pass_ambient_occlusion")
1729                 col.prop(cbk, "use_pass_emit")
1730
1731             elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
1732                 row = col.row(align=True)
1733                 row.use_property_split = False
1734                 row.prop(cbk, "use_pass_direct", toggle=True)
1735                 row.prop(cbk, "use_pass_indirect", toggle=True)
1736                 row.prop(cbk, "use_pass_color", toggle=True)
1737
1738             layout.separator()
1739
1740             col = layout.column()
1741             col.prop(cbk, "margin")
1742             col.prop(cbk, "use_clear", text="Clear Image")
1743
1744             col.separator()
1745
1746             col.prop(cbk, "use_selected_to_active")
1747             sub = col.column()
1748             sub.active = cbk.use_selected_to_active
1749             sub.prop(cbk, "use_cage", text="Cage")
1750             if cbk.use_cage:
1751                 sub.prop(cbk, "cage_extrusion", text="Extrusion")
1752                 sub.prop_search(cbk, "cage_object", scene, "objects", text="Cage Object")
1753             else:
1754                 sub.prop(cbk, "cage_extrusion", text="Ray Distance")
1755
1756             layout.separator()
1757
1758             layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type
1759
1760
1761 class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
1762     bl_label = "Debug"
1763     bl_context = "render"
1764     bl_options = {'DEFAULT_CLOSED'}
1765     COMPAT_ENGINES = {'CYCLES'}
1766
1767     @classmethod
1768     def poll(cls, context):
1769         return CyclesButtonsPanel.poll(context) and bpy.app.debug_value == 256
1770
1771     def draw(self, context):
1772         layout = self.layout
1773
1774         scene = context.scene
1775         cscene = scene.cycles
1776
1777         col = layout.column()
1778
1779         col.label(text="CPU Flags:")
1780         row = col.row(align=True)
1781         row.prop(cscene, "debug_use_cpu_sse2", toggle=True)
1782         row.prop(cscene, "debug_use_cpu_sse3", toggle=True)
1783         row.prop(cscene, "debug_use_cpu_sse41", toggle=True)
1784         row.prop(cscene, "debug_use_cpu_avx", toggle=True)
1785         row.prop(cscene, "debug_use_cpu_avx2", toggle=True)
1786         col.prop(cscene, "debug_bvh_layout")
1787         col.prop(cscene, "debug_use_cpu_split_kernel")
1788
1789         col.separator()
1790
1791         col = layout.column()
1792         col.label(text="CUDA Flags:")
1793         col.prop(cscene, "debug_use_cuda_adaptive_compile")
1794         col.prop(cscene, "debug_use_cuda_split_kernel")
1795
1796         col.separator()
1797
1798         col = layout.column()
1799         col.label(text="OpenCL Flags:")
1800         col.prop(cscene, "debug_opencl_kernel_type", text="Kernel")
1801         col.prop(cscene, "debug_opencl_device_type", text="Device")
1802         col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program")
1803         col.prop(cscene, "debug_use_opencl_debug", text="Debug")
1804         col.prop(cscene, "debug_opencl_mem_limit")
1805
1806         col.separator()
1807
1808         col = layout.column()
1809         col.prop(cscene, "debug_bvh_type")
1810
1811
1812 class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel):
1813     bl_label = "Simplify"
1814     bl_context = "scene"
1815     bl_options = {'DEFAULT_CLOSED'}
1816     COMPAT_ENGINES = {'CYCLES'}
1817
1818     def draw_header(self, context):
1819         rd = context.scene.render
1820         self.layout.prop(rd, "use_simplify", text="")
1821
1822     def draw(self, context):
1823         pass
1824
1825
1826 class CYCLES_SCENE_PT_simplify_viewport(CyclesButtonsPanel, Panel):
1827     bl_label = "Viewport"
1828     bl_context = "scene"
1829     bl_parent_id = "CYCLES_SCENE_PT_simplify"
1830     COMPAT_ENGINES = {'CYCLES'}
1831
1832     def draw(self, context):
1833         layout = self.layout
1834         layout.use_property_split = True
1835         layout.use_property_decorate = False
1836
1837         scene = context.scene
1838         rd = scene.render
1839         cscene = scene.cycles
1840
1841         layout.active = rd.use_simplify
1842
1843         col = layout.column()
1844         col.prop(rd, "simplify_subdivision", text="Max Subdivision")
1845         col.prop(rd, "simplify_child_particles", text="Child Particles")
1846         col.prop(cscene, "texture_limit", text="Texture Limit")
1847         col.prop(cscene, "ao_bounces", text="AO Bounces")
1848
1849
1850 class CYCLES_SCENE_PT_simplify_render(CyclesButtonsPanel, Panel):
1851     bl_label = "Render"
1852     bl_context = "scene"
1853     bl_parent_id = "CYCLES_SCENE_PT_simplify"
1854     COMPAT_ENGINES = {'CYCLES'}
1855
1856     def draw(self, context):
1857         layout = self.layout
1858         layout.use_property_split = True
1859         layout.use_property_decorate = False
1860
1861         scene = context.scene
1862         rd = scene.render
1863         cscene = scene.cycles
1864
1865         layout.active = rd.use_simplify
1866
1867         col = layout.column()
1868
1869         col.prop(rd, "simplify_subdivision_render", text="Max Subdivision")
1870         col.prop(rd, "simplify_child_particles_render", text="Child Particles")
1871         col.prop(cscene, "texture_limit_render", text="Texture Limit")
1872         col.prop(cscene, "ao_bounces_render", text="AO Bounces")
1873
1874
1875 class CYCLES_SCENE_PT_simplify_culling(CyclesButtonsPanel, Panel):
1876     bl_label = "Culling"
1877     bl_context = "scene"
1878     bl_parent_id = "CYCLES_SCENE_PT_simplify"
1879     bl_options = {'DEFAULT_CLOSED'}
1880     COMPAT_ENGINES = {'CYCLES'}
1881
1882     def draw(self, context):
1883         layout = self.layout
1884         layout.use_property_split = True
1885         layout.use_property_decorate = False
1886
1887         scene = context.scene
1888         rd = scene.render
1889         cscene = scene.cycles
1890
1891         layout.active = rd.use_simplify
1892
1893         col = layout.column()
1894         col.prop(cscene, "use_camera_cull")
1895         sub = col.column()
1896         sub.active = cscene.use_camera_cull
1897         sub.prop(cscene, "camera_cull_margin")
1898
1899         col = layout.column()
1900         col.prop(cscene, "use_distance_cull")
1901         sub = col.column()
1902         sub.active = cscene.use_distance_cull
1903         sub.prop(cscene, "distance_cull_margin", text="Distance")
1904
1905
1906 def draw_device(self, context):
1907     scene = context.scene
1908     layout = self.layout
1909     layout.use_property_split = True
1910     layout.use_property_decorate = False
1911
1912     if context.engine == 'CYCLES':
1913         from . import engine
1914         cscene = scene.cycles
1915
1916         col = layout.column()
1917         col.prop(cscene, "feature_set")
1918
1919
1920 def draw_pause(self, context):
1921     layout = self.layout
1922     scene = context.scene
1923
1924     if context.engine == "CYCLES":
1925         view = context.space_data
1926
1927         if view.shading.type == 'RENDERED':
1928             cscene = scene.cycles
1929             layout.prop(cscene, "preview_pause", icon='PAUSE', text="")
1930
1931
1932 def get_panels():
1933     exclude_panels = {
1934         'DATA_PT_area',
1935         'DATA_PT_camera_dof',
1936         'DATA_PT_falloff_curve',
1937         'DATA_PT_light',
1938         'DATA_PT_preview',
1939         'DATA_PT_spot',
1940         'MATERIAL_PT_context_material',
1941         'MATERIAL_PT_preview',
1942         'VIEWLAYER_PT_filter',
1943         'VIEWLAYER_PT_layer_passes',
1944         'RENDER_PT_post_processing',
1945         'SCENE_PT_simplify',
1946     }
1947
1948     panels = []
1949     for panel in bpy.types.Panel.__subclasses__():
1950         if hasattr(panel, 'COMPAT_ENGINES') and 'BLENDER_RENDER' in panel.COMPAT_ENGINES:
1951             if panel.__name__ not in exclude_panels:
1952                 panels.append(panel)
1953
1954     return panels
1955
1956
1957 classes = (
1958     CYCLES_PT_sampling_presets,
1959     CYCLES_PT_integrator_presets,
1960     CYCLES_RENDER_PT_sampling,
1961     CYCLES_RENDER_PT_sampling_light,
1962     CYCLES_RENDER_PT_sampling_sub_samples,
1963     CYCLES_RENDER_PT_sampling_advanced,
1964     CYCLES_RENDER_PT_geometry,
1965     CYCLES_RENDER_PT_geometry_subdivision,
1966     CYCLES_RENDER_PT_geometry_volume,
1967     CYCLES_RENDER_PT_geometry_hair,
1968     CYCLES_RENDER_PT_light_paths,
1969     CYCLES_RENDER_PT_light_paths_max_bounces,
1970     CYCLES_RENDER_PT_light_paths_caustics,
1971     CYCLES_RENDER_PT_motion_blur,
1972     CYCLES_RENDER_PT_motion_blur_curve,
1973     CYCLES_RENDER_PT_film,
1974     CYCLES_RENDER_PT_film_transparency,
1975     CYCLES_RENDER_PT_film_pixel_filter,
1976     CYCLES_RENDER_PT_performance,
1977     CYCLES_RENDER_PT_performance_threads,
1978     CYCLES_RENDER_PT_performance_tiles,
1979     CYCLES_RENDER_PT_performance_acceleration_structure,
1980     CYCLES_RENDER_PT_performance_final_render,
1981     CYCLES_RENDER_PT_performance_viewport,
1982     CYCLES_RENDER_PT_filter,
1983     CYCLES_RENDER_PT_layer_passes,
1984     CYCLES_RENDER_PT_denoising,
1985     CYCLES_PT_post_processing,
1986     CYCLES_CAMERA_PT_dof,
1987     CYCLES_CAMERA_PT_dof_aperture,
1988     CYCLES_CAMERA_PT_dof_viewport,
1989     CYCLES_PT_context_material,
1990     CYCLES_OBJECT_PT_motion_blur,
1991     CYCLES_OBJECT_PT_cycles_settings,
1992     CYCLES_OBJECT_PT_cycles_settings_ray_visibility,
1993     CYCLES_OBJECT_PT_cycles_settings_performance,
1994     CYCLES_OT_use_shading_nodes,
1995     CYCLES_LIGHT_PT_preview,
1996     CYCLES_LIGHT_PT_light,
1997     CYCLES_LIGHT_PT_nodes,
1998     CYCLES_LIGHT_PT_spot,
1999     CYCLES_WORLD_PT_preview,
2000     CYCLES_WORLD_PT_surface,
2001     CYCLES_WORLD_PT_volume,
2002     CYCLES_WORLD_PT_ambient_occlusion,
2003     CYCLES_WORLD_PT_mist,
2004     CYCLES_WORLD_PT_ray_visibility,
2005     CYCLES_WORLD_PT_settings,
2006     CYCLES_WORLD_PT_settings_surface,
2007     CYCLES_WORLD_PT_settings_volume,
2008     CYCLES_MATERIAL_PT_preview,
2009     CYCLES_MATERIAL_PT_surface,
2010     CYCLES_MATERIAL_PT_volume,
2011     CYCLES_MATERIAL_PT_displacement,
2012     CYCLES_MATERIAL_PT_settings,
2013     CYCLES_MATERIAL_PT_settings_surface,
2014     CYCLES_MATERIAL_PT_settings_volume,
2015     CYCLES_RENDER_PT_bake,
2016     CYCLES_RENDER_PT_debug,
2017     CYCLES_SCENE_PT_simplify,
2018     CYCLES_SCENE_PT_simplify_viewport,
2019     CYCLES_SCENE_PT_simplify_render,
2020     CYCLES_SCENE_PT_simplify_culling,
2021 )
2022
2023
2024 def register():
2025     from bpy.utils import register_class
2026
2027     bpy.types.RENDER_PT_context.append(draw_device)
2028     bpy.types.VIEW3D_HT_header.append(draw_pause)
2029
2030     for panel in get_panels():
2031         panel.COMPAT_ENGINES.add('CYCLES')
2032
2033     for cls in classes:
2034         register_class(cls)
2035
2036
2037 def unregister():
2038     from bpy.utils import unregister_class
2039
2040     bpy.types.RENDER_PT_context.remove(draw_device)
2041     bpy.types.VIEW3D_HT_header.remove(draw_pause)
2042
2043     for panel in get_panels():
2044         if 'CYCLES' in panel.COMPAT_ENGINES:
2045             panel.COMPAT_ENGINES.remove('CYCLES')
2046
2047     for cls in classes:
2048         unregister_class(cls)