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