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