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