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