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