Revert "Cycles: Change OpenCL split kernel to use single program by default"
[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.use_bvh_embree = BoolProperty(
551             name="Use Embree",
552             description="Use Embree as ray accelerator",
553             default=False,
554         )
555         cls.debug_bvh_time_steps = IntProperty(
556             name="BVH Time Steps",
557             description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
558             default=0,
559             min=0, max=16,
560         )
561         cls.tile_order = EnumProperty(
562             name="Tile Order",
563             description="Tile order for rendering",
564             items=enum_tile_order,
565             default='HILBERT_SPIRAL',
566             options=set(),  # Not animatable!
567         )
568         cls.use_progressive_refine = BoolProperty(
569             name="Progressive Refine",
570             description="Instead of rendering each tile until it is finished, "
571             "refine the whole image progressively "
572             "(this renders somewhat slower, "
573             "but time can be saved by manually stopping the render when the noise is low enough)",
574             default=False,
575         )
576
577         cls.bake_type = EnumProperty(
578             name="Bake Type",
579             default='COMBINED',
580             description="Type of pass to bake",
581             items=(
582                 ('COMBINED', "Combined", ""),
583                 ('AO', "Ambient Occlusion", ""),
584                 ('SHADOW', "Shadow", ""),
585                 ('NORMAL', "Normal", ""),
586                 ('UV', "UV", ""),
587                 ('ROUGHNESS', "Roughness", ""),
588                 ('EMIT', "Emit", ""),
589                 ('ENVIRONMENT', "Environment", ""),
590                 ('DIFFUSE', "Diffuse", ""),
591                 ('GLOSSY', "Glossy", ""),
592                 ('TRANSMISSION', "Transmission", ""),
593                 ('SUBSURFACE', "Subsurface", ""),
594             ),
595         )
596
597         cls.use_camera_cull = BoolProperty(
598             name="Use Camera Cull",
599             description="Allow objects to be culled based on the camera frustum",
600             default=False,
601         )
602
603         cls.camera_cull_margin = FloatProperty(
604             name="Camera Cull Margin",
605             description="Margin for the camera space culling",
606             default=0.1,
607             min=0.0, max=5.0
608         )
609
610         cls.use_distance_cull = BoolProperty(
611             name="Use Distance Cull",
612             description="Allow objects to be culled based on the distance from camera",
613             default=False,
614         )
615
616         cls.distance_cull_margin = FloatProperty(
617             name="Cull Distance",
618             description="Cull objects which are further away from camera than this distance",
619             default=50,
620             min=0.0
621         )
622
623         cls.motion_blur_position = EnumProperty(
624             name="Motion Blur Position",
625             default='CENTER',
626             description="Offset for the shutter's time interval, allows to change the motion blur trails",
627             items=(
628                 ('START', "Start on Frame", "The shutter opens at the current frame"),
629                 ('CENTER', "Center on Frame", "The shutter is open during the current frame"),
630                 ('END', "End on Frame", "The shutter closes at the current frame"),
631             ),
632         )
633
634         cls.rolling_shutter_type = EnumProperty(
635             name="Shutter Type",
636             default='NONE',
637             description="Type of rolling shutter effect matching CMOS-based cameras",
638             items=(
639                 ('NONE', "None", "No rolling shutter effect used"),
640                 ('TOP', "Top-Bottom", "Sensor is being scanned from top to bottom")
641                 # TODO(seergey): Are there real cameras with different scanning direction?
642             ),
643         )
644
645         cls.rolling_shutter_duration = FloatProperty(
646             name="Rolling Shutter Duration",
647             description="Scanline \"exposure\" time for the rolling shutter effect",
648             default=0.1,
649             min=0.0, max=1.0,
650         )
651
652         cls.texture_limit = EnumProperty(
653             name="Viewport Texture Limit",
654             default='OFF',
655             description="Limit texture size used by viewport rendering",
656             items=enum_texture_limit
657         )
658
659         cls.texture_limit_render = EnumProperty(
660             name="Render Texture Limit",
661             default='OFF',
662             description="Limit texture size used by final rendering",
663             items=enum_texture_limit
664         )
665
666         cls.ao_bounces = IntProperty(
667             name="AO Bounces",
668             default=0,
669             description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
670             min=0, max=1024,
671         )
672
673         cls.ao_bounces_render = IntProperty(
674             name="AO Bounces Render",
675             default=0,
676             description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
677             min=0, max=1024,
678         )
679
680         # Various fine-tuning debug flags
681
682         def devices_update_callback(self, context):
683             import _cycles
684             scene = context.scene.as_pointer()
685             return _cycles.debug_flags_update(scene)
686
687         cls.debug_use_cpu_avx2 = BoolProperty(name="AVX2", default=True)
688         cls.debug_use_cpu_avx = BoolProperty(name="AVX", default=True)
689         cls.debug_use_cpu_sse41 = BoolProperty(name="SSE41", default=True)
690         cls.debug_use_cpu_sse3 = BoolProperty(name="SSE3", default=True)
691         cls.debug_use_cpu_sse2 = BoolProperty(name="SSE2", default=True)
692         cls.debug_bvh_layout = EnumProperty(
693             name="BVH Layout",
694             items=enum_bvh_layouts,
695             default='BVH8',
696         )
697         cls.debug_use_cpu_split_kernel = BoolProperty(name="Split Kernel", default=False)
698
699         cls.debug_use_cuda_adaptive_compile = BoolProperty(name="Adaptive Compile", default=False)
700         cls.debug_use_cuda_split_kernel = BoolProperty(name="Split Kernel", default=False)
701
702         cls.debug_opencl_kernel_type = EnumProperty(
703             name="OpenCL Kernel Type",
704             default='DEFAULT',
705             items=(
706                 ('DEFAULT', "Default", ""),
707                 ('MEGA', "Mega", ""),
708                 ('SPLIT', "Split", ""),
709             ),
710             update=devices_update_callback
711         )
712
713         cls.debug_opencl_device_type = EnumProperty(
714             name="OpenCL Device Type",
715             default='ALL',
716             items=(
717                 ('NONE', "None", ""),
718                 ('ALL', "All", ""),
719                 ('DEFAULT', "Default", ""),
720                 ('CPU', "CPU", ""),
721                 ('GPU', "GPU", ""),
722                 ('ACCELERATOR', "Accelerator", ""),
723             ),
724             update=devices_update_callback
725         )
726
727         cls.debug_opencl_kernel_single_program = BoolProperty(
728             name="Single Program",
729             default=False,
730             update=devices_update_callback,
731         )
732
733         cls.debug_use_opencl_debug = BoolProperty(name="Debug OpenCL", default=False)
734
735         cls.debug_opencl_mem_limit = IntProperty(name="Memory limit", default=0,
736                                                  description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)")
737
738     @classmethod
739     def unregister(cls):
740         del bpy.types.Scene.cycles
741
742
743 class CyclesCameraSettings(bpy.types.PropertyGroup):
744     @classmethod
745     def register(cls):
746         import math
747
748         bpy.types.Camera.cycles = PointerProperty(
749             name="Cycles Camera Settings",
750             description="Cycles camera settings",
751             type=cls,
752         )
753
754         cls.aperture_type = EnumProperty(
755             name="Aperture Type",
756             description="Use f-stop number or aperture radius",
757             items=enum_aperture_types,
758             default='RADIUS',
759         )
760         cls.aperture_fstop = FloatProperty(
761             name="Aperture f-stop",
762             description="F-stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
763             min=0.0, soft_min=0.1, soft_max=64.0,
764             default=5.6,
765             step=10,
766             precision=1,
767         )
768         cls.aperture_size = FloatProperty(
769             name="Aperture Size",
770             description="Radius of the aperture for depth of field (higher values give more defocus)",
771             min=0.0, soft_max=10.0,
772             default=0.0,
773             step=1,
774             precision=4,
775             subtype='DISTANCE',
776         )
777         cls.aperture_blades = IntProperty(
778             name="Aperture Blades",
779             description="Number of blades in aperture for polygonal bokeh (at least 3)",
780             min=0, max=100,
781             default=0,
782         )
783         cls.aperture_rotation = FloatProperty(
784             name="Aperture Rotation",
785             description="Rotation of blades in aperture",
786             soft_min=-math.pi, soft_max=math.pi,
787             subtype='ANGLE',
788             default=0,
789         )
790         cls.aperture_ratio = FloatProperty(
791             name="Aperture Ratio",
792             description="Distortion to simulate anamorphic lens bokeh",
793             min=0.01, soft_min=1.0, soft_max=2.0,
794             default=1.0,
795             precision=4,
796         )
797         cls.panorama_type = EnumProperty(
798             name="Panorama Type",
799             description="Distortion to use for the calculation",
800             items=enum_panorama_types,
801             default='FISHEYE_EQUISOLID',
802         )
803         cls.fisheye_fov = FloatProperty(
804             name="Field of View",
805             description="Field of view for the fisheye lens",
806             min=0.1745, soft_max=2.0 * math.pi, max=10.0 * math.pi,
807             subtype='ANGLE',
808             default=math.pi,
809         )
810         cls.fisheye_lens = FloatProperty(
811             name="Fisheye Lens",
812             description="Lens focal length (mm)",
813             min=0.01, soft_max=15.0, max=100.0,
814             default=10.5,
815         )
816         cls.latitude_min = FloatProperty(
817             name="Min Latitude",
818             description="Minimum latitude (vertical angle) for the equirectangular lens",
819             min=-0.5 * math.pi, max=0.5 * math.pi,
820             subtype='ANGLE',
821             default=-0.5 * math.pi,
822         )
823         cls.latitude_max = FloatProperty(
824             name="Max Latitude",
825             description="Maximum latitude (vertical angle) for the equirectangular lens",
826             min=-0.5 * math.pi, max=0.5 * math.pi,
827             subtype='ANGLE',
828             default=0.5 * math.pi,
829         )
830         cls.longitude_min = FloatProperty(
831             name="Min Longitude",
832             description="Minimum longitude (horizontal angle) for the equirectangular lens",
833             min=-math.pi, max=math.pi,
834             subtype='ANGLE',
835             default=-math.pi,
836         )
837         cls.longitude_max = FloatProperty(
838             name="Max Longitude",
839             description="Maximum longitude (horizontal angle) for the equirectangular lens",
840             min=-math.pi, max=math.pi,
841             subtype='ANGLE',
842             default=math.pi,
843         )
844
845     @classmethod
846     def unregister(cls):
847         del bpy.types.Camera.cycles
848
849
850 class CyclesMaterialSettings(bpy.types.PropertyGroup):
851     @classmethod
852     def register(cls):
853         bpy.types.Material.cycles = PointerProperty(
854             name="Cycles Material Settings",
855             description="Cycles material settings",
856             type=cls,
857         )
858         cls.sample_as_light = BoolProperty(
859             name="Multiple Importance Sample",
860             description="Use multiple importance sampling for this material, "
861             "disabling may reduce overall noise for large "
862             "objects that emit little light compared to other light sources",
863             default=True,
864         )
865         cls.use_transparent_shadow = BoolProperty(
866             name="Transparent Shadows",
867             description="Use transparent shadows for this material if it contains a Transparent BSDF, "
868             "disabling will render faster but not give accurate shadows",
869             default=True,
870         )
871         cls.homogeneous_volume = BoolProperty(
872             name="Homogeneous Volume",
873             description="When using volume rendering, assume volume has the same density everywhere "
874             "(not using any textures), for faster rendering",
875             default=False,
876         )
877         cls.volume_sampling = EnumProperty(
878             name="Volume Sampling",
879             description="Sampling method to use for volumes",
880             items=enum_volume_sampling,
881             default='MULTIPLE_IMPORTANCE',
882         )
883
884         cls.volume_interpolation = EnumProperty(
885             name="Volume Interpolation",
886             description="Interpolation method to use for smoke/fire volumes",
887             items=enum_volume_interpolation,
888             default='LINEAR',
889         )
890
891         cls.displacement_method = EnumProperty(
892             name="Displacement Method",
893             description="Method to use for the displacement",
894             items=enum_displacement_methods,
895             default='BUMP',
896         )
897
898     @classmethod
899     def unregister(cls):
900         del bpy.types.Material.cycles
901
902
903 class CyclesLampSettings(bpy.types.PropertyGroup):
904     @classmethod
905     def register(cls):
906         bpy.types.Lamp.cycles = PointerProperty(
907             name="Cycles Lamp Settings",
908             description="Cycles lamp settings",
909             type=cls,
910         )
911         cls.cast_shadow = BoolProperty(
912             name="Cast Shadow",
913             description="Lamp casts shadows",
914             default=True,
915         )
916         cls.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         cls.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         cls.use_multiple_importance_sampling = BoolProperty(
929             name="Multiple Importance Sample",
930             description="Use multiple importance sampling for the lamp, "
931             "reduces noise for area lamps and sharp glossy materials",
932             default=True,
933         )
934         cls.is_portal = BoolProperty(
935             name="Is Portal",
936             description="Use this area lamp to guide sampling of the background, "
937             "note that this will make the lamp invisible",
938             default=False,
939         )
940
941     @classmethod
942     def unregister(cls):
943         del bpy.types.Lamp.cycles
944
945
946 class CyclesWorldSettings(bpy.types.PropertyGroup):
947     @classmethod
948     def register(cls):
949         bpy.types.World.cycles = PointerProperty(
950             name="Cycles World Settings",
951             description="Cycles world settings",
952             type=cls,
953         )
954         cls.sampling_method = EnumProperty(
955             name="Sampling method",
956             description="How to sample the background light",
957             items=enum_world_mis,
958             default='AUTOMATIC',
959         )
960         cls.sample_map_resolution = IntProperty(
961             name="Map Resolution",
962             description="Importance map size is resolution x resolution/2; "
963             "higher values potentially produce less noise, at the cost of memory and speed",
964             min=4, max=8192,
965             default=1024,
966         )
967         cls.samples = IntProperty(
968             name="Samples",
969             description="Number of light samples to render for each AA sample",
970             min=1, max=10000,
971             default=1,
972         )
973         cls.max_bounces = IntProperty(
974             name="Max Bounces",
975             description="Maximum number of bounces the background light will contribute to the render",
976             min=0, max=1024,
977             default=1024,
978         )
979         cls.homogeneous_volume = BoolProperty(
980             name="Homogeneous Volume",
981             description="When using volume rendering, assume volume has the same density everywhere"
982             "(not using any textures), for faster rendering",
983             default=False,
984         )
985         cls.volume_sampling = EnumProperty(
986             name="Volume Sampling",
987             description="Sampling method to use for volumes",
988             items=enum_volume_sampling,
989             default='EQUIANGULAR',
990         )
991
992         cls.volume_interpolation = EnumProperty(
993             name="Volume Interpolation",
994             description="Interpolation method to use for volumes",
995             items=enum_volume_interpolation,
996             default='LINEAR',
997         )
998
999     @classmethod
1000     def unregister(cls):
1001         del bpy.types.World.cycles
1002
1003
1004 class CyclesVisibilitySettings(bpy.types.PropertyGroup):
1005     @classmethod
1006     def register(cls):
1007         bpy.types.Object.cycles_visibility = PointerProperty(
1008             name="Cycles Visibility Settings",
1009             description="Cycles visibility settings",
1010             type=cls,
1011         )
1012
1013         bpy.types.World.cycles_visibility = PointerProperty(
1014             name="Cycles Visibility Settings",
1015             description="Cycles visibility settings",
1016             type=cls,
1017         )
1018
1019         cls.camera = BoolProperty(
1020             name="Camera",
1021             description="Object visibility for camera rays",
1022             default=True,
1023         )
1024         cls.diffuse = BoolProperty(
1025             name="Diffuse",
1026             description="Object visibility for diffuse reflection rays",
1027             default=True,
1028         )
1029         cls.glossy = BoolProperty(
1030             name="Glossy",
1031             description="Object visibility for glossy reflection rays",
1032             default=True,
1033         )
1034         cls.transmission = BoolProperty(
1035             name="Transmission",
1036             description="Object visibility for transmission rays",
1037             default=True,
1038         )
1039         cls.shadow = BoolProperty(
1040             name="Shadow",
1041             description="Object visibility for shadow rays",
1042             default=True,
1043         )
1044         cls.scatter = BoolProperty(
1045             name="Volume Scatter",
1046             description="Object visibility for volume scatter rays",
1047             default=True,
1048         )
1049
1050     @classmethod
1051     def unregister(cls):
1052         del bpy.types.Object.cycles_visibility
1053         del bpy.types.World.cycles_visibility
1054
1055
1056 class CyclesMeshSettings(bpy.types.PropertyGroup):
1057     @classmethod
1058     def register(cls):
1059         bpy.types.Mesh.cycles = PointerProperty(
1060             name="Cycles Mesh Settings",
1061             description="Cycles mesh settings",
1062             type=cls,
1063         )
1064         bpy.types.Curve.cycles = PointerProperty(
1065             name="Cycles Mesh Settings",
1066             description="Cycles mesh settings",
1067             type=cls,
1068         )
1069         bpy.types.MetaBall.cycles = PointerProperty(
1070             name="Cycles Mesh Settings",
1071             description="Cycles mesh settings",
1072             type=cls,
1073         )
1074
1075     @classmethod
1076     def unregister(cls):
1077         del bpy.types.Mesh.cycles
1078         del bpy.types.Curve.cycles
1079         del bpy.types.MetaBall.cycles
1080
1081
1082 class CyclesObjectSettings(bpy.types.PropertyGroup):
1083     @classmethod
1084     def register(cls):
1085         bpy.types.Object.cycles = PointerProperty(
1086             name="Cycles Object Settings",
1087             description="Cycles object settings",
1088             type=cls,
1089         )
1090
1091         cls.use_motion_blur = BoolProperty(
1092             name="Use Motion Blur",
1093             description="Use motion blur for this object",
1094             default=True,
1095         )
1096
1097         cls.use_deform_motion = BoolProperty(
1098             name="Use Deformation Motion",
1099             description="Use deformation motion blur for this object",
1100             default=True,
1101         )
1102
1103         cls.motion_steps = IntProperty(
1104             name="Motion Steps",
1105             description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
1106             min=1, soft_max=8,
1107             default=1,
1108         )
1109
1110         cls.use_camera_cull = BoolProperty(
1111             name="Use Camera Cull",
1112             description="Allow this object and its duplicators to be culled by camera space culling",
1113             default=False,
1114         )
1115
1116         cls.use_distance_cull = BoolProperty(
1117             name="Use Distance Cull",
1118             description="Allow this object and its duplicators to be culled by distance from camera",
1119             default=False,
1120         )
1121
1122         cls.use_adaptive_subdivision = BoolProperty(
1123             name="Use Adaptive Subdivision",
1124             description="Use adaptive render time subdivision",
1125             default=False,
1126         )
1127
1128         cls.dicing_rate = FloatProperty(
1129             name="Dicing Scale",
1130             description="Multiplier for scene dicing rate (located in the Geometry Panel)",
1131             min=0.1, max=1000.0, soft_min=0.5,
1132             default=1.0,
1133         )
1134
1135         cls.is_shadow_catcher = BoolProperty(
1136             name="Shadow Catcher",
1137             description="Only render shadows on this object, for compositing renders into real footage",
1138             default=False,
1139         )
1140
1141         cls.is_holdout = BoolProperty(
1142             name="Holdout",
1143             description="Render objects as a holdout or matte, creating a "
1144             "hole in the image with zero alpha, to fill out in "
1145             "compositing with real footange or another render",
1146             default=False,
1147         )
1148
1149     @classmethod
1150     def unregister(cls):
1151         del bpy.types.Object.cycles
1152
1153
1154 class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
1155     @classmethod
1156     def register(cls):
1157         bpy.types.Scene.cycles_curves = PointerProperty(
1158             name="Cycles Hair Rendering Settings",
1159             description="Cycles hair rendering settings",
1160             type=cls,
1161         )
1162         cls.primitive = EnumProperty(
1163             name="Primitive",
1164             description="Type of primitive used for hair rendering",
1165             items=enum_curve_primitives,
1166             default='LINE_SEGMENTS',
1167         )
1168         cls.shape = EnumProperty(
1169             name="Shape",
1170             description="Form of hair",
1171             items=enum_curve_shape,
1172             default='THICK',
1173         )
1174         cls.cull_backfacing = BoolProperty(
1175             name="Cull back-faces",
1176             description="Do not test the back-face of each strand",
1177             default=True,
1178         )
1179         cls.use_curves = BoolProperty(
1180             name="Use Cycles Hair Rendering",
1181             description="Activate Cycles hair rendering for particle system",
1182             default=True,
1183         )
1184         cls.resolution = IntProperty(
1185             name="Resolution",
1186             description="Resolution of generated mesh",
1187             min=3, max=64,
1188             default=3,
1189         )
1190         cls.minimum_width = FloatProperty(
1191             name="Minimal width",
1192             description="Minimal pixel width for strands (0 - deactivated)",
1193             min=0.0, max=100.0,
1194             default=0.0,
1195         )
1196         cls.maximum_width = FloatProperty(
1197             name="Maximal width",
1198             description="Maximum extension that strand radius can be increased by",
1199             min=0.0, max=100.0,
1200             default=0.1,
1201         )
1202         cls.subdivisions = IntProperty(
1203             name="Subdivisions",
1204             description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
1205             min=0, max=24,
1206             default=4,
1207         )
1208
1209     @classmethod
1210     def unregister(cls):
1211         del bpy.types.Scene.cycles_curves
1212
1213
1214 def update_render_passes(self, context):
1215     scene = context.scene
1216     rd = scene.render
1217     rl = rd.layers.active
1218     rl.update_render_passes()
1219
1220
1221 class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
1222     @classmethod
1223     def register(cls):
1224         bpy.types.SceneRenderLayer.cycles = PointerProperty(
1225             name="Cycles SceneRenderLayer Settings",
1226             description="Cycles SceneRenderLayer Settings",
1227             type=cls,
1228         )
1229         cls.pass_debug_bvh_traversed_nodes = BoolProperty(
1230             name="Debug BVH Traversed Nodes",
1231             description="Store Debug BVH Traversed Nodes pass",
1232             default=False,
1233             update=update_render_passes,
1234         )
1235         cls.pass_debug_bvh_traversed_instances = BoolProperty(
1236             name="Debug BVH Traversed Instances",
1237             description="Store Debug BVH Traversed Instances pass",
1238             default=False,
1239             update=update_render_passes,
1240         )
1241         cls.pass_debug_bvh_intersections = BoolProperty(
1242             name="Debug BVH Intersections",
1243             description="Store Debug BVH Intersections",
1244             default=False,
1245             update=update_render_passes,
1246         )
1247         cls.pass_debug_ray_bounces = BoolProperty(
1248             name="Debug Ray Bounces",
1249             description="Store Debug Ray Bounces pass",
1250             default=False,
1251             update=update_render_passes,
1252         )
1253         cls.pass_debug_render_time = BoolProperty(
1254             name="Debug Render Time",
1255             description="Render time in milliseconds per sample and pixel",
1256             default=False,
1257             update=update_render_passes,
1258         )
1259         cls.use_pass_volume_direct = BoolProperty(
1260             name="Volume Direct",
1261             description="Deliver direct volumetric scattering pass",
1262             default=False,
1263             update=update_render_passes,
1264         )
1265         cls.use_pass_volume_indirect = BoolProperty(
1266             name="Volume Indirect",
1267             description="Deliver indirect volumetric scattering pass",
1268             default=False,
1269             update=update_render_passes,
1270         )
1271
1272         cls.use_denoising = BoolProperty(
1273             name="Use Denoising",
1274             description="Denoise the rendered image",
1275             default=False,
1276             update=update_render_passes,
1277         )
1278         cls.denoising_diffuse_direct = BoolProperty(
1279             name="Diffuse Direct",
1280             description="Denoise the direct diffuse lighting",
1281             default=True,
1282         )
1283         cls.denoising_diffuse_indirect = BoolProperty(
1284             name="Diffuse Indirect",
1285             description="Denoise the indirect diffuse lighting",
1286             default=True,
1287         )
1288         cls.denoising_glossy_direct = BoolProperty(
1289             name="Glossy Direct",
1290             description="Denoise the direct glossy lighting",
1291             default=True,
1292         )
1293         cls.denoising_glossy_indirect = BoolProperty(
1294             name="Glossy Indirect",
1295             description="Denoise the indirect glossy lighting",
1296             default=True,
1297         )
1298         cls.denoising_transmission_direct = BoolProperty(
1299             name="Transmission Direct",
1300             description="Denoise the direct transmission lighting",
1301             default=True,
1302         )
1303         cls.denoising_transmission_indirect = BoolProperty(
1304             name="Transmission Indirect",
1305             description="Denoise the indirect transmission lighting",
1306             default=True,
1307         )
1308         cls.denoising_subsurface_direct = BoolProperty(
1309             name="Subsurface Direct",
1310             description="Denoise the direct subsurface lighting",
1311             default=True,
1312         )
1313         cls.denoising_subsurface_indirect = BoolProperty(
1314             name="Subsurface Indirect",
1315             description="Denoise the indirect subsurface lighting",
1316             default=True,
1317         )
1318         cls.denoising_strength = FloatProperty(
1319             name="Denoising Strength",
1320             description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
1321             min=0.0, max=1.0,
1322             default=0.5,
1323         )
1324         cls.denoising_feature_strength = FloatProperty(
1325             name="Denoising Feature Strength",
1326             description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
1327             min=0.0, max=1.0,
1328             default=0.5,
1329         )
1330         cls.denoising_radius = IntProperty(
1331             name="Denoising Radius",
1332             description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
1333             min=1, max=25,
1334             default=8,
1335         )
1336         cls.denoising_relative_pca = BoolProperty(
1337             name="Relative filter",
1338             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)",
1339             default=False,
1340         )
1341         cls.denoising_store_passes = BoolProperty(
1342             name="Store denoising passes",
1343             description="Store the denoising feature passes and the noisy image",
1344             default=False,
1345             update=update_render_passes,
1346         )
1347         denoising_neighbor_frames: IntProperty(
1348             name="Neighbor Frames",
1349             description="Number of neighboring frames to use for denoising animations (more frames produce smoother results at the cost of performance)",
1350             min=0, max=7,
1351             default=0,
1352         )
1353         cls.use_pass_crypto_object = BoolProperty(
1354                 name="Cryptomatte Object",
1355                 description="Render cryptomatte object pass, for isolating objects in compositing",
1356                 default=False,
1357                 update=update_render_passes,
1358                 )
1359         cls.use_pass_crypto_material = BoolProperty(
1360                 name="Cryptomatte Material",
1361                 description="Render cryptomatte material pass, for isolating materials in compositing",
1362                 default=False,
1363                 update=update_render_passes,
1364                 )
1365         cls.use_pass_crypto_asset = BoolProperty(
1366                 name="Cryptomatte Asset",
1367                 description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
1368                 default=False,
1369                 update=update_render_passes,
1370                 )
1371         cls.pass_crypto_depth = IntProperty(
1372                 name="Cryptomatte Levels",
1373                 description="Sets how many unique objects can be distinguished per pixel",
1374                 default=6, min=2, max=16, step=2,
1375                 update=update_render_passes,
1376                 )
1377         cls.pass_crypto_accurate = BoolProperty(
1378                 name="Cryptomatte Accurate",
1379                 description="Gerenate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
1380                 default=True,
1381                 update=update_render_passes,
1382                 )
1383     @classmethod
1384     def unregister(cls):
1385         del bpy.types.SceneRenderLayer.cycles
1386
1387
1388 class CyclesCurveSettings(bpy.types.PropertyGroup):
1389     @classmethod
1390     def register(cls):
1391         bpy.types.ParticleSettings.cycles = PointerProperty(
1392             name="Cycles Hair Settings",
1393             description="Cycles hair settings",
1394             type=cls,
1395         )
1396         cls.radius_scale = FloatProperty(
1397             name="Radius Scaling",
1398             description="Multiplier of width properties",
1399             min=0.0, max=1000.0,
1400             default=0.01,
1401         )
1402         cls.root_width = FloatProperty(
1403             name="Root Size",
1404             description="Strand's width at root",
1405             min=0.0, max=1000.0,
1406             default=1.0,
1407         )
1408         cls.tip_width = FloatProperty(
1409             name="Tip Multiplier",
1410             description="Strand's width at tip",
1411             min=0.0, max=1000.0,
1412             default=0.0,
1413         )
1414         cls.shape = FloatProperty(
1415             name="Strand Shape",
1416             description="Strand shape parameter",
1417             min=-1.0, max=1.0,
1418             default=0.0,
1419         )
1420         cls.use_closetip = BoolProperty(
1421             name="Close tip",
1422             description="Set tip radius to zero",
1423             default=True,
1424         )
1425
1426     @classmethod
1427     def unregister(cls):
1428         del bpy.types.ParticleSettings.cycles
1429
1430
1431 class CyclesDeviceSettings(bpy.types.PropertyGroup):
1432     @classmethod
1433     def register(cls):
1434         cls.id = StringProperty(name="ID")
1435         cls.name = StringProperty(name="Name")
1436         cls.use = BoolProperty(name="Use", default=True)
1437         cls.type = EnumProperty(name="Type", items=enum_device_type, default='CUDA')
1438
1439
1440 class CyclesPreferences(bpy.types.AddonPreferences):
1441     bl_idname = __package__
1442
1443     def get_device_types(self, context):
1444         import _cycles
1445         has_cuda, has_opencl = _cycles.get_device_types()
1446         list = [('NONE', "None", "Don't use compute device", 0)]
1447         if has_cuda:
1448             list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
1449         if has_opencl:
1450             list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
1451         return list
1452
1453     compute_device_type = EnumProperty(
1454         name="Compute Device Type",
1455         description="Device to use for computation (rendering with Cycles)",
1456         items=get_device_types,
1457     )
1458
1459     devices = bpy.props.CollectionProperty(type=CyclesDeviceSettings)
1460
1461     def find_existing_device_entry(self, device):
1462         for device_entry in self.devices:
1463             if device_entry.id == device[2] and device_entry.type == device[1]:
1464                 return device_entry
1465         return None
1466
1467     def update_device_entries(self, device_list):
1468         for device in device_list:
1469             if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
1470                 continue
1471             # Try to find existing Device entry
1472             entry = self.find_existing_device_entry(device)
1473             if not entry:
1474                 # Create new entry if no existing one was found
1475                 entry = self.devices.add()
1476                 entry.id = device[2]
1477                 entry.name = device[0]
1478                 entry.type = device[1]
1479                 entry.use = entry.type != 'CPU'
1480             elif entry.name != device[0]:
1481                 # Update name in case it changed
1482                 entry.name = device[0]
1483
1484     def get_devices(self):
1485         import _cycles
1486         # Layout of the device tuples: (Name, Type, Persistent ID)
1487         device_list = _cycles.available_devices(self.compute_device_type)
1488         # Make sure device entries are up to date and not referenced before
1489         # we know we don't add new devices. This way we guarantee to not
1490         # hold pointers to a resized array.
1491         self.update_device_entries(device_list)
1492         # Sort entries into lists
1493         cuda_devices = []
1494         opencl_devices = []
1495         cpu_devices = []
1496         for device in device_list:
1497             entry = self.find_existing_device_entry(device)
1498             if entry.type == 'CUDA':
1499                 cuda_devices.append(entry)
1500             elif entry.type == 'OPENCL':
1501                 opencl_devices.append(entry)
1502             elif entry.type == 'CPU':
1503                 cpu_devices.append(entry)
1504         # Extend all GPU devices with CPU.
1505         cuda_devices.extend(cpu_devices)
1506         opencl_devices.extend(cpu_devices)
1507         return cuda_devices, opencl_devices
1508
1509     def get_num_gpu_devices(self):
1510         import _cycles
1511         device_list = _cycles.available_devices(self.compute_device_type)
1512         num = 0
1513         for device in device_list:
1514             if device[1] != self.compute_device_type:
1515                 continue
1516             for dev in self.devices:
1517                 if dev.use and dev.id == device[2]:
1518                     num += 1
1519         return num
1520
1521     def has_active_device(self):
1522         return self.get_num_gpu_devices() > 0
1523
1524     def _draw_devices(self, layout, device_type, devices):
1525         box = layout.box()
1526
1527         found_device = False
1528         for device in devices:
1529             if device.type == device_type:
1530                 found_device = True
1531                 break
1532
1533         if not found_device:
1534             box.label(text="No compatible GPUs found", icon='INFO')
1535             return
1536
1537         for device in devices:
1538             box.prop(device, "use", text=device.name)
1539
1540     def draw_impl(self, layout, context):
1541         row = layout.row()
1542         row.prop(self, "compute_device_type", expand=True)
1543
1544         cuda_devices, opencl_devices = self.get_devices()
1545         row = layout.row()
1546         if self.compute_device_type == 'CUDA':
1547             self._draw_devices(row, 'CUDA', cuda_devices)
1548         elif self.compute_device_type == 'OPENCL':
1549             self._draw_devices(row, 'OPENCL', opencl_devices)
1550
1551     def draw(self, context):
1552         self.draw_impl(self.layout, context)
1553
1554
1555 def register():
1556     bpy.utils.register_class(CyclesRenderSettings)
1557     bpy.utils.register_class(CyclesCameraSettings)
1558     bpy.utils.register_class(CyclesMaterialSettings)
1559     bpy.utils.register_class(CyclesLampSettings)
1560     bpy.utils.register_class(CyclesWorldSettings)
1561     bpy.utils.register_class(CyclesVisibilitySettings)
1562     bpy.utils.register_class(CyclesMeshSettings)
1563     bpy.utils.register_class(CyclesObjectSettings)
1564     bpy.utils.register_class(CyclesCurveRenderSettings)
1565     bpy.utils.register_class(CyclesCurveSettings)
1566     bpy.utils.register_class(CyclesDeviceSettings)
1567     bpy.utils.register_class(CyclesPreferences)
1568     bpy.utils.register_class(CyclesRenderLayerSettings)
1569
1570
1571 def unregister():
1572     bpy.utils.unregister_class(CyclesRenderSettings)
1573     bpy.utils.unregister_class(CyclesCameraSettings)
1574     bpy.utils.unregister_class(CyclesMaterialSettings)
1575     bpy.utils.unregister_class(CyclesLampSettings)
1576     bpy.utils.unregister_class(CyclesWorldSettings)
1577     bpy.utils.unregister_class(CyclesMeshSettings)
1578     bpy.utils.unregister_class(CyclesObjectSettings)
1579     bpy.utils.unregister_class(CyclesVisibilitySettings)
1580     bpy.utils.unregister_class(CyclesCurveRenderSettings)
1581     bpy.utils.unregister_class(CyclesCurveSettings)
1582     bpy.utils.unregister_class(CyclesDeviceSettings)
1583     bpy.utils.unregister_class(CyclesPreferences)
1584     bpy.utils.unregister_class(CyclesRenderLayerSettings)