Lights: change sun light size to be specified as angle
[blender.git] / intern / cycles / blender / addon / properties.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.props import (
21     BoolProperty,
22     EnumProperty,
23     FloatProperty,
24     IntProperty,
25     PointerProperty,
26     StringProperty,
27 )
28
29 from math import pi
30
31 # enums
32
33 import _cycles
34
35 enum_devices = (
36     ('CPU', "CPU", "Use CPU for rendering"),
37     ('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in the system tab in the user preferences"),
38 )
39
40 if _cycles.with_network:
41     enum_devices += (('NETWORK', "Networked Device", "Use networked device for rendering"),)
42
43 enum_feature_set = (
44     ('SUPPORTED', "Supported", "Only use finished and supported features"),
45     ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future", 'ERROR', 1),
46 )
47
48 enum_displacement_methods = (
49     ('BUMP', "Bump Only", "Bump mapping to simulate the appearance of displacement"),
50     ('DISPLACEMENT', "Displacement Only", "Use true displacement of surface only, requires fine subdivision"),
51     ('BOTH', "Displacement and Bump", "Combination of true displacement and bump mapping for finer detail"),
52 )
53
54 enum_bvh_layouts = (
55     ('BVH2', "BVH2", "", 1),
56     ('BVH4', "BVH4", "", 2),
57     ('BVH8', "BVH8", "", 4),
58 )
59
60 enum_bvh_types = (
61     ('DYNAMIC_BVH', "Dynamic BVH", "Objects can be individually updated, at the cost of slower render time"),
62     ('STATIC_BVH', "Static BVH", "Any object modification requires a complete BVH rebuild, but renders faster"),
63 )
64
65 enum_filter_types = (
66     ('BOX', "Box", "Box filter"),
67     ('GAUSSIAN', "Gaussian", "Gaussian filter"),
68     ('BLACKMAN_HARRIS', "Blackman-Harris", "Blackman-Harris filter"),
69 )
70
71 enum_aperture_types = (
72     ('RADIUS', "Radius", "Directly change the size of the aperture"),
73     ('FSTOP', "F-stop", "Change the size of the aperture by f-stop"),
74 )
75
76 enum_panorama_types = (
77     ('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
78     ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
79     ('FISHEYE_EQUISOLID', "Fisheye Equisolid",
80                           "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
81     ('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
82 )
83
84 enum_curve_primitives = (
85     ('TRIANGLES', "Triangles", "Create triangle geometry around strands"),
86     ('LINE_SEGMENTS', "Line Segments", "Use line segment primitives"),
87     ('CURVE_SEGMENTS', "Curve Segments", "Use segmented cardinal curve primitives"),
88 )
89
90 enum_triangle_curves = (
91     ('CAMERA_TRIANGLES', "Planes", "Create individual triangles forming planes that face camera"),
92     ('TESSELLATED_TRIANGLES', "Tessellated", "Create mesh surrounding each strand"),
93 )
94
95 enum_curve_shape = (
96     ('RIBBONS', "Ribbons", "Ignore thickness of each strand"),
97     ('THICK', "Thick", "Use thickness of strand when rendering"),
98 )
99
100 enum_tile_order = (
101     ('CENTER', "Center", "Render from center to the edges"),
102     ('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"),
103     ('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"),
104     ('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"),
105     ('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"),
106     ('HILBERT_SPIRAL', "Hilbert Spiral", "Render in a Hilbert Spiral"),
107 )
108
109 enum_use_layer_samples = (
110     ('USE', "Use", "Per render layer number of samples override scene samples"),
111     ('BOUNDED', "Bounded", "Bound per render layer number of samples by global samples"),
112     ('IGNORE', "Ignore", "Ignore per render layer number of samples"),
113 )
114
115 enum_sampling_pattern = (
116     ('SOBOL', "Sobol", "Use Sobol random sampling pattern"),
117     ('CORRELATED_MUTI_JITTER', "Correlated Multi-Jitter", "Use Correlated Multi-Jitter random sampling pattern"),
118 )
119
120 enum_integrator = (
121     ('BRANCHED_PATH', "Branched Path Tracing", "Path tracing integrator that branches on the first bounce, giving more control over the number of light and material samples"),
122     ('PATH', "Path Tracing", "Pure path tracing integrator"),
123 )
124
125 enum_volume_sampling = (
126     ('DISTANCE', "Distance", "Use distance sampling, best for dense volumes with lights far away"),
127     ('EQUIANGULAR', "Equiangular", "Use equiangular sampling, best for volumes with low density with light inside or near the volume"),
128     ('MULTIPLE_IMPORTANCE', "Multiple Importance", "Combine distance and equi-angular sampling for volumes where neither method is ideal"),
129 )
130
131 enum_volume_interpolation = (
132     ('LINEAR', "Linear", "Good smoothness and speed"),
133     ('CUBIC', "Cubic", "Smoothed high quality interpolation, but slower")
134 )
135
136 enum_world_mis = (
137     ('NONE', "None", "Don't sample the background, faster but might cause noise for non-solid backgrounds"),
138     ('AUTOMATIC', "Auto", "Automatically try to determine the best setting"),
139     ('MANUAL', "Manual", "Manually set the resolution of the sampling map, higher values are slower and require more memory but reduce noise")
140 )
141
142 enum_device_type = (
143     ('CPU', "CPU", "CPU", 0),
144     ('CUDA', "CUDA", "CUDA", 1),
145     ('OPENCL', "OpenCL", "OpenCL", 2)
146 )
147
148 enum_texture_limit = (
149     ('OFF', "No Limit", "No texture size limit", 0),
150     ('128', "128", "Limit texture size to 128 pixels", 1),
151     ('256', "256", "Limit texture size to 256 pixels", 2),
152     ('512', "512", "Limit texture size to 512 pixels", 3),
153     ('1024', "1024", "Limit texture size to 1024 pixels", 4),
154     ('2048', "2048", "Limit texture size to 2048 pixels", 5),
155     ('4096', "4096", "Limit texture size to 4096 pixels", 6),
156     ('8192', "8192", "Limit texture size to 8192 pixels", 7),
157 )
158
159
160 class CyclesRenderSettings(bpy.types.PropertyGroup):
161
162     device: EnumProperty(
163         name="Device",
164         description="Device to use for rendering",
165         items=enum_devices,
166         default='CPU',
167     )
168     feature_set: EnumProperty(
169         name="Feature Set",
170         description="Feature set to use for rendering",
171         items=enum_feature_set,
172         default='SUPPORTED',
173     )
174     shading_system: BoolProperty(
175         name="Open Shading Language",
176         description="Use Open Shading Language (CPU rendering only)",
177     )
178
179     progressive: EnumProperty(
180         name="Integrator",
181         description="Method to sample lights and materials",
182         items=enum_integrator,
183         default='PATH',
184     )
185
186     use_square_samples: BoolProperty(
187         name="Square Samples",
188         description="Square sampling values for easier artist control",
189         default=False,
190     )
191
192     samples: IntProperty(
193         name="Samples",
194         description="Number of samples to render for each pixel",
195         min=1, max=(1 << 24),
196         default=128,
197     )
198     preview_samples: IntProperty(
199         name="Preview Samples",
200         description="Number of samples to render in the viewport, unlimited if 0",
201         min=0, max=(1 << 24),
202         default=32,
203     )
204     preview_pause: BoolProperty(
205         name="Pause Preview",
206         description="Pause all viewport preview renders",
207         default=False,
208     )
209     aa_samples: IntProperty(
210         name="AA Samples",
211         description="Number of antialiasing samples to render for each pixel",
212         min=1, max=2097151,
213         default=128,
214     )
215     preview_aa_samples: IntProperty(
216         name="AA Samples",
217         description="Number of antialiasing samples to render in the viewport, unlimited if 0",
218         min=0, max=2097151,
219         default=32,
220     )
221     diffuse_samples: IntProperty(
222         name="Diffuse Samples",
223         description="Number of diffuse bounce samples to render for each AA sample",
224         min=1, max=1024,
225         default=1,
226     )
227     glossy_samples: IntProperty(
228         name="Glossy Samples",
229         description="Number of glossy bounce samples to render for each AA sample",
230         min=1, max=1024,
231         default=1,
232     )
233     transmission_samples: IntProperty(
234         name="Transmission Samples",
235         description="Number of transmission bounce samples to render for each AA sample",
236         min=1, max=1024,
237         default=1,
238     )
239     ao_samples: IntProperty(
240         name="Ambient Occlusion Samples",
241         description="Number of ambient occlusion samples to render for each AA sample",
242         min=1, max=1024,
243         default=1,
244     )
245     mesh_light_samples: IntProperty(
246         name="Mesh Light Samples",
247         description="Number of mesh emission light samples to render for each AA sample",
248         min=1, max=1024,
249         default=1,
250     )
251
252     subsurface_samples: IntProperty(
253         name="Subsurface Samples",
254         description="Number of subsurface scattering samples to render for each AA sample",
255         min=1, max=1024,
256         default=1,
257     )
258
259     volume_samples: IntProperty(
260         name="Volume Samples",
261         description="Number of volume scattering samples to render for each AA sample",
262         min=1, max=1024,
263         default=1,
264     )
265
266     sampling_pattern: EnumProperty(
267         name="Sampling Pattern",
268         description="Random sampling pattern used by the integrator",
269         items=enum_sampling_pattern,
270         default='SOBOL',
271     )
272
273     use_layer_samples: EnumProperty(
274         name="Layer Samples",
275         description="How to use per view layer sample settings",
276         items=enum_use_layer_samples,
277         default='USE',
278     )
279
280     sample_all_lights_direct: BoolProperty(
281         name="Sample All Direct Lights",
282         description="Sample all lights (for direct samples), rather than randomly picking one",
283         default=True,
284     )
285
286     sample_all_lights_indirect: BoolProperty(
287         name="Sample All Indirect Lights",
288         description="Sample all lights (for indirect samples), rather than randomly picking one",
289         default=True,
290     )
291     light_sampling_threshold: FloatProperty(
292         name="Light Sampling Threshold",
293         description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
294         "Zero disables the test and never ignores lights",
295         min=0.0, max=1.0,
296         default=0.01,
297     )
298
299     caustics_reflective: BoolProperty(
300         name="Reflective Caustics",
301         description="Use reflective caustics, resulting in a brighter image (more noise but added realism)",
302         default=True,
303     )
304
305     caustics_refractive: BoolProperty(
306         name="Refractive Caustics",
307         description="Use refractive caustics, resulting in a brighter image (more noise but added realism)",
308         default=True,
309     )
310
311     blur_glossy: FloatProperty(
312         name="Filter Glossy",
313         description="Adaptively blur glossy shaders after blurry bounces, "
314         "to reduce noise at the cost of accuracy",
315         min=0.0, max=10.0,
316         default=1.0,
317     )
318
319     max_bounces: IntProperty(
320         name="Max Bounces",
321         description="Total maximum number of bounces",
322         min=0, max=1024,
323         default=12,
324     )
325
326     diffuse_bounces: IntProperty(
327         name="Diffuse Bounces",
328         description="Maximum number of diffuse reflection bounces, bounded by total maximum",
329         min=0, max=1024,
330         default=4,
331     )
332     glossy_bounces: IntProperty(
333         name="Glossy Bounces",
334         description="Maximum number of glossy reflection bounces, bounded by total maximum",
335         min=0, max=1024,
336         default=4,
337     )
338     transmission_bounces: IntProperty(
339         name="Transmission Bounces",
340         description="Maximum number of transmission bounces, bounded by total maximum",
341         min=0, max=1024,
342         default=12,
343     )
344     volume_bounces: IntProperty(
345         name="Volume Bounces",
346         description="Maximum number of volumetric scattering events",
347         min=0, max=1024,
348         default=0,
349     )
350
351     transparent_max_bounces: IntProperty(
352         name="Transparent Max Bounces",
353         description="Maximum number of transparent bounces",
354         min=0, max=1024,
355         default=8,
356     )
357
358     volume_step_size: FloatProperty(
359         name="Step Size",
360         description="Distance between volume shader samples when rendering the volume "
361         "(lower values give more accurate and detailed results, but also increased render time)",
362         default=0.1,
363         min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0, precision=4,
364         unit='LENGTH'
365     )
366
367     volume_max_steps: IntProperty(
368         name="Max Steps",
369         description="Maximum number of steps through the volume before giving up, "
370         "to avoid extremely long render times with big objects or small step sizes",
371         default=1024,
372         min=2, max=65536
373     )
374
375     dicing_rate: FloatProperty(
376         name="Dicing Rate",
377         description="Size of a micropolygon in pixels",
378         min=0.1, max=1000.0, soft_min=0.5,
379         default=1.0,
380         subtype='PIXEL'
381     )
382     preview_dicing_rate: FloatProperty(
383         name="Preview Dicing Rate",
384         description="Size of a micropolygon in pixels during preview render",
385         min=0.1, max=1000.0, soft_min=0.5,
386         default=8.0,
387         subtype='PIXEL'
388     )
389
390     max_subdivisions: IntProperty(
391         name="Max Subdivisions",
392         description="Stop subdividing when this level is reached even if the dice rate would produce finer tessellation",
393         min=0, max=16,
394         default=12,
395     )
396
397     dicing_camera: PointerProperty(
398         name="Dicing Camera",
399         description="Camera to use as reference point when subdividing geometry, useful to avoid crawling "
400         "artifacts in animations when the scene camera is moving",
401         type=bpy.types.Object,
402         poll=lambda self, obj: obj.type == 'CAMERA',
403     )
404     offscreen_dicing_scale: FloatProperty(
405         name="Offscreen Dicing Scale",
406         description="Multiplier for dicing rate of geometry outside of the camera view. The dicing rate "
407         "of objects is gradually increased the further they are outside the camera view. "
408         "Lower values provide higher quality reflections and shadows for off screen objects, "
409         "while higher values use less memory",
410         min=1.0, soft_max=25.0,
411         default=4.0,
412     )
413
414     film_exposure: FloatProperty(
415         name="Exposure",
416         description="Image brightness scale",
417         min=0.0, max=10.0,
418         default=1.0,
419     )
420     film_transparent: BoolProperty(
421         name="Transparent",
422         description="World background is transparent, for compositing the render over another background",
423         default=False,
424     )
425     film_transparent_glass: BoolProperty(
426         name="Transparent Glass",
427         description="Render transmissive surfaces as transparent, for compositing glass over another background",
428         default=False,
429     )
430     film_transparent_roughness: FloatProperty(
431         name="Transparent Roughness Threshold",
432         description="For transparent transmission, keep surfaces with roughness above the threshold opaque",
433         min=0.0, max=1.0,
434         default=0.1,
435     )
436
437     # Really annoyingly, we have to keep it around for a few releases,
438     # otherwise forward compatibility breaks in really bad manner: CRASH!
439     #
440     # TODO(sergey): Remove this during 2.8x series of Blender.
441     filter_type: EnumProperty(
442         name="Filter Type",
443         description="Pixel filter type",
444         items=enum_filter_types,
445         default='BLACKMAN_HARRIS',
446     )
447
448     pixel_filter_type: EnumProperty(
449         name="Filter Type",
450         description="Pixel filter type",
451         items=enum_filter_types,
452         default='BLACKMAN_HARRIS',
453     )
454
455     filter_width: FloatProperty(
456         name="Filter Width",
457         description="Pixel filter width",
458         min=0.01, max=10.0,
459         default=1.5,
460         subtype='PIXEL'
461     )
462
463     seed: IntProperty(
464         name="Seed",
465         description="Seed value for integrator to get different noise patterns",
466         min=0, max=2147483647,
467         default=0,
468     )
469
470     use_animated_seed: BoolProperty(
471         name="Use Animated Seed",
472         description="Use different seed values (and hence noise patterns) at different frames",
473         default=False,
474     )
475
476     sample_clamp_direct: FloatProperty(
477         name="Clamp Direct",
478         description="If non-zero, the maximum value for a direct sample, "
479         "higher values will be scaled down to avoid too "
480         "much noise and slow convergence at the cost of accuracy",
481         min=0.0, max=1e8,
482         default=0.0,
483     )
484
485     sample_clamp_indirect: FloatProperty(
486         name="Clamp Indirect",
487         description="If non-zero, the maximum value for an indirect sample, "
488         "higher values will be scaled down to avoid too "
489         "much noise and slow convergence at the cost of accuracy",
490         min=0.0, max=1e8,
491         default=10.0,
492     )
493
494     debug_tile_size: IntProperty(
495         name="Tile Size",
496         description="",
497         min=1, max=4096,
498         default=1024,
499     )
500
501     preview_start_resolution: IntProperty(
502         name="Start Resolution",
503         description="Resolution to start rendering preview at, "
504         "progressively increasing it to the full viewport size",
505         min=8, max=16384,
506         default=64,
507         subtype='PIXEL'
508     )
509
510     debug_reset_timeout: FloatProperty(
511         name="Reset timeout",
512         description="",
513         min=0.01, max=10.0,
514         default=0.1,
515     )
516     debug_cancel_timeout: FloatProperty(
517         name="Cancel timeout",
518         description="",
519         min=0.01, max=10.0,
520         default=0.1,
521     )
522     debug_text_timeout: FloatProperty(
523         name="Text timeout",
524         description="",
525         min=0.01, max=10.0,
526         default=1.0,
527     )
528
529     debug_bvh_type: EnumProperty(
530         name="Viewport BVH Type",
531         description="Choose between faster updates, or faster render",
532         items=enum_bvh_types,
533         default='DYNAMIC_BVH',
534     )
535     use_bvh_embree: BoolProperty(
536         name="Use Embree",
537         description="Use Embree as ray accelerator",
538         default=False,
539     )
540     debug_use_spatial_splits: BoolProperty(
541         name="Use Spatial Splits",
542         description="Use BVH spatial splits: longer builder time, faster render",
543         default=False,
544     )
545     debug_use_hair_bvh: BoolProperty(
546         name="Use Hair BVH",
547         description="Use special type BVH optimized for hair (uses more ram but renders faster)",
548         default=True,
549     )
550     debug_bvh_time_steps: IntProperty(
551         name="BVH Time Steps",
552         description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
553         default=0,
554         min=0, max=16,
555     )
556     tile_order: EnumProperty(
557         name="Tile Order",
558         description="Tile order for rendering",
559         items=enum_tile_order,
560         default='HILBERT_SPIRAL',
561         options=set(),  # Not animatable!
562     )
563     use_progressive_refine: BoolProperty(
564         name="Progressive Refine",
565         description="Instead of rendering each tile until it is finished, "
566         "refine the whole image progressively "
567         "(this renders somewhat slower, "
568         "but time can be saved by manually stopping the render when the noise is low enough)",
569         default=False,
570     )
571
572     bake_type: EnumProperty(
573         name="Bake Type",
574         default='COMBINED',
575         description="Type of pass to bake",
576         items=(
577             ('COMBINED', "Combined", ""),
578             ('AO', "Ambient Occlusion", ""),
579             ('SHADOW', "Shadow", ""),
580             ('NORMAL', "Normal", ""),
581             ('UV', "UV", ""),
582             ('ROUGHNESS', "Roughness", ""),
583             ('EMIT', "Emit", ""),
584             ('ENVIRONMENT', "Environment", ""),
585             ('DIFFUSE', "Diffuse", ""),
586             ('GLOSSY', "Glossy", ""),
587             ('TRANSMISSION', "Transmission", ""),
588             ('SUBSURFACE', "Subsurface", ""),
589         ),
590     )
591
592     use_camera_cull: BoolProperty(
593         name="Use Camera Cull",
594         description="Allow objects to be culled based on the camera frustum",
595         default=False,
596     )
597
598     camera_cull_margin: FloatProperty(
599         name="Camera Cull Margin",
600         description="Margin for the camera space culling",
601         default=0.1,
602         min=0.0, max=5.0,
603         subtype='FACTOR'
604     )
605
606     use_distance_cull: BoolProperty(
607         name="Use Distance Cull",
608         description="Allow objects to be culled based on the distance from camera",
609         default=False,
610     )
611
612     distance_cull_margin: FloatProperty(
613         name="Cull Distance",
614         description="Cull objects which are further away from camera than this distance",
615         default=50,
616         min=0.0,
617         unit='LENGTH'
618     )
619
620     motion_blur_position: EnumProperty(
621         name="Motion Blur Position",
622         default='CENTER',
623         description="Offset for the shutter's time interval, allows to change the motion blur trails",
624         items=(
625             ('START', "Start on Frame", "The shutter opens at the current frame"),
626             ('CENTER', "Center on Frame", "The shutter is open during the current frame"),
627             ('END', "End on Frame", "The shutter closes at the current frame"),
628         ),
629     )
630
631     rolling_shutter_type: EnumProperty(
632         name="Shutter Type",
633         default='NONE',
634         description="Type of rolling shutter effect matching CMOS-based cameras",
635         items=(
636             ('NONE', "None", "No rolling shutter effect used"),
637             ('TOP', "Top-Bottom", "Sensor is being scanned from top to bottom")
638             # TODO(seergey): Are there real cameras with different scanning direction?
639         ),
640     )
641
642     rolling_shutter_duration: FloatProperty(
643         name="Rolling Shutter Duration",
644         description="Scanline \"exposure\" time for the rolling shutter effect",
645         default=0.1,
646         min=0.0, max=1.0,
647         subtype='FACTOR',
648     )
649
650     texture_limit: EnumProperty(
651         name="Viewport Texture Limit",
652         default='OFF',
653         description="Limit texture size used by viewport rendering",
654         items=enum_texture_limit
655     )
656
657     texture_limit_render: EnumProperty(
658         name="Render Texture Limit",
659         default='OFF',
660         description="Limit texture size used by final rendering",
661         items=enum_texture_limit
662     )
663
664     ao_bounces: IntProperty(
665         name="AO Bounces",
666         default=0,
667         description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
668         min=0, max=1024,
669     )
670
671     ao_bounces_render: IntProperty(
672         name="AO Bounces Render",
673         default=0,
674         description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
675         min=0, max=1024,
676     )
677
678     # Various fine-tuning debug flags
679
680     def _devices_update_callback(self, context):
681         import _cycles
682         scene = context.scene.as_pointer()
683         return _cycles.debug_flags_update(scene)
684
685     debug_use_cpu_avx2: BoolProperty(name="AVX2", default=True)
686     debug_use_cpu_avx: BoolProperty(name="AVX", default=True)
687     debug_use_cpu_sse41: BoolProperty(name="SSE41", default=True)
688     debug_use_cpu_sse3: BoolProperty(name="SSE3", default=True)
689     debug_use_cpu_sse2: BoolProperty(name="SSE2", default=True)
690     debug_bvh_layout: EnumProperty(
691         name="BVH Layout",
692         items=enum_bvh_layouts,
693         default='BVH8',
694     )
695     debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False)
696
697     debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False)
698     debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
699
700     debug_opencl_kernel_type: EnumProperty(
701         name="OpenCL Kernel Type",
702         default='DEFAULT',
703         items=(
704             ('DEFAULT', "Default", ""),
705             ('MEGA', "Mega", ""),
706             ('SPLIT', "Split", ""),
707         ),
708         update=_devices_update_callback
709     )
710
711     debug_opencl_device_type: EnumProperty(
712         name="OpenCL Device Type",
713         default='ALL',
714         items=(
715             ('NONE', "None", ""),
716             ('ALL', "All", ""),
717             ('DEFAULT', "Default", ""),
718             ('CPU', "CPU", ""),
719             ('GPU', "GPU", ""),
720             ('ACCELERATOR', "Accelerator", ""),
721         ),
722         update=_devices_update_callback
723     )
724
725     del _devices_update_callback
726
727     debug_use_opencl_debug: BoolProperty(name="Debug OpenCL", default=False)
728
729     debug_opencl_mem_limit: IntProperty(
730         name="Memory limit",
731         default=0,
732         description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)"
733     )
734
735     @classmethod
736     def register(cls):
737         bpy.types.Scene.cycles = PointerProperty(
738             name="Cycles Render Settings",
739             description="Cycles render settings",
740             type=cls,
741         )
742
743     @classmethod
744     def unregister(cls):
745         del bpy.types.Scene.cycles
746
747
748 class CyclesCameraSettings(bpy.types.PropertyGroup):
749
750     aperture_type: EnumProperty(
751         name="Aperture Type",
752         description="Use f-stop number or aperture radius",
753         items=enum_aperture_types,
754         default='RADIUS',
755     )
756     aperture_fstop: FloatProperty(
757         name="Aperture f-stop",
758         description="F-stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
759         min=0.0, soft_min=0.1, soft_max=64.0,
760         default=5.6,
761         step=10,
762         precision=1,
763     )
764     aperture_size: FloatProperty(
765         name="Aperture Size",
766         description="Radius of the aperture for depth of field (higher values give more defocus)",
767         min=0.0, soft_max=10.0,
768         default=0.0,
769         step=1,
770         precision=4,
771         subtype='DISTANCE',
772     )
773     aperture_blades: IntProperty(
774         name="Aperture Blades",
775         description="Number of blades in aperture for polygonal bokeh (at least 3)",
776         min=0, max=100,
777         default=0,
778     )
779     aperture_rotation: FloatProperty(
780         name="Aperture Rotation",
781         description="Rotation of blades in aperture",
782         soft_min=-pi, soft_max=pi,
783         subtype='ANGLE',
784         default=0,
785     )
786     aperture_ratio: FloatProperty(
787         name="Aperture Ratio",
788         description="Distortion to simulate anamorphic lens bokeh",
789         min=0.01, soft_min=1.0, soft_max=2.0,
790         default=1.0,
791         precision=4,
792     )
793     panorama_type: EnumProperty(
794         name="Panorama Type",
795         description="Distortion to use for the calculation",
796         items=enum_panorama_types,
797         default='FISHEYE_EQUISOLID',
798     )
799     fisheye_fov: FloatProperty(
800         name="Field of View",
801         description="Field of view for the fisheye lens",
802         min=0.1745, soft_max=2.0 * pi, max=10.0 * pi,
803         subtype='ANGLE',
804         default=pi,
805     )
806     fisheye_lens: FloatProperty(
807         name="Fisheye Lens",
808         description="Lens focal length (mm)",
809         min=0.01, soft_max=15.0, max=100.0,
810         default=10.5,
811     )
812     latitude_min: FloatProperty(
813         name="Min Latitude",
814         description="Minimum latitude (vertical angle) for the equirectangular lens",
815         min=-0.5 * pi, max=0.5 * pi,
816         subtype='ANGLE',
817         default=-0.5 * pi,
818     )
819     latitude_max: FloatProperty(
820         name="Max Latitude",
821         description="Maximum latitude (vertical angle) for the equirectangular lens",
822         min=-0.5 * pi, max=0.5 * pi,
823         subtype='ANGLE',
824         default=0.5 * pi,
825     )
826     longitude_min: FloatProperty(
827         name="Min Longitude",
828         description="Minimum longitude (horizontal angle) for the equirectangular lens",
829         min=-pi, max=pi,
830         subtype='ANGLE',
831         default=-pi,
832     )
833     longitude_max: FloatProperty(
834         name="Max Longitude",
835         description="Maximum longitude (horizontal angle) for the equirectangular lens",
836         min=-pi, max=pi,
837         subtype='ANGLE',
838         default=pi,
839     )
840
841     @classmethod
842     def register(cls):
843         bpy.types.Camera.cycles = PointerProperty(
844             name="Cycles Camera Settings",
845             description="Cycles camera settings",
846             type=cls,
847         )
848
849     @classmethod
850     def unregister(cls):
851         del bpy.types.Camera.cycles
852
853
854 class CyclesMaterialSettings(bpy.types.PropertyGroup):
855
856     sample_as_light: BoolProperty(
857         name="Multiple Importance Sample",
858         description="Use multiple importance sampling for this material, "
859         "disabling may reduce overall noise for large "
860         "objects that emit little light compared to other light sources",
861         default=True,
862     )
863     use_transparent_shadow: BoolProperty(
864         name="Transparent Shadows",
865         description="Use transparent shadows for this material if it contains a Transparent BSDF, "
866         "disabling will render faster but not give accurate shadows",
867         default=True,
868     )
869     homogeneous_volume: BoolProperty(
870         name="Homogeneous Volume",
871         description="When using volume rendering, assume volume has the same density everywhere "
872         "(not using any textures), for faster rendering",
873         default=False,
874     )
875     volume_sampling: EnumProperty(
876         name="Volume Sampling",
877         description="Sampling method to use for volumes",
878         items=enum_volume_sampling,
879         default='MULTIPLE_IMPORTANCE',
880     )
881
882     volume_interpolation: EnumProperty(
883         name="Volume Interpolation",
884         description="Interpolation method to use for smoke/fire volumes",
885         items=enum_volume_interpolation,
886         default='LINEAR',
887     )
888
889     displacement_method: EnumProperty(
890         name="Displacement Method",
891         description="Method to use for the displacement",
892         items=enum_displacement_methods,
893         default='BUMP',
894     )
895
896     @classmethod
897     def register(cls):
898         bpy.types.Material.cycles = PointerProperty(
899             name="Cycles Material Settings",
900             description="Cycles material settings",
901             type=cls,
902         )
903
904     @classmethod
905     def unregister(cls):
906         del bpy.types.Material.cycles
907
908
909 class CyclesLightSettings(bpy.types.PropertyGroup):
910
911     cast_shadow: BoolProperty(
912         name="Cast Shadow",
913         description="Light casts shadows",
914         default=True,
915     )
916     samples: IntProperty(
917         name="Samples",
918         description="Number of light samples to render for each AA sample",
919         min=1, max=10000,
920         default=1,
921     )
922     max_bounces: IntProperty(
923         name="Max Bounces",
924         description="Maximum number of bounces the light will contribute to the render",
925         min=0, max=1024,
926         default=1024,
927     )
928     use_multiple_importance_sampling: BoolProperty(
929         name="Multiple Importance Sample",
930         description="Use multiple importance sampling for the light, "
931         "reduces noise for area lights and sharp glossy materials",
932         default=True,
933     )
934     is_portal: BoolProperty(
935         name="Is Portal",
936         description="Use this area light to guide sampling of the background, "
937         "note that this will make the light invisible",
938         default=False,
939     )
940
941     @classmethod
942     def register(cls):
943         bpy.types.Light.cycles = PointerProperty(
944             name="Cycles Light Settings",
945             description="Cycles light settings",
946             type=cls,
947         )
948
949     @classmethod
950     def unregister(cls):
951         del bpy.types.Light.cycles
952
953
954 class CyclesWorldSettings(bpy.types.PropertyGroup):
955
956     sampling_method: EnumProperty(
957         name="Sampling method",
958         description="How to sample the background light",
959         items=enum_world_mis,
960         default='AUTOMATIC',
961     )
962     sample_map_resolution: IntProperty(
963         name="Map Resolution",
964         description="Importance map size is resolution x resolution/2; "
965         "higher values potentially produce less noise, at the cost of memory and speed",
966         min=4, max=8192,
967         default=1024,
968     )
969     samples: IntProperty(
970         name="Samples",
971         description="Number of light samples to render for each AA sample",
972         min=1, max=10000,
973         default=1,
974     )
975     max_bounces: IntProperty(
976         name="Max Bounces",
977         description="Maximum number of bounces the background light will contribute to the render",
978         min=0, max=1024,
979         default=1024,
980     )
981     homogeneous_volume: BoolProperty(
982         name="Homogeneous Volume",
983         description="When using volume rendering, assume volume has the same density everywhere"
984         "(not using any textures), for faster rendering",
985         default=False,
986     )
987     volume_sampling: EnumProperty(
988         name="Volume Sampling",
989         description="Sampling method to use for volumes",
990         items=enum_volume_sampling,
991         default='EQUIANGULAR',
992     )
993     volume_interpolation: EnumProperty(
994         name="Volume Interpolation",
995         description="Interpolation method to use for volumes",
996         items=enum_volume_interpolation,
997         default='LINEAR',
998     )
999
1000     @classmethod
1001     def register(cls):
1002         bpy.types.World.cycles = PointerProperty(
1003             name="Cycles World Settings",
1004             description="Cycles world settings",
1005             type=cls,
1006         )
1007
1008     @classmethod
1009     def unregister(cls):
1010         del bpy.types.World.cycles
1011
1012
1013 class CyclesVisibilitySettings(bpy.types.PropertyGroup):
1014
1015     camera: BoolProperty(
1016         name="Camera",
1017         description="Object visibility for camera rays",
1018         default=True,
1019     )
1020     diffuse: BoolProperty(
1021         name="Diffuse",
1022         description="Object visibility for diffuse reflection rays",
1023         default=True,
1024     )
1025     glossy: BoolProperty(
1026         name="Glossy",
1027         description="Object visibility for glossy reflection rays",
1028         default=True,
1029     )
1030     transmission: BoolProperty(
1031         name="Transmission",
1032         description="Object visibility for transmission rays",
1033         default=True,
1034     )
1035     shadow: BoolProperty(
1036         name="Shadow",
1037         description="Object visibility for shadow rays",
1038         default=True,
1039     )
1040     scatter: BoolProperty(
1041         name="Volume Scatter",
1042         description="Object visibility for volume scatter rays",
1043         default=True,
1044     )
1045
1046     @classmethod
1047     def register(cls):
1048         bpy.types.Object.cycles_visibility = PointerProperty(
1049             name="Cycles Visibility Settings",
1050             description="Cycles visibility settings",
1051             type=cls,
1052         )
1053
1054         bpy.types.World.cycles_visibility = PointerProperty(
1055             name="Cycles Visibility Settings",
1056             description="Cycles visibility settings",
1057             type=cls,
1058         )
1059
1060     @classmethod
1061     def unregister(cls):
1062         del bpy.types.Object.cycles_visibility
1063         del bpy.types.World.cycles_visibility
1064
1065
1066 class CyclesMeshSettings(bpy.types.PropertyGroup):
1067     @classmethod
1068     def register(cls):
1069         bpy.types.Mesh.cycles = PointerProperty(
1070             name="Cycles Mesh Settings",
1071             description="Cycles mesh settings",
1072             type=cls,
1073         )
1074         bpy.types.Curve.cycles = PointerProperty(
1075             name="Cycles Mesh Settings",
1076             description="Cycles mesh settings",
1077             type=cls,
1078         )
1079         bpy.types.MetaBall.cycles = PointerProperty(
1080             name="Cycles Mesh Settings",
1081             description="Cycles mesh settings",
1082             type=cls,
1083         )
1084
1085     @classmethod
1086     def unregister(cls):
1087         del bpy.types.Mesh.cycles
1088         del bpy.types.Curve.cycles
1089         del bpy.types.MetaBall.cycles
1090
1091
1092 class CyclesObjectSettings(bpy.types.PropertyGroup):
1093
1094     use_motion_blur: BoolProperty(
1095         name="Use Motion Blur",
1096         description="Use motion blur for this object",
1097         default=True,
1098     )
1099
1100     use_deform_motion: BoolProperty(
1101         name="Use Deformation Motion",
1102         description="Use deformation motion blur for this object",
1103         default=True,
1104     )
1105
1106     motion_steps: IntProperty(
1107         name="Motion Steps",
1108         description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
1109         min=1, soft_max=8,
1110         default=1,
1111     )
1112
1113     use_camera_cull: BoolProperty(
1114         name="Use Camera Cull",
1115         description="Allow this object and its duplicators to be culled by camera space culling",
1116         default=False,
1117     )
1118
1119     use_distance_cull: BoolProperty(
1120         name="Use Distance Cull",
1121         description="Allow this object and its duplicators to be culled by distance from camera",
1122         default=False,
1123     )
1124
1125     use_adaptive_subdivision: BoolProperty(
1126         name="Use Adaptive Subdivision",
1127         description="Use adaptive render time subdivision",
1128         default=False,
1129     )
1130
1131     dicing_rate: FloatProperty(
1132         name="Dicing Scale",
1133         description="Multiplier for scene dicing rate (located in the Subdivision panel)",
1134         min=0.1, max=1000.0, soft_min=0.5,
1135         default=1.0,
1136     )
1137
1138     is_shadow_catcher: BoolProperty(
1139         name="Shadow Catcher",
1140         description="Only render shadows on this object, for compositing renders into real footage",
1141         default=False,
1142     )
1143
1144     is_holdout: BoolProperty(
1145         name="Holdout",
1146         description="Render objects as a holdout or matte, creating a "
1147         "hole in the image with zero alpha, to fill out in "
1148         "compositing with real footage or another render",
1149         default=False,
1150     )
1151
1152     @classmethod
1153     def register(cls):
1154         bpy.types.Object.cycles = PointerProperty(
1155             name="Cycles Object Settings",
1156             description="Cycles object settings",
1157             type=cls,
1158         )
1159
1160     @classmethod
1161     def unregister(cls):
1162         del bpy.types.Object.cycles
1163
1164
1165 class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
1166
1167     primitive: EnumProperty(
1168         name="Primitive",
1169         description="Type of primitive used for hair rendering",
1170         items=enum_curve_primitives,
1171         default='LINE_SEGMENTS',
1172     )
1173     shape: EnumProperty(
1174         name="Shape",
1175         description="Form of hair",
1176         items=enum_curve_shape,
1177         default='THICK',
1178     )
1179     cull_backfacing: BoolProperty(
1180         name="Cull Back-faces",
1181         description="Do not test the back-face of each strand",
1182         default=True,
1183     )
1184     use_curves: BoolProperty(
1185         name="Use Cycles Hair Rendering",
1186         description="Activate Cycles hair rendering for particle system",
1187         default=True,
1188     )
1189     resolution: IntProperty(
1190         name="Resolution",
1191         description="Resolution of generated mesh",
1192         min=3, max=64,
1193         default=3,
1194     )
1195     subdivisions: IntProperty(
1196         name="Subdivisions",
1197         description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
1198         min=0, max=24,
1199         default=4,
1200     )
1201
1202     @classmethod
1203     def register(cls):
1204         bpy.types.Scene.cycles_curves = PointerProperty(
1205             name="Cycles Hair Rendering Settings",
1206             description="Cycles hair rendering settings",
1207             type=cls,
1208         )
1209
1210     @classmethod
1211     def unregister(cls):
1212         del bpy.types.Scene.cycles_curves
1213
1214
1215 def update_render_passes(self, context):
1216     view_layer = context.view_layer
1217     view_layer.update_render_passes()
1218
1219
1220 class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
1221
1222     pass_debug_bvh_traversed_nodes: BoolProperty(
1223         name="Debug BVH Traversed Nodes",
1224         description="Store Debug BVH Traversed Nodes pass",
1225         default=False,
1226         update=update_render_passes,
1227     )
1228     pass_debug_bvh_traversed_instances: BoolProperty(
1229         name="Debug BVH Traversed Instances",
1230         description="Store Debug BVH Traversed Instances pass",
1231         default=False,
1232         update=update_render_passes,
1233     )
1234     pass_debug_bvh_intersections: BoolProperty(
1235         name="Debug BVH Intersections",
1236         description="Store Debug BVH Intersections",
1237         default=False,
1238         update=update_render_passes,
1239     )
1240     pass_debug_ray_bounces: BoolProperty(
1241         name="Debug Ray Bounces",
1242         description="Store Debug Ray Bounces pass",
1243         default=False,
1244         update=update_render_passes,
1245     )
1246     pass_debug_render_time: BoolProperty(
1247         name="Debug Render Time",
1248         description="Render time in milliseconds per sample and pixel",
1249         default=False,
1250         update=update_render_passes,
1251     )
1252     use_pass_volume_direct: BoolProperty(
1253         name="Volume Direct",
1254         description="Deliver direct volumetric scattering pass",
1255         default=False,
1256         update=update_render_passes,
1257     )
1258     use_pass_volume_indirect: BoolProperty(
1259         name="Volume Indirect",
1260         description="Deliver indirect volumetric scattering pass",
1261         default=False,
1262         update=update_render_passes,
1263     )
1264
1265     use_denoising: BoolProperty(
1266         name="Use Denoising",
1267         description="Denoise the rendered image",
1268         default=False,
1269         update=update_render_passes,
1270     )
1271     denoising_diffuse_direct: BoolProperty(
1272         name="Diffuse Direct",
1273         description="Denoise the direct diffuse lighting",
1274         default=True,
1275     )
1276     denoising_diffuse_indirect: BoolProperty(
1277         name="Diffuse Indirect",
1278         description="Denoise the indirect diffuse lighting",
1279         default=True,
1280     )
1281     denoising_glossy_direct: BoolProperty(
1282         name="Glossy Direct",
1283         description="Denoise the direct glossy lighting",
1284         default=True,
1285     )
1286     denoising_glossy_indirect: BoolProperty(
1287         name="Glossy Indirect",
1288         description="Denoise the indirect glossy lighting",
1289         default=True,
1290     )
1291     denoising_transmission_direct: BoolProperty(
1292         name="Transmission Direct",
1293         description="Denoise the direct transmission lighting",
1294         default=True,
1295     )
1296     denoising_transmission_indirect: BoolProperty(
1297         name="Transmission Indirect",
1298         description="Denoise the indirect transmission lighting",
1299         default=True,
1300     )
1301     denoising_subsurface_direct: BoolProperty(
1302         name="Subsurface Direct",
1303         description="Denoise the direct subsurface lighting",
1304         default=True,
1305     )
1306     denoising_subsurface_indirect: BoolProperty(
1307         name="Subsurface Indirect",
1308         description="Denoise the indirect subsurface lighting",
1309         default=True,
1310     )
1311     denoising_strength: FloatProperty(
1312         name="Denoising Strength",
1313         description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
1314         min=0.0, max=1.0,
1315         default=0.5,
1316     )
1317     denoising_feature_strength: FloatProperty(
1318         name="Denoising Feature Strength",
1319         description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
1320         min=0.0, max=1.0,
1321         default=0.5,
1322     )
1323     denoising_radius: IntProperty(
1324         name="Denoising Radius",
1325         description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
1326         min=1, max=25,
1327         default=8,
1328         subtype="PIXEL",
1329     )
1330     denoising_relative_pca: BoolProperty(
1331         name="Relative filter",
1332         description="When removing pixels that don't carry information, use a relative threshold instead of an absolute one (can help to reduce artifacts, but might cause detail loss around edges)",
1333         default=False,
1334     )
1335     denoising_store_passes: BoolProperty(
1336         name="Store denoising passes",
1337         description="Store the denoising feature passes and the noisy image",
1338         default=False,
1339         update=update_render_passes,
1340     )
1341     denoising_neighbor_frames: IntProperty(
1342         name="Neighbor Frames",
1343         description="Number of neighboring frames to use for denoising animations (more frames produce smoother results at the cost of performance)",
1344         min=0, max=7,
1345         default=0,
1346     )
1347     use_pass_crypto_object: BoolProperty(
1348         name="Cryptomatte Object",
1349         description="Render cryptomatte object pass, for isolating objects in compositing",
1350         default=False,
1351         update=update_render_passes,
1352         )
1353     use_pass_crypto_material: BoolProperty(
1354         name="Cryptomatte Material",
1355         description="Render cryptomatte material pass, for isolating materials in compositing",
1356         default=False,
1357         update=update_render_passes,
1358         )
1359     use_pass_crypto_asset: BoolProperty(
1360         name="Cryptomatte Asset",
1361         description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
1362         default=False,
1363         update=update_render_passes,
1364         )
1365     pass_crypto_depth: IntProperty(
1366         name="Cryptomatte Levels",
1367         description="Sets how many unique objects can be distinguished per pixel",
1368         default=6, min=2, max=16, step=2,
1369         update=update_render_passes,
1370         )
1371     pass_crypto_accurate: BoolProperty(
1372         name="Cryptomatte Accurate",
1373         description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
1374         default=True,
1375         update=update_render_passes,
1376         )
1377
1378     @classmethod
1379     def register(cls):
1380         bpy.types.ViewLayer.cycles = PointerProperty(
1381             name="Cycles ViewLayer Settings",
1382             description="Cycles ViewLayer Settings",
1383             type=cls,
1384         )
1385
1386     @classmethod
1387     def unregister(cls):
1388         del bpy.types.ViewLayer.cycles
1389
1390
1391 class CyclesDeviceSettings(bpy.types.PropertyGroup):
1392     id: StringProperty(name="ID")
1393     name: StringProperty(name="Name")
1394     use: BoolProperty(name="Use", default=True)
1395     type: EnumProperty(name="Type", items=enum_device_type, default='CUDA')
1396
1397
1398 class CyclesPreferences(bpy.types.AddonPreferences):
1399     bl_idname = __package__
1400
1401     def get_device_types(self, context):
1402         import _cycles
1403         has_cuda, has_opencl = _cycles.get_device_types()
1404         list = [('NONE', "None", "Don't use compute device", 0)]
1405         if has_cuda:
1406             list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
1407         if has_opencl:
1408             list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
1409         return list
1410
1411     compute_device_type: EnumProperty(
1412         name="Compute Device Type",
1413         description="Device to use for computation (rendering with Cycles)",
1414         items=get_device_types,
1415     )
1416
1417     devices: bpy.props.CollectionProperty(type=CyclesDeviceSettings)
1418
1419     def find_existing_device_entry(self, device):
1420         for device_entry in self.devices:
1421             if device_entry.id == device[2] and device_entry.type == device[1]:
1422                 return device_entry
1423         return None
1424
1425     def update_device_entries(self, device_list):
1426         for device in device_list:
1427             if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
1428                 continue
1429             # Try to find existing Device entry
1430             entry = self.find_existing_device_entry(device)
1431             if not entry:
1432                 # Create new entry if no existing one was found
1433                 entry = self.devices.add()
1434                 entry.id = device[2]
1435                 entry.name = device[0]
1436                 entry.type = device[1]
1437                 entry.use = entry.type != 'CPU'
1438             elif entry.name != device[0]:
1439                 # Update name in case it changed
1440                 entry.name = device[0]
1441
1442     # Gets all devices types by default.
1443     def get_devices(self, compute_device_type=''):
1444         import _cycles
1445         # Layout of the device tuples: (Name, Type, Persistent ID)
1446         device_list = _cycles.available_devices(compute_device_type)
1447         # Make sure device entries are up to date and not referenced before
1448         # we know we don't add new devices. This way we guarantee to not
1449         # hold pointers to a resized array.
1450         self.update_device_entries(device_list)
1451         # Sort entries into lists
1452         cuda_devices = []
1453         opencl_devices = []
1454         cpu_devices = []
1455         for device in device_list:
1456             entry = self.find_existing_device_entry(device)
1457             if entry.type == 'CUDA':
1458                 cuda_devices.append(entry)
1459             elif entry.type == 'OPENCL':
1460                 opencl_devices.append(entry)
1461             elif entry.type == 'CPU':
1462                 cpu_devices.append(entry)
1463         # Extend all GPU devices with CPU.
1464         cuda_devices.extend(cpu_devices)
1465         opencl_devices.extend(cpu_devices)
1466         return cuda_devices, opencl_devices
1467
1468     def get_num_gpu_devices(self):
1469         import _cycles
1470         device_list = _cycles.available_devices(self.compute_device_type)
1471         num = 0
1472         for device in device_list:
1473             if device[1] != self.compute_device_type:
1474                 continue
1475             for dev in self.devices:
1476                 if dev.use and dev.id == device[2]:
1477                     num += 1
1478         return num
1479
1480     def has_active_device(self):
1481         return self.get_num_gpu_devices() > 0
1482
1483     def _draw_devices(self, layout, device_type, devices):
1484         box = layout.box()
1485
1486         found_device = False
1487         for device in devices:
1488             if device.type == device_type:
1489                 found_device = True
1490                 break
1491
1492         if not found_device:
1493             col = box.column(align=True)
1494             col.label(text="No compatible GPUs found for path tracing", icon='INFO')
1495             col.label(text="Cycles will render on the CPU", icon='BLANK1')
1496             return
1497
1498         for device in devices:
1499             box.prop(device, "use", text=device.name)
1500
1501     def draw_impl(self, layout, context):
1502         row = layout.row()
1503         row.prop(self, "compute_device_type", expand=True)
1504
1505         cuda_devices, opencl_devices = self.get_devices(self.compute_device_type)
1506         row = layout.row()
1507         if self.compute_device_type == 'CUDA':
1508             self._draw_devices(row, 'CUDA', cuda_devices)
1509         elif self.compute_device_type == 'OPENCL':
1510             self._draw_devices(row, 'OPENCL', opencl_devices)
1511
1512     def draw(self, context):
1513         self.draw_impl(self.layout, context)
1514
1515
1516 def register():
1517     bpy.utils.register_class(CyclesRenderSettings)
1518     bpy.utils.register_class(CyclesCameraSettings)
1519     bpy.utils.register_class(CyclesMaterialSettings)
1520     bpy.utils.register_class(CyclesLightSettings)
1521     bpy.utils.register_class(CyclesWorldSettings)
1522     bpy.utils.register_class(CyclesVisibilitySettings)
1523     bpy.utils.register_class(CyclesMeshSettings)
1524     bpy.utils.register_class(CyclesObjectSettings)
1525     bpy.utils.register_class(CyclesCurveRenderSettings)
1526     bpy.utils.register_class(CyclesDeviceSettings)
1527     bpy.utils.register_class(CyclesPreferences)
1528     bpy.utils.register_class(CyclesRenderLayerSettings)
1529
1530
1531 def unregister():
1532     bpy.utils.unregister_class(CyclesRenderSettings)
1533     bpy.utils.unregister_class(CyclesCameraSettings)
1534     bpy.utils.unregister_class(CyclesMaterialSettings)
1535     bpy.utils.unregister_class(CyclesLightSettings)
1536     bpy.utils.unregister_class(CyclesWorldSettings)
1537     bpy.utils.unregister_class(CyclesMeshSettings)
1538     bpy.utils.unregister_class(CyclesObjectSettings)
1539     bpy.utils.unregister_class(CyclesVisibilitySettings)
1540     bpy.utils.unregister_class(CyclesCurveRenderSettings)
1541     bpy.utils.unregister_class(CyclesDeviceSettings)
1542     bpy.utils.unregister_class(CyclesPreferences)
1543     bpy.utils.unregister_class(CyclesRenderLayerSettings)