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_radius", text="Radius")
915         layout.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength")
916         layout.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
917         layout.prop(cycles_view_layer, "denoising_relative_pca")
918
919         layout.separator()
920
921         split = layout.split(factor=0.5)
922         split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
923
924         col = split.column()
925         col.alignment = 'RIGHT'
926         col.label(text="Diffuse")
927
928         row = split.row(align=True)
929         row.use_property_split = False
930         row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True)
931         row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True)
932
933         split = layout.split(factor=0.5)
934         split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
935
936         col = split.column()
937         col.alignment = 'RIGHT'
938         col.label(text="Glossy")
939
940         row = split.row(align=True)
941         row.use_property_split = False
942         row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True)
943         row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True)
944
945         split = layout.split(factor=0.5)
946         split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
947
948         col = split.column()
949         col.alignment = 'RIGHT'
950         col.label(text="Transmission")
951
952         row = split.row(align=True)
953         row.use_property_split = False
954         row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True)
955         row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True)
956
957         split = layout.split(factor=0.5)
958         split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
959
960         col = split.column()
961         col.alignment = 'RIGHT'
962         col.label(text="Subsurface")
963
964         row = split.row(align=True)
965         row.use_property_split = False
966         row.prop(cycles_view_layer, "denoising_subsurface_direct", text="Direct", toggle=True)
967         row.prop(cycles_view_layer, "denoising_subsurface_indirect", text="Indirect", toggle=True)
968
969
970 class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
971     bl_label = "Post Processing"
972     bl_options = {'DEFAULT_CLOSED'}
973     bl_context = "output"
974
975     def draw(self, context):
976         layout = self.layout
977         layout.use_property_split = True
978         layout.use_property_decorate = False
979
980         rd = context.scene.render
981
982         col = layout.column(align=True)
983         col.prop(rd, "use_compositing")
984         col.prop(rd, "use_sequencer")
985
986         layout.prop(rd, "dither_intensity", text="Dither", slider=True)
987
988
989 class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel):
990     bl_label = "Depth of Field"
991     bl_context = "data"
992
993     @classmethod
994     def poll(cls, context):
995         return context.camera and CyclesButtonsPanel.poll(context)
996
997     def draw(self, context):
998         layout = self.layout
999         layout.use_property_split = True
1000
1001         cam = context.camera
1002
1003         split = layout.split()
1004
1005         col = split.column()
1006         col.prop(cam, "dof_object", text="Focus Object")
1007
1008         sub = col.row()
1009         sub.active = cam.dof_object is None
1010         sub.prop(cam, "dof_distance", text="Distance")
1011
1012
1013 class CYCLES_CAMERA_PT_dof_aperture(CyclesButtonsPanel, Panel):
1014     bl_label = "Aperture"
1015     bl_parent_id = "CYCLES_CAMERA_PT_dof"
1016
1017     @classmethod
1018     def poll(cls, context):
1019         return context.camera and CyclesButtonsPanel.poll(context)
1020
1021     def draw(self, context):
1022         layout = self.layout
1023         layout.use_property_split = True
1024         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1025
1026         cam = context.camera
1027         ccam = cam.cycles
1028
1029         col = flow.column()
1030         col.prop(ccam, "aperture_type")
1031         if ccam.aperture_type == 'RADIUS':
1032             col.prop(ccam, "aperture_size", text="Size")
1033         elif ccam.aperture_type == 'FSTOP':
1034             col.prop(ccam, "aperture_fstop", text="Number")
1035         col.separator()
1036
1037         col = flow.column()
1038         col.prop(ccam, "aperture_blades", text="Blades")
1039         col.prop(ccam, "aperture_rotation", text="Rotation")
1040         col.prop(ccam, "aperture_ratio", text="Ratio")
1041
1042
1043 class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel):
1044     bl_label = "Viewport"
1045     bl_parent_id = "CYCLES_CAMERA_PT_dof"
1046
1047     @classmethod
1048     def poll(cls, context):
1049         return context.camera and CyclesButtonsPanel.poll(context)
1050
1051     def draw(self, context):
1052         layout = self.layout
1053         layout.use_property_split = True
1054         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1055
1056         cam = context.camera
1057         dof_options = cam.gpu_dof
1058
1059         sub = flow.column(align=True)
1060         sub.prop(dof_options, "fstop")
1061         sub.prop(dof_options, "blades")
1062
1063
1064 class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
1065     bl_label = ""
1066     bl_context = "material"
1067     bl_options = {'HIDE_HEADER'}
1068
1069     @classmethod
1070     def poll(cls, context):
1071         if context.active_object and context.active_object.type == 'GPENCIL':
1072             return False
1073         else:
1074             return (context.material or context.object) and CyclesButtonsPanel.poll(context)
1075
1076     def draw(self, context):
1077         layout = self.layout
1078
1079         mat = context.material
1080         ob = context.object
1081         slot = context.material_slot
1082         space = context.space_data
1083
1084         if ob:
1085             is_sortable = len(ob.material_slots) > 1
1086             rows = 1
1087             if (is_sortable):
1088                 rows = 4
1089
1090             row = layout.row()
1091
1092             row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
1093
1094             col = row.column(align=True)
1095             col.operator("object.material_slot_add", icon='ADD', text="")
1096             col.operator("object.material_slot_remove", icon='REMOVE', text="")
1097
1098             col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
1099
1100             if is_sortable:
1101                 col.separator()
1102
1103                 col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
1104                 col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
1105
1106             if ob.mode == 'EDIT':
1107                 row = layout.row(align=True)
1108                 row.operator("object.material_slot_assign", text="Assign")
1109                 row.operator("object.material_slot_select", text="Select")
1110                 row.operator("object.material_slot_deselect", text="Deselect")
1111
1112         split = layout.split(factor=0.65)
1113
1114         if ob:
1115             split.template_ID(ob, "active_material", new="material.new")
1116             row = split.row()
1117
1118             if slot:
1119                 row.prop(slot, "link", text="")
1120             else:
1121                 row.label()
1122         elif mat:
1123             split.template_ID(space, "pin_id")
1124             split.separator()
1125
1126
1127 class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
1128     bl_label = "Motion Blur"
1129     bl_context = "object"
1130     bl_options = {'DEFAULT_CLOSED'}
1131
1132     @classmethod
1133     def poll(cls, context):
1134         ob = context.object
1135         if CyclesButtonsPanel.poll(context) and ob:
1136             if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA'}:
1137                 return True
1138             if ob.instance_type == 'COLLECTION' and ob.instance_collection:
1139                 return True
1140             # TODO(sergey): More duplicator types here?
1141         return False
1142
1143     def draw_header(self, context):
1144         layout = self.layout
1145
1146         rd = context.scene.render
1147         # scene = context.scene
1148
1149         layout.active = rd.use_motion_blur
1150
1151         ob = context.object
1152         cob = ob.cycles
1153
1154         layout.prop(cob, "use_motion_blur", text="")
1155
1156     def draw(self, context):
1157         layout = self.layout
1158
1159         rd = context.scene.render
1160         # scene = context.scene
1161
1162         ob = context.object
1163         cob = ob.cycles
1164
1165         layout.active = (rd.use_motion_blur and cob.use_motion_blur)
1166
1167         row = layout.row()
1168         if ob.type != 'CAMERA':
1169             row.prop(cob, "use_deform_motion", text="Deformation")
1170         row.prop(cob, "motion_steps", text="Steps")
1171
1172
1173 class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel):
1174     bl_label = "Cycles Settings"
1175     bl_context = "object"
1176     bl_options = {'DEFAULT_CLOSED'}
1177
1178     @classmethod
1179     def poll(cls, context):
1180         ob = context.object
1181         return (CyclesButtonsPanel.poll(context) and
1182                 ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or
1183                         (ob.instance_type == 'COLLECTION' and ob.instance_collection)))
1184
1185     def draw(self, context):
1186         pass
1187
1188
1189 class CYCLES_OBJECT_PT_cycles_settings_ray_visibility(CyclesButtonsPanel, Panel):
1190     bl_label = "Ray Visibility"
1191     bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings"
1192     bl_context = "object"
1193
1194     def draw(self, context):
1195         layout = self.layout
1196         layout.use_property_split = True
1197         layout.use_property_decorate = False
1198
1199         scene = context.scene
1200         ob = context.object
1201         cob = ob.cycles
1202         visibility = ob.cycles_visibility
1203
1204         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1205
1206         col = flow.column()
1207         col.prop(visibility, "camera")
1208         col = flow.column()
1209         col.prop(visibility, "diffuse")
1210         col = flow.column()
1211         col.prop(visibility, "glossy")
1212         col = flow.column()
1213         col.prop(visibility, "transmission")
1214         col = flow.column()
1215         col.prop(visibility, "scatter")
1216
1217         if ob.type != 'LIGHT':
1218             col = flow.column()
1219             col.prop(visibility, "shadow")
1220
1221         layout.separator()
1222
1223         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1224
1225         col = flow.column()
1226         col.prop(cob, "is_shadow_catcher")
1227         col = flow.column()
1228         col.prop(cob, "is_holdout")
1229
1230
1231 class CYCLES_OBJECT_PT_cycles_settings_performance(CyclesButtonsPanel, Panel):
1232     bl_label = "Performance"
1233     bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings"
1234     bl_context = "object"
1235
1236
1237     def draw(self, context):
1238         layout = self.layout
1239         layout.use_property_split = True
1240         layout.use_property_decorate = False
1241
1242         scene = context.scene
1243         cscene = scene.cycles
1244         ob = context.object
1245         cob = ob.cycles
1246
1247         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
1248
1249         col = flow.column()
1250         col.active = scene.render.use_simplify and cscene.use_camera_cull
1251         col.prop(cob, "use_camera_cull")
1252
1253         col = flow.column()
1254         col.active = scene.render.use_simplify and cscene.use_distance_cull
1255         col.prop(cob, "use_distance_cull")
1256
1257
1258 class CYCLES_OT_use_shading_nodes(Operator):
1259     """Enable nodes on a material, world or light"""
1260     bl_idname = "cycles.use_shading_nodes"
1261     bl_label = "Use Nodes"
1262
1263     @classmethod
1264     def poll(cls, context):
1265         return (getattr(context, "material", False) or getattr(context, "world", False) or
1266                 getattr(context, "light", False))
1267
1268     def execute(self, context):
1269         if context.material:
1270             context.material.use_nodes = True
1271         elif context.world:
1272             context.world.use_nodes = True
1273         elif context.light:
1274             context.light.use_nodes = True
1275
1276         return {'FINISHED'}
1277
1278
1279 def panel_node_draw(layout, id_data, output_type, input_name):
1280     if not id_data.use_nodes:
1281         layout.operator("cycles.use_shading_nodes", icon='NODETREE')
1282         return False
1283
1284     ntree = id_data.node_tree
1285
1286     node = ntree.get_output_node('CYCLES')
1287     if node:
1288         input = find_node_input(node, input_name)
1289         if input:
1290             layout.template_node_view(ntree, node, input)
1291         else:
1292             layout.label(text="Incompatible output node")
1293     else:
1294         layout.label(text="No output node")
1295
1296     return True
1297
1298
1299 class CYCLES_LIGHT_PT_preview(CyclesButtonsPanel, Panel):
1300     bl_label = "Preview"
1301     bl_context = "data"
1302     bl_options = {'DEFAULT_CLOSED'}
1303
1304     @classmethod
1305     def poll(cls, context):
1306         return (
1307             context.light and
1308             not (
1309                 context.light.type == 'AREA' and
1310                 context.light.cycles.is_portal
1311             ) and
1312             CyclesButtonsPanel.poll(context)
1313         )
1314
1315     def draw(self, context):
1316         self.layout.template_preview(context.light)
1317
1318
1319 class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
1320     bl_label = "Light"
1321     bl_context = "data"
1322
1323     @classmethod
1324     def poll(cls, context):
1325         return context.light and CyclesButtonsPanel.poll(context)
1326
1327     def draw(self, context):
1328         layout = self.layout
1329
1330         light = context.light
1331         clamp = light.cycles
1332         # cscene = context.scene.cycles
1333
1334         layout.prop(light, "type", expand=True)
1335
1336         layout.use_property_split = True
1337         layout.use_property_decorate = False
1338
1339         col = layout.column()
1340
1341         if light.type in {'POINT', 'SUN', 'SPOT'}:
1342             col.prop(light, "shadow_soft_size", text="Size")
1343         elif light.type == 'AREA':
1344             col.prop(light, "shape", text="Shape")
1345             sub = col.column(align=True)
1346
1347             if light.shape in {'SQUARE', 'DISK'}:
1348                 sub.prop(light, "size")
1349             elif light.shape in {'RECTANGLE', 'ELLIPSE'}:
1350                 sub.prop(light, "size", text="Size X")
1351                 sub.prop(light, "size_y", text="Y")
1352
1353         if not (light.type == 'AREA' and clamp.is_portal):
1354             sub = col.column()
1355             if use_branched_path(context):
1356                 subsub = sub.row(align=True)
1357                 subsub.active = use_sample_all_lights(context)
1358                 subsub.prop(clamp, "samples")
1359             sub.prop(clamp, "max_bounces")
1360
1361         sub = col.column(align=True)
1362         sub.active = not (light.type == 'AREA' and clamp.is_portal)
1363         sub.prop(clamp, "cast_shadow")
1364         sub.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance")
1365
1366         if light.type == 'AREA':
1367             col.prop(clamp, "is_portal", text="Portal")
1368
1369
1370 class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
1371     bl_label = "Nodes"
1372     bl_context = "data"
1373
1374     @classmethod
1375     def poll(cls, context):
1376         return context.light and not (context.light.type == 'AREA' and
1377                                       context.light.cycles.is_portal) and \
1378             CyclesButtonsPanel.poll(context)
1379
1380     def draw(self, context):
1381         layout = self.layout
1382
1383         light = context.light
1384         if not panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface'):
1385             layout.prop(light, "color")
1386
1387
1388 class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
1389     bl_label = "Spot Shape"
1390     bl_context = "data"
1391
1392     @classmethod
1393     def poll(cls, context):
1394         light = context.light
1395         return (light and light.type == 'SPOT') and CyclesButtonsPanel.poll(context)
1396
1397     def draw(self, context):
1398         layout = self.layout
1399         light = context.light
1400         layout.use_property_split = True
1401         layout.use_property_decorate = False
1402
1403         col = layout.column()
1404         col.prop(light, "spot_size", text="Size")
1405         col.prop(light, "spot_blend", text="Blend", slider=True)
1406         col.prop(light, "show_cone")
1407
1408
1409 class CYCLES_WORLD_PT_preview(CyclesButtonsPanel, Panel):
1410     bl_label = "Preview"
1411     bl_context = "world"
1412     bl_options = {'DEFAULT_CLOSED'}
1413
1414     @classmethod
1415     def poll(cls, context):
1416         return context.world and CyclesButtonsPanel.poll(context)
1417
1418     def draw(self, context):
1419         self.layout.template_preview(context.world)
1420
1421
1422 class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
1423     bl_label = "Surface"
1424     bl_context = "world"
1425
1426     @classmethod
1427     def poll(cls, context):
1428         return context.world and CyclesButtonsPanel.poll(context)
1429
1430     def draw(self, context):
1431         layout = self.layout
1432
1433         world = context.world
1434
1435         if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
1436             layout.prop(world, "color")
1437
1438
1439 class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
1440     bl_label = "Volume"
1441     bl_context = "world"
1442     bl_options = {'DEFAULT_CLOSED'}
1443
1444     @classmethod
1445     def poll(cls, context):
1446         world = context.world
1447         return world and world.node_tree and CyclesButtonsPanel.poll(context)
1448
1449     def draw(self, context):
1450         layout = self.layout
1451
1452         world = context.world
1453         panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
1454
1455
1456 class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
1457     bl_label = "Ambient Occlusion"
1458     bl_context = "world"
1459     bl_options = {'DEFAULT_CLOSED'}
1460
1461     @classmethod
1462     def poll(cls, context):
1463         return context.world and CyclesButtonsPanel.poll(context)
1464
1465     def draw_header(self, context):
1466         light = context.world.light_settings
1467         self.layout.prop(light, "use_ambient_occlusion", text="")
1468
1469     def draw(self, context):
1470         layout = self.layout
1471         layout.use_property_split = True
1472         layout.use_property_decorate = False
1473
1474         light = context.world.light_settings
1475         scene = context.scene
1476
1477         col = layout.column()
1478         sub = col.column()
1479         sub.active = light.use_ambient_occlusion or scene.render.use_simplify
1480         sub.prop(light, "ao_factor", text="Factor")
1481         col.prop(light, "distance", text="Distance")
1482
1483
1484 class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
1485     bl_label = "Mist Pass"
1486     bl_context = "world"
1487     bl_options = {'DEFAULT_CLOSED'}
1488
1489     @classmethod
1490     def poll(cls, context):
1491         if CyclesButtonsPanel.poll(context):
1492             if context.world:
1493                 for view_layer in context.scene.view_layers:
1494                     if view_layer.use_pass_mist:
1495                         return True
1496
1497         return False
1498
1499     def draw(self, context):
1500         layout = self.layout
1501
1502         world = context.world
1503
1504         split = layout.split(align=True)
1505         split.prop(world.mist_settings, "start")
1506         split.prop(world.mist_settings, "depth")
1507
1508         layout.prop(world.mist_settings, "falloff")
1509
1510
1511 class CYCLES_WORLD_PT_ray_visibility(CyclesButtonsPanel, Panel):
1512     bl_label = "Ray Visibility"
1513     bl_context = "world"
1514     bl_options = {'DEFAULT_CLOSED'}
1515
1516     @classmethod
1517     def poll(cls, context):
1518         return CyclesButtonsPanel.poll(context) and context.world
1519
1520     def draw(self, context):
1521         layout = self.layout
1522
1523         world = context.world
1524         visibility = world.cycles_visibility
1525
1526         flow = layout.column_flow()
1527
1528         flow.prop(visibility, "camera")
1529         flow.prop(visibility, "diffuse")
1530         flow.prop(visibility, "glossy")
1531         flow.prop(visibility, "transmission")
1532         flow.prop(visibility, "scatter")
1533
1534
1535 class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel):
1536     bl_label = "Settings"
1537     bl_context = "world"
1538     bl_options = {'DEFAULT_CLOSED'}
1539
1540     @classmethod
1541     def poll(cls, context):
1542         return context.world and CyclesButtonsPanel.poll(context)
1543
1544     def draw(self, context):
1545         layout = self.layout
1546         layout.use_property_split = True
1547         layout.use_property_decorate = False
1548
1549         layout.column()
1550
1551
1552 class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
1553     bl_label = "Surface"
1554     bl_parent_id = "CYCLES_WORLD_PT_settings"
1555     bl_context = "world"
1556
1557     @classmethod
1558     def poll(cls, context):
1559         return context.world and CyclesButtonsPanel.poll(context)
1560
1561     def draw(self, context):
1562         layout = self.layout
1563         layout.use_property_split = True
1564         layout.use_property_decorate = False
1565
1566         world = context.world
1567         cworld = world.cycles
1568
1569         col = layout.column()
1570         col.prop(cworld, "sampling_method", text="Sampling")
1571
1572         sub = col.column()
1573         sub.active = cworld.sampling_method != 'NONE'
1574         subsub = sub.row(align=True)
1575         subsub.active = cworld.sampling_method == 'MANUAL'
1576         subsub.prop(cworld, "sample_map_resolution")
1577         if use_branched_path(context):
1578             subsub = sub.column(align=True)
1579             subsub.active = use_sample_all_lights(context)
1580             subsub.prop(cworld, "samples")
1581         sub.prop(cworld, "max_bounces")
1582
1583
1584 class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
1585     bl_label = "Volume"
1586     bl_parent_id = "CYCLES_WORLD_PT_settings"
1587     bl_context = "world"
1588
1589     @classmethod
1590     def poll(cls, context):
1591         return context.world and CyclesButtonsPanel.poll(context)
1592
1593     def draw(self, context):
1594         layout = self.layout
1595         layout.use_property_split = True
1596         layout.use_property_decorate = False
1597
1598         world = context.world
1599         cworld = world.cycles
1600
1601         col = layout.column()
1602
1603         sub = col.column()
1604         sub.active = use_cpu(context)
1605         sub.prop(cworld, "volume_sampling", text="Sampling")
1606         col.prop(cworld, "volume_interpolation", text="Interpolation")
1607         col.prop(cworld, "homogeneous_volume", text="Homogeneous")
1608
1609
1610 class CYCLES_MATERIAL_PT_preview(CyclesButtonsPanel, Panel):
1611     bl_label = "Preview"
1612     bl_context = "material"
1613     bl_options = {'DEFAULT_CLOSED'}
1614
1615     @classmethod
1616     def poll(cls, context):
1617         return context.material and CyclesButtonsPanel.poll(context)
1618
1619     def draw(self, context):
1620         self.layout.template_preview(context.material)
1621
1622
1623 class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel):
1624     bl_label = "Surface"
1625     bl_context = "material"
1626
1627     @classmethod
1628     def poll(cls, context):
1629         return context.material and CyclesButtonsPanel.poll(context)
1630
1631     def draw(self, context):
1632         layout = self.layout
1633
1634         mat = context.material
1635         if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
1636             layout.prop(mat, "diffuse_color")
1637
1638
1639 class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel):
1640     bl_label = "Volume"
1641     bl_context = "material"
1642     bl_options = {'DEFAULT_CLOSED'}
1643
1644     @classmethod
1645     def poll(cls, context):
1646         mat = context.material
1647         return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
1648
1649     def draw(self, context):
1650         layout = self.layout
1651
1652         mat = context.material
1653         # cmat = mat.cycles
1654
1655         panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
1656
1657
1658 class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
1659     bl_label = "Displacement"
1660     bl_context = "material"
1661
1662     @classmethod
1663     def poll(cls, context):
1664         mat = context.material
1665         return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
1666
1667     def draw(self, context):
1668         layout = self.layout
1669
1670         mat = context.material
1671         panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
1672
1673
1674 class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
1675     bl_label = "Settings"
1676     bl_context = "material"
1677     bl_options = {'DEFAULT_CLOSED'}
1678
1679     @classmethod
1680     def poll(cls, context):
1681         return context.material and CyclesButtonsPanel.poll(context)
1682
1683     @staticmethod
1684     def draw_shared(self, mat):
1685         layout = self.layout
1686         layout.use_property_split = True
1687         layout.use_property_decorate = False
1688
1689         layout.prop(mat, "pass_index")
1690
1691     def draw(self, context):
1692         self.draw_shared(self, context.material)
1693
1694
1695 class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
1696     bl_label = "Surface"
1697     bl_parent_id = "CYCLES_MATERIAL_PT_settings"
1698     bl_context = "material"
1699
1700     @staticmethod
1701     def draw_shared(self, mat):
1702         layout = self.layout
1703         layout.use_property_split = True
1704         layout.use_property_decorate = False
1705
1706         cmat = mat.cycles
1707
1708         col = layout.column()
1709         col.prop(cmat, "sample_as_light", text="Multiple Importance")
1710         col.prop(cmat, "use_transparent_shadow")
1711         col.prop(cmat, "displacement_method", text="Displacement Method")
1712
1713     def draw(self, context):
1714         self.draw_shared(self, context.material)
1715
1716
1717 class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
1718     bl_label = "Volume"
1719     bl_parent_id = "CYCLES_MATERIAL_PT_settings"
1720     bl_context = "material"
1721
1722     @staticmethod
1723     def draw_shared(self, context, mat):
1724         layout = self.layout
1725         layout.use_property_split = True
1726         layout.use_property_decorate = False
1727
1728         cmat = mat.cycles
1729
1730         col = layout.column()
1731         sub = col.column()
1732         sub.active = use_cpu(context)
1733         sub.prop(cmat, "volume_sampling", text="Sampling")
1734         col.prop(cmat, "volume_interpolation", text="Interpolation")
1735         col.prop(cmat, "homogeneous_volume", text="Homogeneous")
1736
1737     def draw(self, context):
1738         self.draw_shared(self, context, context.material)
1739
1740
1741 class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
1742     bl_label = "Bake"
1743     bl_context = "render"
1744     bl_options = {'DEFAULT_CLOSED'}
1745     COMPAT_ENGINES = {'CYCLES'}
1746
1747     def draw(self, context):
1748         layout = self.layout
1749         layout.use_property_split = True
1750         layout.use_property_decorate = False  # No animation.
1751
1752         scene = context.scene
1753         cscene = scene.cycles
1754         cbk = scene.render.bake
1755         rd = scene.render
1756
1757         col = layout.column()
1758         col.prop(rd, "use_bake_multires")
1759         if rd.use_bake_multires:
1760             col.prop(rd, "bake_type")
1761
1762             col = layout.column()
1763             col.prop(rd, "bake_margin")
1764             col.prop(rd, "use_bake_clear")
1765
1766             if rd.bake_type == 'DISPLACEMENT':
1767                 col.prop(rd, "use_bake_lores_mesh")
1768
1769             col.operator("object.bake_image", icon='RENDER_STILL')
1770
1771         else:
1772             col.prop(cscene, "bake_type")
1773
1774             col = layout.column()
1775
1776             if cscene.bake_type == 'NORMAL':
1777                 col.prop(cbk, "normal_space", text="Space")
1778
1779                 sub = col.column(align=True)
1780                 sub.prop(cbk, "normal_r", text="Swizzle R")
1781                 sub.prop(cbk, "normal_g", text="G")
1782                 sub.prop(cbk, "normal_b", text="B")
1783
1784             elif cscene.bake_type == 'COMBINED':
1785                 row = col.row(align=True)
1786                 row.use_property_split = False
1787                 row.prop(cbk, "use_pass_direct", toggle=True)
1788                 row.prop(cbk, "use_pass_indirect", toggle=True)
1789
1790                 col = col.column()
1791                 col.active = cbk.use_pass_direct or cbk.use_pass_indirect
1792                 col.prop(cbk, "use_pass_diffuse")
1793                 col.prop(cbk, "use_pass_glossy")
1794                 col.prop(cbk, "use_pass_transmission")
1795                 col.prop(cbk, "use_pass_subsurface")
1796                 col.prop(cbk, "use_pass_ambient_occlusion")
1797                 col.prop(cbk, "use_pass_emit")
1798
1799             elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
1800                 row = col.row(align=True)
1801                 row.use_property_split = False
1802                 row.prop(cbk, "use_pass_direct", toggle=True)
1803                 row.prop(cbk, "use_pass_indirect", toggle=True)
1804                 row.prop(cbk, "use_pass_color", toggle=True)
1805
1806             layout.separator()
1807
1808             col = layout.column()
1809             col.prop(cbk, "margin")
1810             col.prop(cbk, "use_clear", text="Clear Image")
1811
1812             col.separator()
1813
1814             col.prop(cbk, "use_selected_to_active")
1815             sub = col.column()
1816             sub.active = cbk.use_selected_to_active
1817             sub.prop(cbk, "use_cage", text="Cage")
1818             if cbk.use_cage:
1819                 sub.prop(cbk, "cage_extrusion", text="Extrusion")
1820                 sub.prop(cbk, "cage_object", text="Cage Object")
1821             else:
1822                 sub.prop(cbk, "cage_extrusion", text="Ray Distance")
1823
1824             layout.separator()
1825
1826             layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type
1827
1828
1829 class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
1830     bl_label = "Debug"
1831     bl_context = "render"
1832     bl_options = {'DEFAULT_CLOSED'}
1833     COMPAT_ENGINES = {'CYCLES'}
1834
1835     @classmethod
1836     def poll(cls, context):
1837         return CyclesButtonsPanel.poll(context) and bpy.app.debug_value == 256
1838
1839     def draw(self, context):
1840         layout = self.layout
1841
1842         scene = context.scene
1843         cscene = scene.cycles
1844
1845         col = layout.column()
1846
1847         col.label(text="CPU Flags:")
1848         row = col.row(align=True)
1849         row.prop(cscene, "debug_use_cpu_sse2", toggle=True)
1850         row.prop(cscene, "debug_use_cpu_sse3", toggle=True)
1851         row.prop(cscene, "debug_use_cpu_sse41", toggle=True)
1852         row.prop(cscene, "debug_use_cpu_avx", toggle=True)
1853         row.prop(cscene, "debug_use_cpu_avx2", toggle=True)
1854         col.prop(cscene, "debug_bvh_layout")
1855         col.prop(cscene, "debug_use_cpu_split_kernel")
1856
1857         col.separator()
1858
1859         col = layout.column()
1860         col.label(text="CUDA Flags:")
1861         col.prop(cscene, "debug_use_cuda_adaptive_compile")
1862         col.prop(cscene, "debug_use_cuda_split_kernel")
1863
1864         col.separator()
1865
1866         col = layout.column()
1867         col.label(text="OpenCL Flags:")
1868         col.prop(cscene, "debug_opencl_kernel_type", text="Kernel")
1869         col.prop(cscene, "debug_opencl_device_type", text="Device")
1870         col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program")
1871         col.prop(cscene, "debug_use_opencl_debug", text="Debug")
1872         col.prop(cscene, "debug_opencl_mem_limit")
1873
1874         col.separator()
1875
1876         col = layout.column()
1877         col.prop(cscene, "debug_bvh_type")
1878
1879
1880 class CYCLES_RENDER_PT_simplify(CyclesButtonsPanel, Panel):
1881     bl_label = "Simplify"
1882     bl_context = "render"
1883     bl_options = {'DEFAULT_CLOSED'}
1884     COMPAT_ENGINES = {'CYCLES'}
1885
1886     def draw_header(self, context):
1887         rd = context.scene.render
1888         self.layout.prop(rd, "use_simplify", text="")
1889
1890     def draw(self, context):
1891         pass
1892
1893
1894 class CYCLES_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel):
1895     bl_label = "Viewport"
1896     bl_context = "render"
1897     bl_parent_id = "CYCLES_RENDER_PT_simplify"
1898     COMPAT_ENGINES = {'CYCLES'}
1899
1900     def draw(self, context):
1901         layout = self.layout
1902         layout.use_property_split = True
1903         layout.use_property_decorate = False
1904
1905         scene = context.scene
1906         rd = scene.render
1907         cscene = scene.cycles
1908
1909         layout.active = rd.use_simplify
1910
1911         col = layout.column()
1912         col.prop(rd, "simplify_subdivision", text="Max Subdivision")
1913         col.prop(rd, "simplify_child_particles", text="Child Particles")
1914         col.prop(cscene, "texture_limit", text="Texture Limit")
1915         col.prop(cscene, "ao_bounces", text="AO Bounces")
1916
1917
1918 class CYCLES_RENDER_PT_simplify_render(CyclesButtonsPanel, Panel):
1919     bl_label = "Render"
1920     bl_context = "render"
1921     bl_parent_id = "CYCLES_RENDER_PT_simplify"
1922     COMPAT_ENGINES = {'CYCLES'}
1923
1924     def draw(self, context):
1925         layout = self.layout
1926         layout.use_property_split = True
1927         layout.use_property_decorate = False
1928
1929         scene = context.scene
1930         rd = scene.render
1931         cscene = scene.cycles
1932
1933         layout.active = rd.use_simplify
1934
1935         col = layout.column()
1936
1937         col.prop(rd, "simplify_subdivision_render", text="Max Subdivision")
1938         col.prop(rd, "simplify_child_particles_render", text="Child Particles")
1939         col.prop(cscene, "texture_limit_render", text="Texture Limit")
1940         col.prop(cscene, "ao_bounces_render", text="AO Bounces")
1941
1942
1943 class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
1944     bl_label = "Culling"
1945     bl_context = "render"
1946     bl_parent_id = "CYCLES_RENDER_PT_simplify"
1947     bl_options = {'DEFAULT_CLOSED'}
1948     COMPAT_ENGINES = {'CYCLES'}
1949
1950     def draw(self, context):
1951         layout = self.layout
1952         layout.use_property_split = True
1953         layout.use_property_decorate = False
1954
1955         scene = context.scene
1956         rd = scene.render
1957         cscene = scene.cycles
1958
1959         layout.active = rd.use_simplify
1960
1961         col = layout.column()
1962         col.prop(cscene, "use_camera_cull")
1963         sub = col.column()
1964         sub.active = cscene.use_camera_cull
1965         sub.prop(cscene, "camera_cull_margin")
1966
1967         col = layout.column()
1968         col.prop(cscene, "use_distance_cull")
1969         sub = col.column()
1970         sub.active = cscene.use_distance_cull
1971         sub.prop(cscene, "distance_cull_margin", text="Distance")
1972
1973
1974 class CYCLES_NODE_PT_settings(CyclesNodeButtonsPanel, Panel):
1975     bl_label = "Settings"
1976     bl_category = "Node"
1977     bl_options = {'DEFAULT_CLOSED'}
1978
1979     @classmethod
1980     def poll(cls, context):
1981         snode = context.space_data
1982         return CyclesNodeButtonsPanel.poll(context) and \
1983                snode.tree_type == 'ShaderNodeTree' and snode.id and \
1984                snode.id.bl_rna.identifier == 'Material'
1985
1986     def draw(self, context):
1987         material = context.space_data.id
1988         CYCLES_MATERIAL_PT_settings.draw_shared(self, material)
1989
1990
1991 class CYCLES_NODE_PT_settings_surface(CyclesNodeButtonsPanel, Panel):
1992     bl_label = "Surface"
1993     bl_category = "Node"
1994     bl_parent_id = "CYCLES_NODE_PT_settings"
1995
1996     def draw(self, context):
1997         material = context.space_data.id
1998         CYCLES_MATERIAL_PT_settings_surface.draw_shared(self, material)
1999
2000
2001 class CYCLES_NODE_PT_settings_volume(CyclesNodeButtonsPanel, Panel):
2002     bl_label = "Volume"
2003     bl_category = "Node"
2004     bl_parent_id = "CYCLES_NODE_PT_settings"
2005
2006     def draw(self, context):
2007         material = context.space_data.id
2008         CYCLES_MATERIAL_PT_settings_volume.draw_shared(self, context, material)
2009
2010
2011 def draw_device(self, context):
2012     scene = context.scene
2013     layout = self.layout
2014     layout.use_property_split = True
2015     layout.use_property_decorate = False
2016
2017     if context.engine == 'CYCLES':
2018         from . import engine
2019         cscene = scene.cycles
2020
2021         col = layout.column()
2022         col.prop(cscene, "feature_set")
2023
2024         scene = context.scene
2025
2026         col = layout.column()
2027         col.active = show_device_active(context)
2028         col.prop(cscene, "device")
2029
2030         from . import engine
2031         if engine.with_osl() and use_cpu(context):
2032             col.prop(cscene, "shading_system")
2033
2034
2035 def draw_pause(self, context):
2036     layout = self.layout
2037     scene = context.scene
2038
2039     if context.engine == "CYCLES":
2040         view = context.space_data
2041
2042         if view.shading.type == 'RENDERED':
2043             cscene = scene.cycles
2044             layout.prop(cscene, "preview_pause", icon='PAUSE', text="")
2045
2046
2047 def get_panels():
2048     exclude_panels = {
2049         'DATA_PT_area',
2050         'DATA_PT_camera_dof',
2051         'DATA_PT_falloff_curve',
2052         'DATA_PT_light',
2053         'DATA_PT_preview',
2054         'DATA_PT_spot',
2055         'MATERIAL_PT_context_material',
2056         'MATERIAL_PT_preview',
2057         'VIEWLAYER_PT_filter',
2058         'VIEWLAYER_PT_layer_passes',
2059         'RENDER_PT_post_processing',
2060         'RENDER_PT_simplify',
2061     }
2062
2063     panels = []
2064     for panel in bpy.types.Panel.__subclasses__():
2065         if hasattr(panel, 'COMPAT_ENGINES') and 'BLENDER_RENDER' in panel.COMPAT_ENGINES:
2066             if panel.__name__ not in exclude_panels:
2067                 panels.append(panel)
2068
2069     return panels
2070
2071
2072 classes = (
2073     CYCLES_PT_sampling_presets,
2074     CYCLES_PT_integrator_presets,
2075     CYCLES_RENDER_PT_sampling,
2076     CYCLES_RENDER_PT_sampling_sub_samples,
2077     CYCLES_RENDER_PT_sampling_advanced,
2078     CYCLES_RENDER_PT_light_paths,
2079     CYCLES_RENDER_PT_light_paths_max_bounces,
2080     CYCLES_RENDER_PT_light_paths_clamping,
2081     CYCLES_RENDER_PT_light_paths_caustics,
2082     CYCLES_RENDER_PT_volumes,
2083     CYCLES_RENDER_PT_subdivision,
2084     CYCLES_RENDER_PT_hair,
2085     CYCLES_RENDER_PT_simplify,
2086     CYCLES_RENDER_PT_simplify_viewport,
2087     CYCLES_RENDER_PT_simplify_render,
2088     CYCLES_RENDER_PT_simplify_culling,
2089     CYCLES_RENDER_PT_motion_blur,
2090     CYCLES_RENDER_PT_motion_blur_curve,
2091     CYCLES_RENDER_PT_film,
2092     CYCLES_RENDER_PT_film_pixel_filter,
2093     CYCLES_RENDER_PT_film_transparency,
2094     CYCLES_RENDER_PT_performance,
2095     CYCLES_RENDER_PT_performance_threads,
2096     CYCLES_RENDER_PT_performance_tiles,
2097     CYCLES_RENDER_PT_performance_acceleration_structure,
2098     CYCLES_RENDER_PT_performance_final_render,
2099     CYCLES_RENDER_PT_performance_viewport,
2100     CYCLES_RENDER_PT_filter,
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_OT_use_shading_nodes,
2117     CYCLES_LIGHT_PT_preview,
2118     CYCLES_LIGHT_PT_light,
2119     CYCLES_LIGHT_PT_nodes,
2120     CYCLES_LIGHT_PT_spot,
2121     CYCLES_WORLD_PT_preview,
2122     CYCLES_WORLD_PT_surface,
2123     CYCLES_WORLD_PT_volume,
2124     CYCLES_WORLD_PT_ambient_occlusion,
2125     CYCLES_WORLD_PT_mist,
2126     CYCLES_WORLD_PT_ray_visibility,
2127     CYCLES_WORLD_PT_settings,
2128     CYCLES_WORLD_PT_settings_surface,
2129     CYCLES_WORLD_PT_settings_volume,
2130     CYCLES_MATERIAL_PT_preview,
2131     CYCLES_MATERIAL_PT_surface,
2132     CYCLES_MATERIAL_PT_volume,
2133     CYCLES_MATERIAL_PT_displacement,
2134     CYCLES_MATERIAL_PT_settings,
2135     CYCLES_MATERIAL_PT_settings_surface,
2136     CYCLES_MATERIAL_PT_settings_volume,
2137     CYCLES_RENDER_PT_bake,
2138     CYCLES_RENDER_PT_debug,
2139     CYCLES_NODE_PT_settings,
2140     CYCLES_NODE_PT_settings_surface,
2141     CYCLES_NODE_PT_settings_volume,
2142 )
2143
2144
2145 def register():
2146     from bpy.utils import register_class
2147
2148     bpy.types.RENDER_PT_context.append(draw_device)
2149     bpy.types.VIEW3D_HT_header.append(draw_pause)
2150
2151     for panel in get_panels():
2152         panel.COMPAT_ENGINES.add('CYCLES')
2153
2154     for cls in classes:
2155         register_class(cls)
2156
2157
2158 def unregister():
2159     from bpy.utils import unregister_class
2160
2161     bpy.types.RENDER_PT_context.remove(draw_device)
2162     bpy.types.VIEW3D_HT_header.remove(draw_pause)
2163
2164     for panel in get_panels():
2165         if 'CYCLES' in panel.COMPAT_ENGINES:
2166             panel.COMPAT_ENGINES.remove('CYCLES')
2167
2168     for cls in classes:
2169         unregister_class(cls)