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