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