Merge branch 'blender2.7'
[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     minimum_width: FloatProperty(
1196         name="Minimal width",
1197         description="Minimal pixel width for strands (0 - deactivated)",
1198         min=0.0, max=100.0,
1199         default=0.0,
1200         subtype='PIXEL'
1201     )
1202     maximum_width: FloatProperty(
1203         name="Maximal width",
1204         description="Maximum extension that strand radius can be increased by",
1205         min=0.0, max=100.0,
1206         default=0.1,
1207         subtype='PIXEL'
1208     )
1209     subdivisions: IntProperty(
1210         name="Subdivisions",
1211         description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
1212         min=0, max=24,
1213         default=4,
1214     )
1215
1216     @classmethod
1217     def register(cls):
1218         bpy.types.Scene.cycles_curves = PointerProperty(
1219             name="Cycles Hair Rendering Settings",
1220             description="Cycles hair rendering settings",
1221             type=cls,
1222         )
1223
1224     @classmethod
1225     def unregister(cls):
1226         del bpy.types.Scene.cycles_curves
1227
1228
1229 def update_render_passes(self, context):
1230     view_layer = context.view_layer
1231     view_layer.update_render_passes()
1232
1233
1234 class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
1235
1236     pass_debug_bvh_traversed_nodes: BoolProperty(
1237         name="Debug BVH Traversed Nodes",
1238         description="Store Debug BVH Traversed Nodes pass",
1239         default=False,
1240         update=update_render_passes,
1241     )
1242     pass_debug_bvh_traversed_instances: BoolProperty(
1243         name="Debug BVH Traversed Instances",
1244         description="Store Debug BVH Traversed Instances pass",
1245         default=False,
1246         update=update_render_passes,
1247     )
1248     pass_debug_bvh_intersections: BoolProperty(
1249         name="Debug BVH Intersections",
1250         description="Store Debug BVH Intersections",
1251         default=False,
1252         update=update_render_passes,
1253     )
1254     pass_debug_ray_bounces: BoolProperty(
1255         name="Debug Ray Bounces",
1256         description="Store Debug Ray Bounces pass",
1257         default=False,
1258         update=update_render_passes,
1259     )
1260     pass_debug_render_time: BoolProperty(
1261         name="Debug Render Time",
1262         description="Render time in milliseconds per sample and pixel",
1263         default=False,
1264         update=update_render_passes,
1265     )
1266     use_pass_volume_direct: BoolProperty(
1267         name="Volume Direct",
1268         description="Deliver direct volumetric scattering pass",
1269         default=False,
1270         update=update_render_passes,
1271     )
1272     use_pass_volume_indirect: BoolProperty(
1273         name="Volume Indirect",
1274         description="Deliver indirect volumetric scattering pass",
1275         default=False,
1276         update=update_render_passes,
1277     )
1278
1279     use_denoising: BoolProperty(
1280         name="Use Denoising",
1281         description="Denoise the rendered image",
1282         default=False,
1283         update=update_render_passes,
1284     )
1285     denoising_diffuse_direct: BoolProperty(
1286         name="Diffuse Direct",
1287         description="Denoise the direct diffuse lighting",
1288         default=True,
1289     )
1290     denoising_diffuse_indirect: BoolProperty(
1291         name="Diffuse Indirect",
1292         description="Denoise the indirect diffuse lighting",
1293         default=True,
1294     )
1295     denoising_glossy_direct: BoolProperty(
1296         name="Glossy Direct",
1297         description="Denoise the direct glossy lighting",
1298         default=True,
1299     )
1300     denoising_glossy_indirect: BoolProperty(
1301         name="Glossy Indirect",
1302         description="Denoise the indirect glossy lighting",
1303         default=True,
1304     )
1305     denoising_transmission_direct: BoolProperty(
1306         name="Transmission Direct",
1307         description="Denoise the direct transmission lighting",
1308         default=True,
1309     )
1310     denoising_transmission_indirect: BoolProperty(
1311         name="Transmission Indirect",
1312         description="Denoise the indirect transmission lighting",
1313         default=True,
1314     )
1315     denoising_subsurface_direct: BoolProperty(
1316         name="Subsurface Direct",
1317         description="Denoise the direct subsurface lighting",
1318         default=True,
1319     )
1320     denoising_subsurface_indirect: BoolProperty(
1321         name="Subsurface Indirect",
1322         description="Denoise the indirect subsurface lighting",
1323         default=True,
1324     )
1325     denoising_strength: FloatProperty(
1326         name="Denoising Strength",
1327         description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
1328         min=0.0, max=1.0,
1329         default=0.5,
1330     )
1331     denoising_feature_strength: FloatProperty(
1332         name="Denoising Feature Strength",
1333         description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
1334         min=0.0, max=1.0,
1335         default=0.5,
1336     )
1337     denoising_radius: IntProperty(
1338         name="Denoising Radius",
1339         description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
1340         min=1, max=25,
1341         default=8,
1342         subtype="PIXEL",
1343     )
1344     denoising_relative_pca: BoolProperty(
1345         name="Relative filter",
1346         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)",
1347         default=False,
1348     )
1349     denoising_store_passes: BoolProperty(
1350         name="Store denoising passes",
1351         description="Store the denoising feature passes and the noisy image",
1352         default=False,
1353         update=update_render_passes,
1354     )
1355     denoising_neighbor_frames: IntProperty(
1356         name="Neighbor Frames",
1357         description="Number of neighboring frames to use for denoising animations (more frames produce smoother results at the cost of performance)",
1358         min=0, max=7,
1359         default=0,
1360     )
1361     use_pass_crypto_object: BoolProperty(
1362         name="Cryptomatte Object",
1363         description="Render cryptomatte object pass, for isolating objects in compositing",
1364         default=False,
1365         update=update_render_passes,
1366         )
1367     use_pass_crypto_material: BoolProperty(
1368         name="Cryptomatte Material",
1369         description="Render cryptomatte material pass, for isolating materials in compositing",
1370         default=False,
1371         update=update_render_passes,
1372         )
1373     use_pass_crypto_asset: BoolProperty(
1374         name="Cryptomatte Asset",
1375         description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
1376         default=False,
1377         update=update_render_passes,
1378         )
1379     pass_crypto_depth: IntProperty(
1380         name="Cryptomatte Levels",
1381         description="Sets how many unique objects can be distinguished per pixel",
1382         default=6, min=2, max=16, step=2,
1383         update=update_render_passes,
1384         )
1385     pass_crypto_accurate: BoolProperty(
1386         name="Cryptomatte Accurate",
1387         description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
1388         default=True,
1389         update=update_render_passes,
1390         )
1391
1392     @classmethod
1393     def register(cls):
1394         bpy.types.ViewLayer.cycles = PointerProperty(
1395             name="Cycles ViewLayer Settings",
1396             description="Cycles ViewLayer Settings",
1397             type=cls,
1398         )
1399
1400     @classmethod
1401     def unregister(cls):
1402         del bpy.types.ViewLayer.cycles
1403
1404
1405 class CyclesDeviceSettings(bpy.types.PropertyGroup):
1406     id: StringProperty(name="ID")
1407     name: StringProperty(name="Name")
1408     use: BoolProperty(name="Use", default=True)
1409     type: EnumProperty(name="Type", items=enum_device_type, default='CUDA')
1410
1411
1412 class CyclesPreferences(bpy.types.AddonPreferences):
1413     bl_idname = __package__
1414
1415     def get_device_types(self, context):
1416         import _cycles
1417         has_cuda, has_opencl = _cycles.get_device_types()
1418         list = [('NONE', "None", "Don't use compute device", 0)]
1419         if has_cuda:
1420             list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
1421         if has_opencl:
1422             list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
1423         return list
1424
1425     compute_device_type: EnumProperty(
1426         name="Compute Device Type",
1427         description="Device to use for computation (rendering with Cycles)",
1428         items=get_device_types,
1429     )
1430
1431     devices: bpy.props.CollectionProperty(type=CyclesDeviceSettings)
1432
1433     def find_existing_device_entry(self, device):
1434         for device_entry in self.devices:
1435             if device_entry.id == device[2] and device_entry.type == device[1]:
1436                 return device_entry
1437         return None
1438
1439     def update_device_entries(self, device_list):
1440         for device in device_list:
1441             if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
1442                 continue
1443             # Try to find existing Device entry
1444             entry = self.find_existing_device_entry(device)
1445             if not entry:
1446                 # Create new entry if no existing one was found
1447                 entry = self.devices.add()
1448                 entry.id = device[2]
1449                 entry.name = device[0]
1450                 entry.type = device[1]
1451                 entry.use = entry.type != 'CPU'
1452             elif entry.name != device[0]:
1453                 # Update name in case it changed
1454                 entry.name = device[0]
1455
1456     def get_devices(self):
1457         import _cycles
1458         # Layout of the device tuples: (Name, Type, Persistent ID)
1459         device_list = _cycles.available_devices(self.compute_device_type)
1460         # Make sure device entries are up to date and not referenced before
1461         # we know we don't add new devices. This way we guarantee to not
1462         # hold pointers to a resized array.
1463         self.update_device_entries(device_list)
1464         # Sort entries into lists
1465         cuda_devices = []
1466         opencl_devices = []
1467         cpu_devices = []
1468         for device in device_list:
1469             entry = self.find_existing_device_entry(device)
1470             if entry.type == 'CUDA':
1471                 cuda_devices.append(entry)
1472             elif entry.type == 'OPENCL':
1473                 opencl_devices.append(entry)
1474             elif entry.type == 'CPU':
1475                 cpu_devices.append(entry)
1476         # Extend all GPU devices with CPU.
1477         cuda_devices.extend(cpu_devices)
1478         opencl_devices.extend(cpu_devices)
1479         return cuda_devices, opencl_devices
1480
1481     def get_num_gpu_devices(self):
1482         import _cycles
1483         device_list = _cycles.available_devices(self.compute_device_type)
1484         num = 0
1485         for device in device_list:
1486             if device[1] != self.compute_device_type:
1487                 continue
1488             for dev in self.devices:
1489                 if dev.use and dev.id == device[2]:
1490                     num += 1
1491         return num
1492
1493     def has_active_device(self):
1494         return self.get_num_gpu_devices() > 0
1495
1496     def _draw_devices(self, layout, device_type, devices):
1497         box = layout.box()
1498
1499         found_device = False
1500         for device in devices:
1501             if device.type == device_type:
1502                 found_device = True
1503                 break
1504
1505         if not found_device:
1506             box.label(text="No compatible GPUs found", icon='INFO')
1507             return
1508
1509         for device in devices:
1510             box.prop(device, "use", text=device.name)
1511
1512     def draw_impl(self, layout, context):
1513         row = layout.row()
1514         row.prop(self, "compute_device_type", expand=True)
1515
1516         cuda_devices, opencl_devices = self.get_devices()
1517         row = layout.row()
1518         if self.compute_device_type == 'CUDA':
1519             self._draw_devices(row, 'CUDA', cuda_devices)
1520         elif self.compute_device_type == 'OPENCL':
1521             self._draw_devices(row, 'OPENCL', opencl_devices)
1522
1523     def draw(self, context):
1524         self.draw_impl(self.layout, context)
1525
1526
1527 def register():
1528     bpy.utils.register_class(CyclesRenderSettings)
1529     bpy.utils.register_class(CyclesCameraSettings)
1530     bpy.utils.register_class(CyclesMaterialSettings)
1531     bpy.utils.register_class(CyclesLightSettings)
1532     bpy.utils.register_class(CyclesWorldSettings)
1533     bpy.utils.register_class(CyclesVisibilitySettings)
1534     bpy.utils.register_class(CyclesMeshSettings)
1535     bpy.utils.register_class(CyclesObjectSettings)
1536     bpy.utils.register_class(CyclesCurveRenderSettings)
1537     bpy.utils.register_class(CyclesDeviceSettings)
1538     bpy.utils.register_class(CyclesPreferences)
1539     bpy.utils.register_class(CyclesRenderLayerSettings)
1540
1541
1542 def unregister():
1543     bpy.utils.unregister_class(CyclesRenderSettings)
1544     bpy.utils.unregister_class(CyclesCameraSettings)
1545     bpy.utils.unregister_class(CyclesMaterialSettings)
1546     bpy.utils.unregister_class(CyclesLightSettings)
1547     bpy.utils.unregister_class(CyclesWorldSettings)
1548     bpy.utils.unregister_class(CyclesMeshSettings)
1549     bpy.utils.unregister_class(CyclesObjectSettings)
1550     bpy.utils.unregister_class(CyclesVisibilitySettings)
1551     bpy.utils.unregister_class(CyclesCurveRenderSettings)
1552     bpy.utils.unregister_class(CyclesDeviceSettings)
1553     bpy.utils.unregister_class(CyclesPreferences)
1554     bpy.utils.unregister_class(CyclesRenderLayerSettings)