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