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