Merge branch 'master' into blender2.8
[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=2147483647,
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=2147483647,
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 render 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     )
365
366     volume_max_steps: IntProperty(
367         name="Max Steps",
368         description="Maximum number of steps through the volume before giving up, "
369         "to avoid extremely long render times with big objects or small step sizes",
370         default=1024,
371         min=2, max=65536
372     )
373
374     dicing_rate: FloatProperty(
375         name="Dicing Rate",
376         description="Size of a micropolygon in pixels",
377         min=0.1, max=1000.0, soft_min=0.5,
378         default=1.0,
379         subtype="PIXEL"
380     )
381     preview_dicing_rate: FloatProperty(
382         name="Preview Dicing Rate",
383         description="Size of a micropolygon in pixels during preview render",
384         min=0.1, max=1000.0, soft_min=0.5,
385         default=8.0,
386         subtype="PIXEL"
387     )
388
389     max_subdivisions: IntProperty(
390         name="Max Subdivisions",
391         description="Stop subdividing when this level is reached even if the dice rate would produce finer tessellation",
392         min=0, max=16,
393         default=12,
394     )
395
396     dicing_camera: PointerProperty(
397         name="Dicing Camera",
398         description="Camera to use as reference point when subdividing geometry, useful to avoid crawling "
399         "artifacts in animations when the scene camera is moving",
400         type=bpy.types.Object,
401         poll=lambda self, obj: obj.type == 'CAMERA',
402     )
403     offscreen_dicing_scale: FloatProperty(
404         name="Offscreen Dicing Scale",
405         description="Multiplier for dicing rate of geometry outside of the camera view. The dicing rate "
406         "of objects is gradually increased the further they are outside the camera view. "
407         "Lower values provide higher quality reflections and shadows for off screen objects, "
408         "while higher values use less memory",
409         min=1.0, soft_max=25.0,
410         default=4.0,
411     )
412
413     film_exposure: FloatProperty(
414         name="Exposure",
415         description="Image brightness scale",
416         min=0.0, max=10.0,
417         default=1.0,
418     )
419     film_transparent: BoolProperty(
420         name="Transparent",
421         description="World background is transparent, for compositing the render over another background",
422         default=False,
423     )
424     film_transparent_glass: BoolProperty(
425         name="Transparent Glass",
426         description="Render transmissive surfaces as transparent, for compositing glass over another background",
427         default=False,
428     )
429     film_transparent_roughness: FloatProperty(
430         name="Transparent Roughness Threshold",
431         description="For transparent transmission, keep surfaces with roughness above the threshold opaque",
432         min=0.0, max=1.0,
433         default=0.1,
434     )
435
436     # Really annoyingly, we have to keep it around for a few releases,
437     # otherwise forward compatibility breaks in really bad manner: CRASH!
438     #
439     # TODO(sergey): Remove this during 2.8x series of Blender.
440     filter_type: EnumProperty(
441         name="Filter Type",
442         description="Pixel filter type",
443         items=enum_filter_types,
444         default='BLACKMAN_HARRIS',
445     )
446
447     pixel_filter_type: EnumProperty(
448         name="Filter Type",
449         description="Pixel filter type",
450         items=enum_filter_types,
451         default='BLACKMAN_HARRIS',
452     )
453
454     filter_width: FloatProperty(
455         name="Filter Width",
456         description="Pixel filter width",
457         min=0.01, max=10.0,
458         default=1.5,
459     )
460
461     seed: IntProperty(
462         name="Seed",
463         description="Seed value for integrator to get different noise patterns",
464         min=0, max=2147483647,
465         default=0,
466     )
467
468     use_animated_seed: BoolProperty(
469         name="Use Animated Seed",
470         description="Use different seed values (and hence noise patterns) at different frames",
471         default=False,
472     )
473
474     sample_clamp_direct: FloatProperty(
475         name="Clamp Direct",
476         description="If non-zero, the maximum value for a direct sample, "
477         "higher values will be scaled down to avoid too "
478         "much noise and slow convergence at the cost of accuracy",
479         min=0.0, max=1e8,
480         default=0.0,
481     )
482
483     sample_clamp_indirect: FloatProperty(
484         name="Clamp Indirect",
485         description="If non-zero, the maximum value for an indirect sample, "
486         "higher values will be scaled down to avoid too "
487         "much noise and slow convergence at the cost of accuracy",
488         min=0.0, max=1e8,
489         default=10.0,
490     )
491
492     debug_tile_size: IntProperty(
493         name="Tile Size",
494         description="",
495         min=1, max=4096,
496         default=1024,
497     )
498
499     preview_start_resolution: IntProperty(
500         name="Start Resolution",
501         description="Resolution to start rendering preview at, "
502         "progressively increasing it to the full viewport size",
503         min=8, max=16384,
504         default=64,
505     )
506
507     debug_reset_timeout: FloatProperty(
508         name="Reset timeout",
509         description="",
510         min=0.01, max=10.0,
511         default=0.1,
512     )
513     debug_cancel_timeout: FloatProperty(
514         name="Cancel timeout",
515         description="",
516         min=0.01, max=10.0,
517         default=0.1,
518     )
519     debug_text_timeout: FloatProperty(
520         name="Text timeout",
521         description="",
522         min=0.01, max=10.0,
523         default=1.0,
524     )
525
526     debug_bvh_type: EnumProperty(
527         name="Viewport BVH Type",
528         description="Choose between faster updates, or faster render",
529         items=enum_bvh_types,
530         default='DYNAMIC_BVH',
531     )
532     use_bvh_embree: BoolProperty(
533         name="Use Embree",
534         description="Use Embree as ray accelerator",
535         default=False,
536     )
537     debug_use_spatial_splits: BoolProperty(
538         name="Use Spatial Splits",
539         description="Use BVH spatial splits: longer builder time, faster render",
540         default=False,
541     )
542     debug_use_hair_bvh: BoolProperty(
543         name="Use Hair BVH",
544         description="Use special type BVH optimized for hair (uses more ram but renders faster)",
545         default=True,
546     )
547     debug_bvh_time_steps: IntProperty(
548         name="BVH Time Steps",
549         description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
550         default=0,
551         min=0, max=16,
552     )
553     tile_order: EnumProperty(
554         name="Tile Order",
555         description="Tile order for rendering",
556         items=enum_tile_order,
557         default='HILBERT_SPIRAL',
558         options=set(),  # Not animatable!
559     )
560     use_progressive_refine: BoolProperty(
561         name="Progressive Refine",
562         description="Instead of rendering each tile until it is finished, "
563         "refine the whole image progressively "
564         "(this renders somewhat slower, "
565         "but time can be saved by manually stopping the render when the noise is low enough)",
566         default=False,
567     )
568
569     bake_type: EnumProperty(
570         name="Bake Type",
571         default='COMBINED',
572         description="Type of pass to bake",
573         items=(
574             ('COMBINED', "Combined", ""),
575             ('AO', "Ambient Occlusion", ""),
576             ('SHADOW', "Shadow", ""),
577             ('NORMAL', "Normal", ""),
578             ('UV', "UV", ""),
579             ('ROUGHNESS', "Roughness", ""),
580             ('EMIT', "Emit", ""),
581             ('ENVIRONMENT', "Environment", ""),
582             ('DIFFUSE', "Diffuse", ""),
583             ('GLOSSY', "Glossy", ""),
584             ('TRANSMISSION', "Transmission", ""),
585             ('SUBSURFACE', "Subsurface", ""),
586         ),
587     )
588
589     use_camera_cull: BoolProperty(
590         name="Use Camera Cull",
591         description="Allow objects to be culled based on the camera frustum",
592         default=False,
593     )
594
595     camera_cull_margin: FloatProperty(
596         name="Camera Cull Margin",
597         description="Margin for the camera space culling",
598         default=0.1,
599         min=0.0, max=5.0
600     )
601
602     use_distance_cull: BoolProperty(
603         name="Use Distance Cull",
604         description="Allow objects to be culled based on the distance from camera",
605         default=False,
606     )
607
608     distance_cull_margin: FloatProperty(
609         name="Cull Distance",
610         description="Cull objects which are further away from camera than this distance",
611         default=50,
612         min=0.0
613     )
614
615     motion_blur_position: EnumProperty(
616         name="Motion Blur Position",
617         default='CENTER',
618         description="Offset for the shutter's time interval, allows to change the motion blur trails",
619         items=(
620             ('START', "Start on Frame", "The shutter opens at the current frame"),
621             ('CENTER', "Center on Frame", "The shutter is open during the current frame"),
622             ('END', "End on Frame", "The shutter closes at the current frame"),
623         ),
624     )
625
626     rolling_shutter_type: EnumProperty(
627         name="Shutter Type",
628         default='NONE',
629         description="Type of rolling shutter effect matching CMOS-based cameras",
630         items=(
631             ('NONE', "None", "No rolling shutter effect used"),
632             ('TOP', "Top-Bottom", "Sensor is being scanned from top to bottom")
633             # TODO(seergey): Are there real cameras with different scanning direction?
634         ),
635     )
636
637     rolling_shutter_duration: FloatProperty(
638         name="Rolling Shutter Duration",
639         description="Scanline \"exposure\" time for the rolling shutter effect",
640         default=0.1,
641         min=0.0, max=1.0,
642     )
643
644     texture_limit: EnumProperty(
645         name="Viewport Texture Limit",
646         default='OFF',
647         description="Limit texture size used by viewport rendering",
648         items=enum_texture_limit
649     )
650
651     texture_limit_render: EnumProperty(
652         name="Render Texture Limit",
653         default='OFF',
654         description="Limit texture size used by final rendering",
655         items=enum_texture_limit
656     )
657
658     ao_bounces: IntProperty(
659         name="AO Bounces",
660         default=0,
661         description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
662         min=0, max=1024,
663     )
664
665     ao_bounces_render: IntProperty(
666         name="AO Bounces Render",
667         default=0,
668         description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
669         min=0, max=1024,
670     )
671
672     # Various fine-tuning debug flags
673
674     def _devices_update_callback(self, context):
675         import _cycles
676         scene = context.scene.as_pointer()
677         return _cycles.debug_flags_update(scene)
678
679     debug_use_cpu_avx2: BoolProperty(name="AVX2", default=True)
680     debug_use_cpu_avx: BoolProperty(name="AVX", default=True)
681     debug_use_cpu_sse41: BoolProperty(name="SSE41", default=True)
682     debug_use_cpu_sse3: BoolProperty(name="SSE3", default=True)
683     debug_use_cpu_sse2: BoolProperty(name="SSE2", default=True)
684     debug_bvh_layout: EnumProperty(
685         name="BVH Layout",
686         items=enum_bvh_layouts,
687         default='BVH8',
688     )
689     debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False)
690
691     debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False)
692     debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
693
694     debug_opencl_kernel_type: EnumProperty(
695         name="OpenCL Kernel Type",
696         default='DEFAULT',
697         items=(
698             ('DEFAULT', "Default", ""),
699             ('MEGA', "Mega", ""),
700             ('SPLIT', "Split", ""),
701         ),
702         update=_devices_update_callback
703     )
704
705     debug_opencl_device_type: EnumProperty(
706         name="OpenCL Device Type",
707         default='ALL',
708         items=(
709             ('NONE', "None", ""),
710             ('ALL', "All", ""),
711             ('DEFAULT', "Default", ""),
712             ('CPU', "CPU", ""),
713             ('GPU', "GPU", ""),
714             ('ACCELERATOR', "Accelerator", ""),
715         ),
716         update=_devices_update_callback
717     )
718
719     debug_opencl_kernel_single_program: BoolProperty(
720         name="Single Program",
721         default=True,
722         update=_devices_update_callback,
723     )
724     del _devices_update_callback
725
726     debug_use_opencl_debug: BoolProperty(name="Debug OpenCL", default=False)
727
728     debug_opencl_mem_limit: IntProperty(
729         name="Memory limit",
730         default=0,
731         description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)"
732     )
733
734     @classmethod
735     def register(cls):
736         bpy.types.Scene.cycles = PointerProperty(
737             name="Cycles Render Settings",
738             description="Cycles render settings",
739             type=cls,
740         )
741
742     @classmethod
743     def unregister(cls):
744         del bpy.types.Scene.cycles
745
746
747 class CyclesCameraSettings(bpy.types.PropertyGroup):
748
749     aperture_type: EnumProperty(
750         name="Aperture Type",
751         description="Use f-stop number or aperture radius",
752         items=enum_aperture_types,
753         default='RADIUS',
754     )
755     aperture_fstop: FloatProperty(
756         name="Aperture f-stop",
757         description="F-stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
758         min=0.0, soft_min=0.1, soft_max=64.0,
759         default=5.6,
760         step=10,
761         precision=1,
762     )
763     aperture_size: FloatProperty(
764         name="Aperture Size",
765         description="Radius of the aperture for depth of field (higher values give more defocus)",
766         min=0.0, soft_max=10.0,
767         default=0.0,
768         step=1,
769         precision=4,
770         subtype='DISTANCE',
771     )
772     aperture_blades: IntProperty(
773         name="Aperture Blades",
774         description="Number of blades in aperture for polygonal bokeh (at least 3)",
775         min=0, max=100,
776         default=0,
777     )
778     aperture_rotation: FloatProperty(
779         name="Aperture Rotation",
780         description="Rotation of blades in aperture",
781         soft_min=-pi, soft_max=pi,
782         subtype='ANGLE',
783         default=0,
784     )
785     aperture_ratio: FloatProperty(
786         name="Aperture Ratio",
787         description="Distortion to simulate anamorphic lens bokeh",
788         min=0.01, soft_min=1.0, soft_max=2.0,
789         default=1.0,
790         precision=4,
791     )
792     panorama_type: EnumProperty(
793         name="Panorama Type",
794         description="Distortion to use for the calculation",
795         items=enum_panorama_types,
796         default='FISHEYE_EQUISOLID',
797     )
798     fisheye_fov: FloatProperty(
799         name="Field of View",
800         description="Field of view for the fisheye lens",
801         min=0.1745, soft_max=2.0 * pi, max=10.0 * pi,
802         subtype='ANGLE',
803         default=pi,
804     )
805     fisheye_lens: FloatProperty(
806         name="Fisheye Lens",
807         description="Lens focal length (mm)",
808         min=0.01, soft_max=15.0, max=100.0,
809         default=10.5,
810     )
811     latitude_min: FloatProperty(
812         name="Min Latitude",
813         description="Minimum latitude (vertical angle) for the equirectangular lens",
814         min=-0.5 * pi, max=0.5 * pi,
815         subtype='ANGLE',
816         default=-0.5 * pi,
817     )
818     latitude_max: FloatProperty(
819         name="Max Latitude",
820         description="Maximum latitude (vertical angle) for the equirectangular lens",
821         min=-0.5 * pi, max=0.5 * pi,
822         subtype='ANGLE',
823         default=0.5 * pi,
824     )
825     longitude_min: FloatProperty(
826         name="Min Longitude",
827         description="Minimum longitude (horizontal angle) for the equirectangular lens",
828         min=-pi, max=pi,
829         subtype='ANGLE',
830         default=-pi,
831     )
832     longitude_max: FloatProperty(
833         name="Max Longitude",
834         description="Maximum longitude (horizontal angle) for the equirectangular lens",
835         min=-pi, max=pi,
836         subtype='ANGLE',
837         default=pi,
838     )
839
840     @classmethod
841     def register(cls):
842         bpy.types.Camera.cycles = PointerProperty(
843             name="Cycles Camera Settings",
844             description="Cycles camera settings",
845             type=cls,
846         )
847
848     @classmethod
849     def unregister(cls):
850         del bpy.types.Camera.cycles
851
852
853 class CyclesMaterialSettings(bpy.types.PropertyGroup):
854
855     sample_as_light: BoolProperty(
856         name="Multiple Importance Sample",
857         description="Use multiple importance sampling for this material, "
858         "disabling may reduce overall noise for large "
859         "objects that emit little light compared to other light sources",
860         default=True,
861     )
862     use_transparent_shadow: BoolProperty(
863         name="Transparent Shadows",
864         description="Use transparent shadows for this material if it contains a Transparent BSDF, "
865         "disabling will render faster but not give accurate shadows",
866         default=True,
867     )
868     homogeneous_volume: BoolProperty(
869         name="Homogeneous Volume",
870         description="When using volume rendering, assume volume has the same density everywhere "
871         "(not using any textures), for faster rendering",
872         default=False,
873     )
874     volume_sampling: EnumProperty(
875         name="Volume Sampling",
876         description="Sampling method to use for volumes",
877         items=enum_volume_sampling,
878         default='MULTIPLE_IMPORTANCE',
879     )
880
881     volume_interpolation: EnumProperty(
882         name="Volume Interpolation",
883         description="Interpolation method to use for smoke/fire volumes",
884         items=enum_volume_interpolation,
885         default='LINEAR',
886     )
887
888     displacement_method: EnumProperty(
889         name="Displacement Method",
890         description="Method to use for the displacement",
891         items=enum_displacement_methods,
892         default='DISPLACEMENT',
893     )
894
895     @classmethod
896     def register(cls):
897         bpy.types.Material.cycles = PointerProperty(
898             name="Cycles Material Settings",
899             description="Cycles material settings",
900             type=cls,
901         )
902
903     @classmethod
904     def unregister(cls):
905         del bpy.types.Material.cycles
906
907
908 class CyclesLightSettings(bpy.types.PropertyGroup):
909
910     cast_shadow: BoolProperty(
911         name="Cast Shadow",
912         description="Light casts shadows",
913         default=True,
914     )
915     samples: IntProperty(
916         name="Samples",
917         description="Number of light samples to render for each AA sample",
918         min=1, max=10000,
919         default=1,
920     )
921     max_bounces: IntProperty(
922         name="Max Bounces",
923         description="Maximum number of bounces the light will contribute to the render",
924         min=0, max=1024,
925         default=1024,
926     )
927     use_multiple_importance_sampling: BoolProperty(
928         name="Multiple Importance Sample",
929         description="Use multiple importance sampling for the light, "
930         "reduces noise for area lights and sharp glossy materials",
931         default=True,
932     )
933     is_portal: BoolProperty(
934         name="Is Portal",
935         description="Use this area light to guide sampling of the background, "
936         "note that this will make the light invisible",
937         default=False,
938     )
939
940     @classmethod
941     def register(cls):
942         bpy.types.Light.cycles = PointerProperty(
943             name="Cycles Light Settings",
944             description="Cycles light settings",
945             type=cls,
946         )
947
948     @classmethod
949     def unregister(cls):
950         del bpy.types.Light.cycles
951
952
953 class CyclesWorldSettings(bpy.types.PropertyGroup):
954
955     sampling_method: EnumProperty(
956         name="Sampling method",
957         description="How to sample the background light",
958         items=enum_world_mis,
959         default='AUTOMATIC',
960     )
961     sample_map_resolution: IntProperty(
962         name="Map Resolution",
963         description="Importance map size is resolution x resolution/2; "
964         "higher values potentially produce less noise, at the cost of memory and speed",
965         min=4, max=8192,
966         default=1024,
967     )
968     samples: IntProperty(
969         name="Samples",
970         description="Number of light samples to render for each AA sample",
971         min=1, max=10000,
972         default=1,
973     )
974     max_bounces: IntProperty(
975         name="Max Bounces",
976         description="Maximum number of bounces the background light will contribute to the render",
977         min=0, max=1024,
978         default=1024,
979     )
980     homogeneous_volume: BoolProperty(
981         name="Homogeneous Volume",
982         description="When using volume rendering, assume volume has the same density everywhere"
983         "(not using any textures), for faster rendering",
984         default=False,
985     )
986     volume_sampling: EnumProperty(
987         name="Volume Sampling",
988         description="Sampling method to use for volumes",
989         items=enum_volume_sampling,
990         default='EQUIANGULAR',
991     )
992     volume_interpolation: EnumProperty(
993         name="Volume Interpolation",
994         description="Interpolation method to use for volumes",
995         items=enum_volume_interpolation,
996         default='LINEAR',
997     )
998
999     @classmethod
1000     def register(cls):
1001         bpy.types.World.cycles = PointerProperty(
1002             name="Cycles World Settings",
1003             description="Cycles world settings",
1004             type=cls,
1005         )
1006
1007     @classmethod
1008     def unregister(cls):
1009         del bpy.types.World.cycles
1010
1011
1012 class CyclesVisibilitySettings(bpy.types.PropertyGroup):
1013
1014     camera: BoolProperty(
1015         name="Camera",
1016         description="Object visibility for camera rays",
1017         default=True,
1018     )
1019     diffuse: BoolProperty(
1020         name="Diffuse",
1021         description="Object visibility for diffuse reflection rays",
1022         default=True,
1023     )
1024     glossy: BoolProperty(
1025         name="Glossy",
1026         description="Object visibility for glossy reflection rays",
1027         default=True,
1028     )
1029     transmission: BoolProperty(
1030         name="Transmission",
1031         description="Object visibility for transmission rays",
1032         default=True,
1033     )
1034     shadow: BoolProperty(
1035         name="Shadow",
1036         description="Object visibility for shadow rays",
1037         default=True,
1038     )
1039     scatter: BoolProperty(
1040         name="Volume Scatter",
1041         description="Object visibility for volume scatter rays",
1042         default=True,
1043     )
1044
1045     @classmethod
1046     def register(cls):
1047         bpy.types.Object.cycles_visibility = PointerProperty(
1048             name="Cycles Visibility Settings",
1049             description="Cycles visibility settings",
1050             type=cls,
1051         )
1052
1053         bpy.types.World.cycles_visibility = PointerProperty(
1054             name="Cycles Visibility Settings",
1055             description="Cycles visibility settings",
1056             type=cls,
1057         )
1058
1059     @classmethod
1060     def unregister(cls):
1061         del bpy.types.Object.cycles_visibility
1062         del bpy.types.World.cycles_visibility
1063
1064
1065 class CyclesMeshSettings(bpy.types.PropertyGroup):
1066     @classmethod
1067     def register(cls):
1068         bpy.types.Mesh.cycles = PointerProperty(
1069             name="Cycles Mesh Settings",
1070             description="Cycles mesh settings",
1071             type=cls,
1072         )
1073         bpy.types.Curve.cycles = PointerProperty(
1074             name="Cycles Mesh Settings",
1075             description="Cycles mesh settings",
1076             type=cls,
1077         )
1078         bpy.types.MetaBall.cycles = PointerProperty(
1079             name="Cycles Mesh Settings",
1080             description="Cycles mesh settings",
1081             type=cls,
1082         )
1083
1084     @classmethod
1085     def unregister(cls):
1086         del bpy.types.Mesh.cycles
1087         del bpy.types.Curve.cycles
1088         del bpy.types.MetaBall.cycles
1089
1090
1091 class CyclesObjectSettings(bpy.types.PropertyGroup):
1092
1093     use_motion_blur: BoolProperty(
1094         name="Use Motion Blur",
1095         description="Use motion blur for this object",
1096         default=True,
1097     )
1098
1099     use_deform_motion: BoolProperty(
1100         name="Use Deformation Motion",
1101         description="Use deformation motion blur for this object",
1102         default=True,
1103     )
1104
1105     motion_steps: IntProperty(
1106         name="Motion Steps",
1107         description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
1108         min=1, soft_max=8,
1109         default=1,
1110     )
1111
1112     use_camera_cull: BoolProperty(
1113         name="Use Camera Cull",
1114         description="Allow this object and its duplicators to be culled by camera space culling",
1115         default=False,
1116     )
1117
1118     use_distance_cull: BoolProperty(
1119         name="Use Distance Cull",
1120         description="Allow this object and its duplicators to be culled by distance from camera",
1121         default=False,
1122     )
1123
1124     use_adaptive_subdivision: BoolProperty(
1125         name="Use Adaptive Subdivision",
1126         description="Use adaptive render time subdivision",
1127         default=False,
1128     )
1129
1130     dicing_rate: FloatProperty(
1131         name="Dicing Scale",
1132         description="Multiplier for scene dicing rate (located in the Geometry Panel)",
1133         min=0.1, max=1000.0, soft_min=0.5,
1134         default=1.0,
1135     )
1136
1137     is_shadow_catcher: BoolProperty(
1138         name="Shadow Catcher",
1139         description="Only render shadows on this object, for compositing renders into real footage",
1140         default=False,
1141     )
1142
1143     is_holdout: BoolProperty(
1144         name="Holdout",
1145         description="Render objects as a holdout or matte, creating a "
1146         "hole in the image with zero alpha, to fill out in "
1147         "compositing with real footange or another render",
1148         default=False,
1149     )
1150
1151     @classmethod
1152     def register(cls):
1153         bpy.types.Object.cycles = PointerProperty(
1154             name="Cycles Object Settings",
1155             description="Cycles object settings",
1156             type=cls,
1157         )
1158
1159     @classmethod
1160     def unregister(cls):
1161         del bpy.types.Object.cycles
1162
1163
1164 class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
1165
1166     primitive: EnumProperty(
1167         name="Primitive",
1168         description="Type of primitive used for hair rendering",
1169         items=enum_curve_primitives,
1170         default='LINE_SEGMENTS',
1171     )
1172     shape: EnumProperty(
1173         name="Shape",
1174         description="Form of hair",
1175         items=enum_curve_shape,
1176         default='THICK',
1177     )
1178     cull_backfacing: BoolProperty(
1179         name="Cull Back-faces",
1180         description="Do not test the back-face of each strand",
1181         default=True,
1182     )
1183     use_curves: BoolProperty(
1184         name="Use Cycles Hair Rendering",
1185         description="Activate Cycles hair rendering for particle system",
1186         default=True,
1187     )
1188     resolution: IntProperty(
1189         name="Resolution",
1190         description="Resolution of generated mesh",
1191         min=3, max=64,
1192         default=3,
1193     )
1194     minimum_width: FloatProperty(
1195         name="Minimal width",
1196         description="Minimal pixel width for strands (0 - deactivated)",
1197         min=0.0, max=100.0,
1198         default=0.0,
1199     )
1200     maximum_width: FloatProperty(
1201         name="Maximal width",
1202         description="Maximum extension that strand radius can be increased by",
1203         min=0.0, max=100.0,
1204         default=0.1,
1205     )
1206     subdivisions: IntProperty(
1207         name="Subdivisions",
1208         description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
1209         min=0, max=24,
1210         default=4,
1211     )
1212
1213     @classmethod
1214     def register(cls):
1215         bpy.types.Scene.cycles_curves = PointerProperty(
1216             name="Cycles Hair Rendering Settings",
1217             description="Cycles hair rendering settings",
1218             type=cls,
1219         )
1220
1221     @classmethod
1222     def unregister(cls):
1223         del bpy.types.Scene.cycles_curves
1224
1225
1226 def update_render_passes(self, context):
1227     view_layer = context.view_layer
1228     view_layer.update_render_passes()
1229
1230
1231 class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
1232
1233     pass_debug_bvh_traversed_nodes: BoolProperty(
1234         name="Debug BVH Traversed Nodes",
1235         description="Store Debug BVH Traversed Nodes pass",
1236         default=False,
1237         update=update_render_passes,
1238     )
1239     pass_debug_bvh_traversed_instances: BoolProperty(
1240         name="Debug BVH Traversed Instances",
1241         description="Store Debug BVH Traversed Instances pass",
1242         default=False,
1243         update=update_render_passes,
1244     )
1245     pass_debug_bvh_intersections: BoolProperty(
1246         name="Debug BVH Intersections",
1247         description="Store Debug BVH Intersections",
1248         default=False,
1249         update=update_render_passes,
1250     )
1251     pass_debug_ray_bounces: BoolProperty(
1252         name="Debug Ray Bounces",
1253         description="Store Debug Ray Bounces pass",
1254         default=False,
1255         update=update_render_passes,
1256     )
1257     pass_debug_render_time: BoolProperty(
1258         name="Debug Render Time",
1259         description="Render time in milliseconds per sample and pixel",
1260         default=False,
1261         update=update_render_passes,
1262     )
1263     use_pass_volume_direct: BoolProperty(
1264         name="Volume Direct",
1265         description="Deliver direct volumetric scattering pass",
1266         default=False,
1267         update=update_render_passes,
1268     )
1269     use_pass_volume_indirect: BoolProperty(
1270         name="Volume Indirect",
1271         description="Deliver indirect volumetric scattering pass",
1272         default=False,
1273         update=update_render_passes,
1274     )
1275
1276     use_denoising: BoolProperty(
1277         name="Use Denoising",
1278         description="Denoise the rendered image",
1279         default=False,
1280         update=update_render_passes,
1281     )
1282     denoising_diffuse_direct: BoolProperty(
1283         name="Diffuse Direct",
1284         description="Denoise the direct diffuse lighting",
1285         default=True,
1286     )
1287     denoising_diffuse_indirect: BoolProperty(
1288         name="Diffuse Indirect",
1289         description="Denoise the indirect diffuse lighting",
1290         default=True,
1291     )
1292     denoising_glossy_direct: BoolProperty(
1293         name="Glossy Direct",
1294         description="Denoise the direct glossy lighting",
1295         default=True,
1296     )
1297     denoising_glossy_indirect: BoolProperty(
1298         name="Glossy Indirect",
1299         description="Denoise the indirect glossy lighting",
1300         default=True,
1301     )
1302     denoising_transmission_direct: BoolProperty(
1303         name="Transmission Direct",
1304         description="Denoise the direct transmission lighting",
1305         default=True,
1306     )
1307     denoising_transmission_indirect: BoolProperty(
1308         name="Transmission Indirect",
1309         description="Denoise the indirect transmission lighting",
1310         default=True,
1311     )
1312     denoising_subsurface_direct: BoolProperty(
1313         name="Subsurface Direct",
1314         description="Denoise the direct subsurface lighting",
1315         default=True,
1316     )
1317     denoising_subsurface_indirect: BoolProperty(
1318         name="Subsurface Indirect",
1319         description="Denoise the indirect subsurface lighting",
1320         default=True,
1321     )
1322     denoising_strength: FloatProperty(
1323         name="Denoising Strength",
1324         description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
1325         min=0.0, max=1.0,
1326         default=0.5,
1327     )
1328     denoising_feature_strength: FloatProperty(
1329         name="Denoising Feature Strength",
1330         description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
1331         min=0.0, max=1.0,
1332         default=0.5,
1333     )
1334     denoising_radius: IntProperty(
1335         name="Denoising Radius",
1336         description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
1337         min=1, max=25,
1338         default=8,
1339     )
1340     denoising_relative_pca: BoolProperty(
1341         name="Relative filter",
1342         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)",
1343         default=False,
1344     )
1345     denoising_store_passes: BoolProperty(
1346         name="Store denoising passes",
1347         description="Store the denoising feature passes and the noisy image",
1348         default=False,
1349         update=update_render_passes,
1350     )
1351     use_pass_crypto_object: BoolProperty(
1352         name="Cryptomatte Object",
1353         description="Render cryptomatte object pass, for isolating objects in compositing",
1354         default=False,
1355         update=update_render_passes,
1356         )
1357     use_pass_crypto_material: BoolProperty(
1358         name="Cryptomatte Material",
1359         description="Render cryptomatte material pass, for isolating materials in compositing",
1360         default=False,
1361         update=update_render_passes,
1362         )
1363     use_pass_crypto_asset: BoolProperty(
1364         name="Cryptomatte Asset",
1365         description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
1366         default=False,
1367         update=update_render_passes,
1368         )
1369     pass_crypto_depth: IntProperty(
1370         name="Cryptomatte Levels",
1371         description="Sets how many unique objects can be distinguished per pixel",
1372         default=6, min=2, max=16, step=2,
1373         update=update_render_passes,
1374         )
1375     pass_crypto_accurate: BoolProperty(
1376         name="Cryptomatte Accurate",
1377         description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
1378         default=True,
1379         update=update_render_passes,
1380         )
1381
1382     @classmethod
1383     def register(cls):
1384         bpy.types.ViewLayer.cycles = PointerProperty(
1385             name="Cycles ViewLayer Settings",
1386             description="Cycles ViewLayer Settings",
1387             type=cls,
1388         )
1389
1390     @classmethod
1391     def unregister(cls):
1392         del bpy.types.ViewLayer.cycles
1393
1394
1395 class CyclesDeviceSettings(bpy.types.PropertyGroup):
1396     id: StringProperty(name="ID")
1397     name: StringProperty(name="Name")
1398     use: BoolProperty(name="Use", default=True)
1399     type: EnumProperty(name="Type", items=enum_device_type, default='CUDA')
1400
1401
1402 class CyclesPreferences(bpy.types.AddonPreferences):
1403     bl_idname = __package__
1404
1405     def get_device_types(self, context):
1406         import _cycles
1407         has_cuda, has_opencl = _cycles.get_device_types()
1408         list = [('NONE', "None", "Don't use compute device", 0)]
1409         if has_cuda:
1410             list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
1411         if has_opencl:
1412             list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
1413         return list
1414
1415     compute_device_type: EnumProperty(
1416         name="Compute Device Type",
1417         description="Device to use for computation (rendering with Cycles)",
1418         items=get_device_types,
1419     )
1420
1421     devices: bpy.props.CollectionProperty(type=CyclesDeviceSettings)
1422
1423     def find_existing_device_entry(self, device):
1424         for device_entry in self.devices:
1425             if device_entry.id == device[2] and device_entry.type == device[1]:
1426                 return device_entry
1427         return None
1428
1429     def update_device_entries(self, device_list):
1430         for device in device_list:
1431             if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
1432                 continue
1433             # Try to find existing Device entry
1434             entry = self.find_existing_device_entry(device)
1435             if not entry:
1436                 # Create new entry if no existing one was found
1437                 entry = self.devices.add()
1438                 entry.id = device[2]
1439                 entry.name = device[0]
1440                 entry.type = device[1]
1441                 entry.use = entry.type != 'CPU'
1442             elif entry.name != device[0]:
1443                 # Update name in case it changed
1444                 entry.name = device[0]
1445
1446     def get_devices(self):
1447         import _cycles
1448         # Layout of the device tuples: (Name, Type, Persistent ID)
1449         device_list = _cycles.available_devices()
1450         # Make sure device entries are up to date and not referenced before
1451         # we know we don't add new devices. This way we guarantee to not
1452         # hold pointers to a resized array.
1453         self.update_device_entries(device_list)
1454         # Sort entries into lists
1455         cuda_devices = []
1456         opencl_devices = []
1457         cpu_devices = []
1458         for device in device_list:
1459             entry = self.find_existing_device_entry(device)
1460             if entry.type == 'CUDA':
1461                 cuda_devices.append(entry)
1462             elif entry.type == 'OPENCL':
1463                 opencl_devices.append(entry)
1464             elif entry.type == 'CPU':
1465                 cpu_devices.append(entry)
1466         # Extend all GPU devices with CPU.
1467         cuda_devices.extend(cpu_devices)
1468         opencl_devices.extend(cpu_devices)
1469         return cuda_devices, opencl_devices
1470
1471     def get_num_gpu_devices(self):
1472         import _cycles
1473         device_list = _cycles.available_devices()
1474         num = 0
1475         for device in device_list:
1476             if device[1] != self.compute_device_type:
1477                 continue
1478             for dev in self.devices:
1479                 if dev.use and dev.id == device[2]:
1480                     num += 1
1481         return num
1482
1483     def has_active_device(self):
1484         return self.get_num_gpu_devices() > 0
1485
1486     def draw_impl(self, layout, context):
1487         layout.label(text="Cycles Compute Device:")
1488         layout.row().prop(self, "compute_device_type", expand=True)
1489
1490         cuda_devices, opencl_devices = self.get_devices()
1491         row = layout.row()
1492
1493         if self.compute_device_type == 'CUDA' and cuda_devices:
1494             box = row.box()
1495             for device in cuda_devices:
1496                 box.prop(device, "use", text=device.name)
1497
1498         if self.compute_device_type == 'OPENCL' and opencl_devices:
1499             box = row.box()
1500             for device in opencl_devices:
1501                 box.prop(device, "use", text=device.name)
1502
1503     def draw(self, context):
1504         self.draw_impl(self.layout, context)
1505
1506
1507 def register():
1508     bpy.utils.register_class(CyclesRenderSettings)
1509     bpy.utils.register_class(CyclesCameraSettings)
1510     bpy.utils.register_class(CyclesMaterialSettings)
1511     bpy.utils.register_class(CyclesLightSettings)
1512     bpy.utils.register_class(CyclesWorldSettings)
1513     bpy.utils.register_class(CyclesVisibilitySettings)
1514     bpy.utils.register_class(CyclesMeshSettings)
1515     bpy.utils.register_class(CyclesObjectSettings)
1516     bpy.utils.register_class(CyclesCurveRenderSettings)
1517     bpy.utils.register_class(CyclesDeviceSettings)
1518     bpy.utils.register_class(CyclesPreferences)
1519     bpy.utils.register_class(CyclesRenderLayerSettings)
1520
1521
1522 def unregister():
1523     bpy.utils.unregister_class(CyclesRenderSettings)
1524     bpy.utils.unregister_class(CyclesCameraSettings)
1525     bpy.utils.unregister_class(CyclesMaterialSettings)
1526     bpy.utils.unregister_class(CyclesLightSettings)
1527     bpy.utils.unregister_class(CyclesWorldSettings)
1528     bpy.utils.unregister_class(CyclesMeshSettings)
1529     bpy.utils.unregister_class(CyclesObjectSettings)
1530     bpy.utils.unregister_class(CyclesVisibilitySettings)
1531     bpy.utils.unregister_class(CyclesCurveRenderSettings)
1532     bpy.utils.unregister_class(CyclesDeviceSettings)
1533     bpy.utils.unregister_class(CyclesPreferences)
1534     bpy.utils.unregister_class(CyclesRenderLayerSettings)