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