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