Merging r46111 through r46136 from trunk into soc-2011-tomato
[blender.git] / intern / cycles / blender / addon / ui.py
1 #
2 # Copyright 2011, Blender Foundation.
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #
18
19 # <pep8 compliant>
20
21 import bpy
22
23 from bpy.types import Panel, Menu
24
25 from . import enums, engine
26
27
28 class CYCLES_MT_integrator_presets(Menu):
29     bl_label = "Integrator Presets"
30     preset_subdir = "cycles/integrator"
31     preset_operator = "script.execute_preset"
32     COMPAT_ENGINES = {'CYCLES'}
33     draw = Menu.draw_preset
34
35
36 class CyclesButtonsPanel():
37     bl_space_type = "PROPERTIES"
38     bl_region_type = "WINDOW"
39     bl_context = "render"
40
41     @classmethod
42     def poll(cls, context):
43         rd = context.scene.render
44         return rd.engine == 'CYCLES'
45
46
47 class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel):
48     bl_label = "Integrator"
49     bl_options = {'DEFAULT_CLOSED'}
50
51     def draw(self, context):
52         layout = self.layout
53
54         scene = context.scene
55         cscene = scene.cycles
56
57         row = layout.row(align=True)
58         row.menu("CYCLES_MT_integrator_presets", text=bpy.types.CYCLES_MT_integrator_presets.bl_label)
59         row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMIN")
60         row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMOUT").remove_active = True
61
62         split = layout.split()
63
64         col = split.column()
65         sub = col.column(align=True)
66         sub.label(text="Samples:")
67         sub.prop(cscene, "samples", text="Render")
68         sub.prop(cscene, "preview_samples", text="Preview")
69         sub.prop(cscene, "seed")
70         sub.prop(cscene, "sample_clamp")
71
72         sub = col.column(align=True)
73         sub.label("Transparency:")
74         sub.prop(cscene, "transparent_max_bounces", text="Max")
75         sub.prop(cscene, "transparent_min_bounces", text="Min")
76         sub.prop(cscene, "use_transparent_shadows", text="Shadows")
77
78         col = split.column()
79
80         sub = col.column(align=True)
81         sub.label(text="Bounces:")
82         sub.prop(cscene, "max_bounces", text="Max")
83         sub.prop(cscene, "min_bounces", text="Min")
84
85         sub = col.column(align=True)
86         sub.label(text="Light Paths:")
87         sub.prop(cscene, "diffuse_bounces", text="Diffuse")
88         sub.prop(cscene, "glossy_bounces", text="Glossy")
89         sub.prop(cscene, "transmission_bounces", text="Transmission")
90
91         col.separator()
92
93         col.prop(cscene, "no_caustics")
94         col.prop(cscene, "blur_glossy")
95
96
97 class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel):
98     bl_label = "Motion Blur"
99     bl_options = {'DEFAULT_CLOSED'}
100
101     @classmethod
102     def poll(cls, context):
103         return False
104
105     def draw_header(self, context):
106         rd = context.scene.render
107
108         self.layout.prop(rd, "use_motion_blur", text="")
109
110     def draw(self, context):
111         layout = self.layout
112
113         rd = context.scene.render
114         layout.active = rd.use_motion_blur
115
116         row = layout.row()
117         row.prop(rd, "motion_blur_shutter")
118
119
120 class CyclesRender_PT_film(CyclesButtonsPanel, Panel):
121     bl_label = "Film"
122
123     def draw(self, context):
124         layout = self.layout
125
126         scene = context.scene
127         cscene = scene.cycles
128
129         split = layout.split()
130
131         col = split.column()
132         col.prop(cscene, "film_exposure")
133         col.prop(cscene, "film_transparent")
134
135         col = split.column()
136         sub = col.column(align=True)
137         sub.prop(cscene, "filter_type", text="")
138         if cscene.filter_type != 'BOX':
139             sub.prop(cscene, "filter_width", text="Width")
140
141
142 class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
143     bl_label = "Performance"
144     bl_options = {'DEFAULT_CLOSED'}
145
146     def draw(self, context):
147         layout = self.layout
148
149         scene = context.scene
150         rd = scene.render
151         cscene = scene.cycles
152
153         split = layout.split()
154
155         col = split.column(align=True)
156
157         col.label(text="Threads:")
158         col.row().prop(rd, "threads_mode", expand=True)
159         sub = col.column()
160         sub.enabled = rd.threads_mode == 'FIXED'
161         sub.prop(rd, "threads")
162
163         sub = col.column(align=True)
164         sub.label(text="Tiles:")
165         sub.prop(cscene, "debug_tile_size")
166         sub.prop(cscene, "debug_min_size")
167
168         col = split.column()
169
170         sub = col.column(align=True)
171         sub.label(text="Acceleration structure:")
172         sub.prop(cscene, "debug_bvh_type", text="")
173         sub.prop(cscene, "debug_use_spatial_splits")
174         sub.prop(cscene, "use_cache")
175
176
177 class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
178     bl_label = "Layers"
179     bl_options = {'DEFAULT_CLOSED'}
180     COMPAT_ENGINES = {'BLENDER_RENDER'}
181
182     def draw(self, context):
183         layout = self.layout
184
185         scene = context.scene
186         rd = scene.render
187
188         row = layout.row()
189         row.template_list(rd, "layers", rd.layers, "active_index", rows=2)
190
191         col = row.column(align=True)
192         col.operator("scene.render_layer_add", icon='ZOOMIN', text="")
193         col.operator("scene.render_layer_remove", icon='ZOOMOUT', text="")
194
195         row = layout.row()
196         rl = rd.layers.active
197         row.prop(rl, "name")
198         row.prop(rd, "use_single_layer", text="", icon_only=True)
199
200         split = layout.split()
201
202         col = split.column()
203         col.prop(scene, "layers", text="Scene")
204         col.prop(rl, "layers_exclude", text="Exclude")
205
206         col = split.column()
207         col.prop(rl, "layers", text="Layer")
208         col.label(text="Mask Layers:")
209         col.prop(rl, "layers_zmask", text="")
210
211         split = layout.split()
212
213         col = split.column()
214         col.label(text="Material:")
215         col.prop(rl, "material_override", text="")
216
217         col = split.column()
218         col.prop(rl, "samples")
219         col.prop(rl, "use_sky", "Use Environment")
220
221         split = layout.split()
222
223         col = split.column()
224         col.label(text="Passes:")
225         col.prop(rl, "use_pass_combined")
226         col.prop(rl, "use_pass_z")
227         col.prop(rl, "use_pass_normal")
228         col.prop(rl, "use_pass_vector")
229         col.prop(rl, "use_pass_uv")
230         col.prop(rl, "use_pass_object_index")
231         col.prop(rl, "use_pass_material_index")
232         col.prop(rl, "use_pass_ambient_occlusion")
233         col.prop(rl, "use_pass_shadow")
234
235         col = split.column()
236         col.label()
237         col.label(text="Diffuse:")
238         row = col.row(align=True)
239         row.prop(rl, "use_pass_diffuse_direct", text="Direct", toggle=True)
240         row.prop(rl, "use_pass_diffuse_indirect", text="Indirect", toggle=True)
241         row.prop(rl, "use_pass_diffuse_color", text="Color", toggle=True)
242         col.label(text="Glossy:")
243         row = col.row(align=True)
244         row.prop(rl, "use_pass_glossy_direct", text="Direct", toggle=True)
245         row.prop(rl, "use_pass_glossy_indirect", text="Indirect", toggle=True)
246         row.prop(rl, "use_pass_glossy_color", text="Color", toggle=True)
247         col.label(text="Transmission:")
248         row = col.row(align=True)
249         row.prop(rl, "use_pass_transmission_direct", text="Direct", toggle=True)
250         row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True)
251         row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True)
252
253         col.prop(rl, "use_pass_emit", text="Emission")
254         col.prop(rl, "use_pass_environment")
255
256
257 class Cycles_PT_post_processing(CyclesButtonsPanel, Panel):
258     bl_label = "Post Processing"
259     bl_options = {'DEFAULT_CLOSED'}
260
261     def draw(self, context):
262         layout = self.layout
263
264         rd = context.scene.render
265
266         split = layout.split()
267
268         col = split.column()
269         col.prop(rd, "use_compositing")
270         col.prop(rd, "use_sequencer")
271
272         col = split.column()
273         col.prop(rd, "dither_intensity", text="Dither", slider=True)
274
275
276 class CyclesCamera_PT_dof(CyclesButtonsPanel, Panel):
277     bl_label = "Depth of Field"
278     bl_context = "data"
279
280     @classmethod
281     def poll(cls, context):
282         return context.camera and CyclesButtonsPanel.poll(context)
283
284     def draw(self, context):
285         layout = self.layout
286
287         cam = context.camera
288         ccam = cam.cycles
289
290         split = layout.split()
291
292         col = split.column()
293         col.label("Focus:")
294         col.prop(cam, "dof_object", text="")
295
296         sub = col.row()
297         sub.active = cam.dof_object is None
298         sub.prop(cam, "dof_distance", text="Distance")
299
300         col = split.column()
301
302         col.label("Aperture:")
303         sub = col.column(align=True)
304         sub.prop(ccam, "aperture_type", text="")
305         if ccam.aperture_type == 'RADIUS':
306             sub.prop(ccam, "aperture_size", text="Size")
307         elif ccam.aperture_type == 'FSTOP':
308             sub.prop(ccam, "aperture_fstop", text="Number")
309
310         sub = col.column(align=True)
311         sub.prop(ccam, "aperture_blades", text="Blades")
312         sub.prop(ccam, "aperture_rotation", text="Rotation")
313
314
315 class Cycles_PT_context_material(CyclesButtonsPanel, Panel):
316     bl_label = ""
317     bl_context = "material"
318     bl_options = {'HIDE_HEADER'}
319
320     @classmethod
321     def poll(cls, context):
322         return (context.material or context.object) and CyclesButtonsPanel.poll(context)
323
324     def draw(self, context):
325         layout = self.layout
326
327         mat = context.material
328         ob = context.object
329         slot = context.material_slot
330         space = context.space_data
331
332         if ob:
333             row = layout.row()
334
335             row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
336
337             col = row.column(align=True)
338             col.operator("object.material_slot_add", icon='ZOOMIN', text="")
339             col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
340
341             col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
342
343             if ob.mode == 'EDIT':
344                 row = layout.row(align=True)
345                 row.operator("object.material_slot_assign", text="Assign")
346                 row.operator("object.material_slot_select", text="Select")
347                 row.operator("object.material_slot_deselect", text="Deselect")
348
349         split = layout.split(percentage=0.65)
350
351         if ob:
352             split.template_ID(ob, "active_material", new="material.new")
353             row = split.row()
354
355             if slot:
356                 row.prop(slot, "link", text="")
357             else:
358                 row.label()
359         elif mat:
360             split.template_ID(space, "pin_id")
361             split.separator()
362
363
364 class Cycles_PT_mesh_displacement(CyclesButtonsPanel, Panel):
365     bl_label = "Displacement"
366     bl_context = "data"
367
368     @classmethod
369     def poll(cls, context):
370         if CyclesButtonsPanel.poll(context):
371             if context.mesh or context.curve or context.meta_ball:
372                 if context.scene.cycles.feature_set == 'EXPERIMENTAL':
373                     return True
374
375         return False
376
377     def draw(self, context):
378         layout = self.layout
379
380         mesh = context.mesh
381         curve = context.curve
382         mball = context.meta_ball
383
384         if mesh:
385             cdata = mesh.cycles
386         elif curve:
387             cdata = curve.cycles
388         elif mball:
389             cdata = mball.cycles
390
391         layout.prop(cdata, "displacement_method", text="Method")
392         layout.prop(cdata, "use_subdivision")
393         layout.prop(cdata, "dicing_rate")
394
395
396 class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel):
397     bl_label = "Ray Visibility"
398     bl_context = "object"
399     bl_options = {'DEFAULT_CLOSED'}
400
401     @classmethod
402     def poll(cls, context):
403         ob = context.object
404         return CyclesButtonsPanel.poll(context) and ob and ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META'}  # todo: 'LAMP'
405
406     def draw(self, context):
407         layout = self.layout
408
409         ob = context.object
410         visibility = ob.cycles_visibility
411
412         flow = layout.column_flow()
413
414         flow.prop(visibility, "camera")
415         flow.prop(visibility, "diffuse")
416         flow.prop(visibility, "glossy")
417         flow.prop(visibility, "transmission")
418         flow.prop(visibility, "shadow")
419
420
421 def find_node(material, nodetype):
422     if material and material.node_tree:
423         ntree = material.node_tree
424
425         for node in ntree.nodes:
426             if getattr(node, "type", None) == nodetype:
427                 return node
428
429     return None
430
431
432 def find_node_input(node, name):
433     for input in node.inputs:
434         if input.name == name:
435             return input
436
437     return None
438
439
440 def panel_node_draw(layout, id_data, output_type, input_name):
441     if not id_data.use_nodes:
442         layout.prop(id_data, "use_nodes", icon='NODETREE')
443         return False
444
445     ntree = id_data.node_tree
446
447     node = find_node(id_data, output_type)
448     if not node:
449         layout.label(text="No output node.")
450     else:
451         input = find_node_input(node, input_name)
452         layout.template_node_view(ntree, node, input)
453
454     return True
455
456
457 class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
458     bl_label = "Lamp"
459     bl_context = "data"
460
461     @classmethod
462     def poll(cls, context):
463         return context.lamp and CyclesButtonsPanel.poll(context)
464
465     def draw(self, context):
466         layout = self.layout
467
468         lamp = context.lamp
469         clamp = lamp.cycles
470
471         layout.prop(lamp, "type", expand=True)
472
473         split = layout.split()
474         col = split.column(align=True)
475
476         if lamp.type in {'POINT', 'SUN', 'SPOT'}:
477             col.prop(lamp, "shadow_soft_size", text="Size")
478         elif lamp.type == 'AREA':
479             col.prop(lamp, "shape", text="")
480             sub = col.column(align=True)
481
482             if lamp.shape == 'SQUARE':
483                 sub.prop(lamp, "size")
484             elif lamp.shape == 'RECTANGLE':
485                 sub.prop(lamp, "size", text="Size X")
486                 sub.prop(lamp, "size_y", text="Size Y")
487
488         col = split.column()
489         col.prop(clamp, "cast_shadow")
490
491         if lamp.type == 'SPOT':
492             layout.label(text="Not supported, interpreted as point lamp.")
493         elif lamp.type == 'HEMI':
494             layout.label(text="Not supported, interpreted as sun lamp.")
495
496
497 class CyclesLamp_PT_nodes(CyclesButtonsPanel, Panel):
498     bl_label = "Nodes"
499     bl_context = "data"
500
501     @classmethod
502     def poll(cls, context):
503         return context.lamp and CyclesButtonsPanel.poll(context)
504
505     def draw(self, context):
506         layout = self.layout
507
508         lamp = context.lamp
509         if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
510             layout.prop(lamp, "color")
511
512
513 class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
514     bl_label = "Surface"
515     bl_context = "world"
516
517     @classmethod
518     def poll(cls, context):
519         return context.world and CyclesButtonsPanel.poll(context)
520
521     def draw(self, context):
522         layout = self.layout
523
524         world = context.world
525
526         if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
527             layout.prop(world, "horizon_color", text="Color")
528
529
530 class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
531     bl_label = "Volume"
532     bl_context = "world"
533     bl_options = {'DEFAULT_CLOSED'}
534
535     @classmethod
536     def poll(cls, context):
537         # world = context.world
538         # world and world.node_tree and CyclesButtonsPanel.poll(context)
539         return False
540
541     def draw(self, context):
542         layout = self.layout
543         layout.active = False
544
545         world = context.world
546         panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
547
548
549 class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
550     bl_label = "Ambient Occlusion"
551     bl_context = "world"
552
553     @classmethod
554     def poll(cls, context):
555         return context.world and CyclesButtonsPanel.poll(context)
556
557     def draw_header(self, context):
558         light = context.world.light_settings
559         self.layout.prop(light, "use_ambient_occlusion", text="")
560
561     def draw(self, context):
562         layout = self.layout
563         light = context.world.light_settings
564
565         layout.active = light.use_ambient_occlusion
566
567         row = layout.row()
568         row.prop(light, "ao_factor", text="Factor")
569         row.prop(light, "distance", text="Distance")
570
571
572 class CyclesWorld_PT_settings(CyclesButtonsPanel, Panel):
573     bl_label = "Settings"
574     bl_context = "world"
575     bl_options = {'DEFAULT_CLOSED'}
576
577     @classmethod
578     def poll(cls, context):
579         return context.world and CyclesButtonsPanel.poll(context)
580
581     def draw(self, context):
582         layout = self.layout
583
584         world = context.world
585         cworld = world.cycles
586
587         col = layout.column()
588
589         col.prop(cworld, "sample_as_light")
590         row = col.row()
591         row.active = cworld.sample_as_light
592         row.prop(cworld, "sample_map_resolution")
593
594
595 class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel):
596     bl_label = "Surface"
597     bl_context = "material"
598
599     @classmethod
600     def poll(cls, context):
601         return context.material and CyclesButtonsPanel.poll(context)
602
603     def draw(self, context):
604         layout = self.layout
605
606         mat = context.material
607         if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
608             layout.prop(mat, "diffuse_color")
609
610
611 class CyclesMaterial_PT_volume(CyclesButtonsPanel, Panel):
612     bl_label = "Volume"
613     bl_context = "material"
614     bl_options = {'DEFAULT_CLOSED'}
615
616     @classmethod
617     def poll(cls, context):
618         # mat = context.material
619         # mat and mat.node_tree and CyclesButtonsPanel.poll(context)
620         return False
621
622     def draw(self, context):
623         layout = self.layout
624         layout.active = False
625
626         mat = context.material
627         cmat = mat.cycles
628
629         panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
630
631         layout.prop(cmat, "homogeneous_volume")
632
633
634 class CyclesMaterial_PT_displacement(CyclesButtonsPanel, Panel):
635     bl_label = "Displacement"
636     bl_context = "material"
637
638     @classmethod
639     def poll(cls, context):
640         mat = context.material
641         return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
642
643     def draw(self, context):
644         layout = self.layout
645
646         mat = context.material
647         panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
648
649
650 class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
651     bl_label = "Settings"
652     bl_context = "material"
653     bl_options = {'DEFAULT_CLOSED'}
654
655     @classmethod
656     def poll(cls, context):
657         return context.material and CyclesButtonsPanel.poll(context)
658
659     def draw(self, context):
660         layout = self.layout
661
662         mat = context.material
663         cmat = mat.cycles
664
665         split = layout.split()
666
667         col = split.column()
668         col.prop(mat, "diffuse_color", text="Viewport Color")
669
670         col = split.column()
671         col.prop(cmat, "sample_as_light")
672         col.prop(mat, "pass_index")
673
674
675 class CyclesTexture_PT_context(CyclesButtonsPanel, Panel):
676     bl_label = ""
677     bl_context = "texture"
678     bl_options = {'HIDE_HEADER'}
679     COMPAT_ENGINES = {'CYCLES'}
680
681     def draw(self, context):
682         layout = self.layout
683
684         tex = context.texture
685         space = context.space_data
686         pin_id = space.pin_id
687         use_pin_id = space.use_pin_id
688         user = context.texture_user
689
690         if not use_pin_id or not isinstance(pin_id, bpy.types.Texture):
691             pin_id = None
692
693         if not pin_id:
694             layout.template_texture_user()
695
696         if user:
697             layout.separator()
698
699             split = layout.split(percentage=0.65)
700             col = split.column()
701
702             if pin_id:
703                 col.template_ID(space, "pin_id")
704             elif user:
705                 col.template_ID(user, "texture", new="texture.new")
706
707             if tex:
708                 split = layout.split(percentage=0.2)
709                 split.label(text="Type:")
710                 split.prop(tex, "type", text="")
711
712
713 class CyclesTexture_PT_nodes(CyclesButtonsPanel, Panel):
714     bl_label = "Nodes"
715     bl_context = "texture"
716
717     @classmethod
718     def poll(cls, context):
719         tex = context.texture
720         return (tex and tex.use_nodes) and CyclesButtonsPanel.poll(context)
721
722     def draw(self, context):
723         layout = self.layout
724
725         tex = context.texture
726         panel_node_draw(layout, tex, 'OUTPUT_TEXTURE', 'Color')
727
728
729 class CyclesTexture_PT_node(CyclesButtonsPanel, Panel):
730     bl_label = "Node"
731     bl_context = "texture"
732
733     @classmethod
734     def poll(cls, context):
735         node = context.texture_node
736         return node and CyclesButtonsPanel.poll(context)
737
738     def draw(self, context):
739         layout = self.layout
740
741         node = context.texture_node
742         ntree = node.id_data
743         layout.template_node_view(ntree, node, None)
744
745
746 class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel):
747     bl_label = "Mapping"
748     bl_context = "texture"
749
750     @classmethod
751     def poll(cls, context):
752         tex = context.texture
753         node = context.texture_node
754         return (node or (tex and tex.use_nodes)) and CyclesButtonsPanel.poll(context)
755
756     def draw(self, context):
757         layout = self.layout
758
759         # tex = context.texture
760         node = context.texture_node
761
762         mapping = node.texture_mapping
763
764         row = layout.row()
765
766         row.column().prop(mapping, "translation")
767         row.column().prop(mapping, "rotation")
768         row.column().prop(mapping, "scale")
769
770         layout.label(text="Projection:")
771
772         row = layout.row()
773         row.prop(mapping, "mapping_x", text="")
774         row.prop(mapping, "mapping_y", text="")
775         row.prop(mapping, "mapping_z", text="")
776
777
778 class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel):
779     bl_label = "Color"
780     bl_context = "texture"
781     bl_options = {'DEFAULT_CLOSED'}
782
783     @classmethod
784     def poll(cls, context):
785         # tex = context.texture
786         # node = context.texture_node
787         return False
788         #return (node or (tex and tex.use_nodes)) and CyclesButtonsPanel.poll(context)
789
790     def draw(self, context):
791         layout = self.layout
792
793         # tex = context.texture
794         node = context.texture_node
795
796         mapping = node.color_mapping
797
798         split = layout.split()
799
800         col = split.column()
801         col.label(text="Blend:")
802         col.prop(mapping, "blend_type", text="")
803         col.prop(mapping, "blend_factor", text="Factor")
804         col.prop(mapping, "blend_color", text="")
805
806         col = split.column()
807         col.label(text="Adjust:")
808         col.prop(mapping, "brightness")
809         col.prop(mapping, "contrast")
810         col.prop(mapping, "saturation")
811
812         layout.separator()
813
814         layout.prop(mapping, "use_color_ramp", text="Ramp")
815         if mapping.use_color_ramp:
816             layout.template_color_ramp(mapping, "color_ramp", expand=True)
817
818
819 class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel):
820     bl_label = "Simplify"
821     bl_context = "scene"
822     COMPAT_ENGINES = {'CYCLES'}
823
824     def draw_header(self, context):
825         rd = context.scene.render
826         self.layout.prop(rd, "use_simplify", text="")
827
828     def draw(self, context):
829         layout = self.layout
830
831         rd = context.scene.render
832
833         layout.active = rd.use_simplify
834
835         split = layout.split()
836
837         col = split.column()
838         col.prop(rd, "simplify_subdivision", text="Subdivision")
839
840         col = split.column()
841         col.prop(rd, "simplify_child_particles", text="Child Particles")
842
843
844 def draw_device(self, context):
845     scene = context.scene
846     layout = self.layout
847
848     if scene.render.engine == 'CYCLES':
849         cscene = scene.cycles
850
851         layout.prop(cscene, "feature_set")
852
853         device_type = context.user_preferences.system.compute_device_type
854         if device_type == 'CUDA':
855             layout.prop(cscene, "device")
856         elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL':
857             layout.prop(cscene, "device")
858
859
860 def draw_pause(self, context):
861     layout = self.layout
862     scene = context.scene
863
864     if scene.render.engine == "CYCLES":
865         view = context.space_data
866
867         if view.viewport_shade == 'RENDERED':
868             cscene = scene.cycles
869             layername = scene.render.layers.active.name
870             layout.prop(cscene, "preview_pause", icon="PAUSE", text="")
871             layout.prop(cscene, "preview_active_layer", icon="RENDERLAYERS", text=layername)
872
873
874 def get_panels():
875     return (
876         bpy.types.RENDER_PT_render,
877         bpy.types.RENDER_PT_output,
878         bpy.types.RENDER_PT_encoding,
879         bpy.types.RENDER_PT_dimensions,
880         bpy.types.RENDER_PT_stamp,
881         bpy.types.SCENE_PT_scene,
882         bpy.types.SCENE_PT_audio,
883         bpy.types.SCENE_PT_unit,
884         bpy.types.SCENE_PT_keying_sets,
885         bpy.types.SCENE_PT_keying_set_paths,
886         bpy.types.SCENE_PT_physics,
887         bpy.types.WORLD_PT_context_world,
888         bpy.types.DATA_PT_context_mesh,
889         bpy.types.DATA_PT_context_camera,
890         bpy.types.DATA_PT_context_lamp,
891         bpy.types.DATA_PT_texture_space,
892         bpy.types.DATA_PT_curve_texture_space,
893         bpy.types.DATA_PT_mball_texture_space,
894         bpy.types.DATA_PT_vertex_groups,
895         bpy.types.DATA_PT_shape_keys,
896         bpy.types.DATA_PT_uv_texture,
897         bpy.types.DATA_PT_vertex_colors,
898         bpy.types.DATA_PT_camera,
899         bpy.types.DATA_PT_camera_display,
900         bpy.types.DATA_PT_lens,
901         bpy.types.DATA_PT_custom_props_mesh,
902         bpy.types.DATA_PT_custom_props_camera,
903         bpy.types.DATA_PT_custom_props_lamp,
904         bpy.types.TEXTURE_PT_clouds,
905         bpy.types.TEXTURE_PT_wood,
906         bpy.types.TEXTURE_PT_marble,
907         bpy.types.TEXTURE_PT_magic,
908         bpy.types.TEXTURE_PT_blend,
909         bpy.types.TEXTURE_PT_stucci,
910         bpy.types.TEXTURE_PT_image,
911         bpy.types.TEXTURE_PT_image_sampling,
912         bpy.types.TEXTURE_PT_image_mapping,
913         bpy.types.TEXTURE_PT_musgrave,
914         bpy.types.TEXTURE_PT_voronoi,
915         bpy.types.TEXTURE_PT_distortednoise,
916         bpy.types.TEXTURE_PT_voxeldata,
917         bpy.types.TEXTURE_PT_pointdensity,
918         bpy.types.TEXTURE_PT_pointdensity_turbulence,
919         bpy.types.PARTICLE_PT_context_particles,
920         bpy.types.PARTICLE_PT_emission,
921         bpy.types.PARTICLE_PT_hair_dynamics,
922         bpy.types.PARTICLE_PT_cache,
923         bpy.types.PARTICLE_PT_velocity,
924         bpy.types.PARTICLE_PT_rotation,
925         bpy.types.PARTICLE_PT_physics,
926         bpy.types.PARTICLE_PT_boidbrain,
927         bpy.types.PARTICLE_PT_render,
928         bpy.types.PARTICLE_PT_draw,
929         bpy.types.PARTICLE_PT_children,
930         bpy.types.PARTICLE_PT_field_weights,
931         bpy.types.PARTICLE_PT_force_fields,
932         bpy.types.PARTICLE_PT_vertexgroups,
933         bpy.types.PARTICLE_PT_custom_props,
934         )
935
936
937 def register():
938     bpy.types.RENDER_PT_render.append(draw_device)
939     bpy.types.VIEW3D_HT_header.append(draw_pause)
940
941     for panel in get_panels():
942         panel.COMPAT_ENGINES.add('CYCLES')
943
944
945 def unregister():
946     bpy.types.RENDER_PT_render.remove(draw_device)
947     bpy.types.VIEW3D_HT_header.remove(draw_pause)
948
949     for panel in get_panels():
950         panel.COMPAT_ENGINES.remove('CYCLES')