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