Removed a remnant to an unsuccessful attempt to get clipping functional so I can...
[blender.git] / release / scripts / startup / bl_ui / properties_material.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from rna_prop_ui import PropertyPanel
22
23
24 def active_node_mat(mat):
25     # TODO, 2.4x has a pipeline section, for 2.5 we need to communicate
26     # which settings from node-materials are used
27     if mat is not None:
28         mat_node = mat.active_node_material
29         if mat_node:
30             return mat_node
31         else:
32             return mat
33
34     return None
35
36
37 def check_material(mat):
38     if mat is not None:
39         if mat.use_nodes:
40             if mat.active_node_material is not None:
41                 return True
42             return False
43         return True
44     return False
45
46
47 def simple_material(mat):
48     if (mat is not None) and (not mat.use_nodes):
49         return True
50     return False
51
52
53 class MATERIAL_MT_sss_presets(bpy.types.Menu):
54     bl_label = "SSS Presets"
55     preset_subdir = "sss"
56     preset_operator = "script.execute_preset"
57     draw = bpy.types.Menu.draw_preset
58
59
60 class MATERIAL_MT_specials(bpy.types.Menu):
61     bl_label = "Material Specials"
62
63     def draw(self, context):
64         layout = self.layout
65
66         layout.operator("object.material_slot_copy", icon='COPY_ID')
67         layout.operator("material.copy", icon='COPYDOWN')
68         layout.operator("material.paste", icon='PASTEDOWN')
69
70
71 class MaterialButtonsPanel():
72     bl_space_type = 'PROPERTIES'
73     bl_region_type = 'WINDOW'
74     bl_context = "material"
75     # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
76
77     @classmethod
78     def poll(cls, context):
79         return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES)
80
81
82 class MATERIAL_PT_context_material(MaterialButtonsPanel, bpy.types.Panel):
83     bl_label = ""
84     bl_options = {'HIDE_HEADER'}
85     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
86
87     @classmethod
88     def poll(cls, context):
89         # An exception, dont call the parent poll func because
90         # this manages materials for all engine types
91
92         engine = context.scene.render.engine
93         return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)
94
95     def draw(self, context):
96         layout = self.layout
97
98         mat = context.material
99         ob = context.object
100         slot = context.material_slot
101         space = context.space_data
102
103         if ob:
104             row = layout.row()
105
106             row.template_list(ob, "material_slots", ob, "active_material_index", rows=2)
107
108             col = row.column(align=True)
109             col.operator("object.material_slot_add", icon='ZOOMIN', text="")
110             col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
111
112             col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
113
114             if ob.mode == 'EDIT':
115                 row = layout.row(align=True)
116                 row.operator("object.material_slot_assign", text="Assign")
117                 row.operator("object.material_slot_select", text="Select")
118                 row.operator("object.material_slot_deselect", text="Deselect")
119
120         split = layout.split(percentage=0.65)
121
122         if ob:
123             split.template_ID(ob, "active_material", new="material.new")
124             row = split.row()
125             if mat:
126                 row.prop(mat, "use_nodes", icon="NODETREE", text="")
127
128             if slot:
129                 row.prop(slot, "link", text="")
130             else:
131                 row.label()
132         elif mat:
133             split.template_ID(space, "pin_id")
134             split.separator()
135
136         if mat:
137             layout.prop(mat, "type", expand=True)
138             if mat.use_nodes:
139                 row = layout.row()
140                 row.label(text="", icon='NODETREE')
141                 if mat.active_node_material:
142                     row.prop(mat.active_node_material, "name", text="")
143                 else:
144                     row.label(text="No material node selected")
145
146
147 class MATERIAL_PT_preview(MaterialButtonsPanel, bpy.types.Panel):
148     bl_label = "Preview"
149     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
150
151     def draw(self, context):
152         self.layout.template_preview(context.material)
153
154
155 class MATERIAL_PT_pipeline(MaterialButtonsPanel, bpy.types.Panel):
156     bl_label = "Render Pipeline Options"
157     bl_options = {'DEFAULT_CLOSED'}
158     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
159
160     @classmethod
161     def poll(cls, context):
162         mat = context.material
163         engine = context.scene.render.engine
164         return mat and (not simple_material(mat)) and (mat.type in {'SURFACE', 'WIRE', 'VOLUME'}) and (engine in cls.COMPAT_ENGINES)
165
166     def draw(self, context):
167         layout = self. layout
168
169         mat = context.material
170         mat_type = mat.type in {'SURFACE', 'WIRE'}
171
172         row = layout.row()
173         row.active = mat_type
174         row.prop(mat, "use_transparency")
175         sub = row.column()
176         sub.prop(mat, "offset_z")
177         sub.active = mat_type and mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY'
178
179         row = layout.row()
180         row.active = mat.use_transparency or not mat_type
181         row.prop(mat, "transparency_method", expand=True)
182
183         layout.separator()
184
185         split = layout.split()
186         col = split.column()
187
188         col.prop(mat, "use_raytrace")
189         col.prop(mat, "use_full_oversampling")
190         sub = col.column()
191         sub.active = mat_type
192         sub.prop(mat, "use_sky")
193         sub.prop(mat, "invert_z")
194
195         col = split.column()
196         col.active = mat_type
197
198         col.prop(mat, "use_cast_shadows_only", text="Cast Only")
199         col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
200         col.prop(mat, "use_cast_buffer_shadows")
201         col.prop(mat, "use_cast_approximate")
202
203
204 class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
205     bl_label = "Diffuse"
206     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
207
208     @classmethod
209     def poll(cls, context):
210         mat = context.material
211         engine = context.scene.render.engine
212         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
213
214     def draw(self, context):
215         layout = self.layout
216
217         mat = active_node_mat(context.material)
218
219         split = layout.split()
220
221         col = split.column()
222         col.prop(mat, "diffuse_color", text="")
223         sub = col.column()
224         sub.active = (not mat.use_shadeless)
225         sub.prop(mat, "diffuse_intensity", text="Intensity")
226
227         col = split.column()
228         col.active = (not mat.use_shadeless)
229         col.prop(mat, "diffuse_shader", text="")
230         col.prop(mat, "use_diffuse_ramp", text="Ramp")
231
232         col = layout.column()
233         col.active = (not mat.use_shadeless)
234         if mat.diffuse_shader == 'OREN_NAYAR':
235             col.prop(mat, "roughness")
236         elif mat.diffuse_shader == 'MINNAERT':
237             col.prop(mat, "darkness")
238         elif mat.diffuse_shader == 'TOON':
239             row = col.row()
240             row.prop(mat, "diffuse_toon_size", text="Size")
241             row.prop(mat, "diffuse_toon_smooth", text="Smooth")
242         elif mat.diffuse_shader == 'FRESNEL':
243             row = col.row()
244             row.prop(mat, "diffuse_fresnel", text="Fresnel")
245             row.prop(mat, "diffuse_fresnel_factor", text="Factor")
246
247         if mat.use_diffuse_ramp:
248             layout.separator()
249             layout.template_color_ramp(mat, "diffuse_ramp", expand=True)
250             layout.separator()
251
252             row = layout.row()
253             row.prop(mat, "diffuse_ramp_input", text="Input")
254             row.prop(mat, "diffuse_ramp_blend", text="Blend")
255
256             layout.prop(mat, "diffuse_ramp_factor", text="Factor")
257
258
259 class MATERIAL_PT_specular(MaterialButtonsPanel, bpy.types.Panel):
260     bl_label = "Specular"
261     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
262
263     @classmethod
264     def poll(cls, context):
265         mat = context.material
266         engine = context.scene.render.engine
267         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
268
269     def draw(self, context):
270         layout = self.layout
271
272         mat = active_node_mat(context.material)
273
274         layout.active = (not mat.use_shadeless)
275
276         split = layout.split()
277
278         col = split.column()
279         col.prop(mat, "specular_color", text="")
280         col.prop(mat, "specular_intensity", text="Intensity")
281
282         col = split.column()
283         col.prop(mat, "specular_shader", text="")
284         col.prop(mat, "use_specular_ramp", text="Ramp")
285
286         col = layout.column()
287         if mat.specular_shader in {'COOKTORR', 'PHONG'}:
288             col.prop(mat, "specular_hardness", text="Hardness")
289         elif mat.specular_shader == 'BLINN':
290             row = col.row()
291             row.prop(mat, "specular_hardness", text="Hardness")
292             row.prop(mat, "specular_ior", text="IOR")
293         elif mat.specular_shader == 'WARDISO':
294             col.prop(mat, "specular_slope", text="Slope")
295         elif mat.specular_shader == 'TOON':
296             row = col.row()
297             row.prop(mat, "specular_toon_size", text="Size")
298             row.prop(mat, "specular_toon_smooth", text="Smooth")
299
300         if mat.use_specular_ramp:
301             layout.separator()
302             layout.template_color_ramp(mat, "specular_ramp", expand=True)
303             layout.separator()
304
305             row = layout.row()
306             row.prop(mat, "specular_ramp_input", text="Input")
307             row.prop(mat, "specular_ramp_blend", text="Blend")
308
309             layout.prop(mat, "specular_ramp_factor", text="Factor")
310
311
312 class MATERIAL_PT_shading(MaterialButtonsPanel, bpy.types.Panel):
313     bl_label = "Shading"
314     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
315
316     @classmethod
317     def poll(cls, context):
318         mat = context.material
319         engine = context.scene.render.engine
320         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
321
322     def draw(self, context):
323         layout = self.layout
324
325         mat = active_node_mat(context.material)
326
327         if mat.type in {'SURFACE', 'WIRE'}:
328             split = layout.split()
329
330             col = split.column()
331             sub = col.column()
332             sub.active = not mat.use_shadeless
333             sub.prop(mat, "emit")
334             sub.prop(mat, "ambient")
335             sub = col.column()
336             sub.prop(mat, "translucency")
337
338             col = split.column()
339             col.prop(mat, "use_shadeless")
340             sub = col.column()
341             sub.active = not mat.use_shadeless
342             sub.prop(mat, "use_tangent_shading")
343             sub.prop(mat, "use_cubic")
344
345
346 class MATERIAL_PT_transp(MaterialButtonsPanel, bpy.types.Panel):
347     bl_label = "Transparency"
348     # bl_options = {'DEFAULT_CLOSED'}
349     COMPAT_ENGINES = {'BLENDER_RENDER'}
350
351     @classmethod
352     def poll(cls, context):
353         mat = context.material
354         engine = context.scene.render.engine
355         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
356
357     def draw_header(self, context):
358         mat = context.material
359
360         if simple_material(mat):
361             self.layout.prop(mat, "use_transparency", text="")
362
363     def draw(self, context):
364         layout = self.layout
365
366         base_mat = context.material
367         mat = active_node_mat(context.material)
368         rayt = mat.raytrace_transparency
369
370         if simple_material(base_mat):
371             row = layout.row()
372             row.active = mat.use_transparency
373             row.prop(mat, "transparency_method", expand=True)
374
375         split = layout.split()
376         split.active = base_mat.use_transparency
377
378         col = split.column()
379         col.prop(mat, "alpha")
380         row = col.row()
381         row.active = (base_mat.transparency_method != 'MASK') and (not mat.use_shadeless)
382         row.prop(mat, "specular_alpha", text="Specular")
383
384         col = split.column()
385         col.active = (not mat.use_shadeless)
386         col.prop(rayt, "fresnel")
387         sub = col.column()
388         sub.active = rayt.fresnel > 0
389         sub.prop(rayt, "fresnel_factor", text="Blend")
390
391         if base_mat.transparency_method == 'RAYTRACE':
392             layout.separator()
393             split = layout.split()
394             split.active = base_mat.use_transparency
395
396             col = split.column()
397             col.prop(rayt, "ior")
398             col.prop(rayt, "filter")
399             col.prop(rayt, "falloff")
400             col.prop(rayt, "depth_max")
401             col.prop(rayt, "depth")
402
403             col = split.column()
404             col.label(text="Gloss:")
405             col.prop(rayt, "gloss_factor", text="Amount")
406             sub = col.column()
407             sub.active = rayt.gloss_factor < 1.0
408             sub.prop(rayt, "gloss_threshold", text="Threshold")
409             sub.prop(rayt, "gloss_samples", text="Samples")
410
411
412 class MATERIAL_PT_mirror(MaterialButtonsPanel, bpy.types.Panel):
413     bl_label = "Mirror"
414     bl_options = {'DEFAULT_CLOSED'}
415     COMPAT_ENGINES = {'BLENDER_RENDER'}
416
417     @classmethod
418     def poll(cls, context):
419         mat = context.material
420         engine = context.scene.render.engine
421         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
422
423     def draw_header(self, context):
424         raym = active_node_mat(context.material).raytrace_mirror
425
426         self.layout.prop(raym, "use", text="")
427
428     def draw(self, context):
429         layout = self.layout
430
431         mat = active_node_mat(context.material)
432         raym = mat.raytrace_mirror
433
434         layout.active = raym.use
435
436         split = layout.split()
437
438         col = split.column()
439         col.prop(raym, "reflect_factor")
440         col.prop(mat, "mirror_color", text="")
441
442         col = split.column()
443         col.prop(raym, "fresnel")
444         sub = col.column()
445         sub.active = raym.fresnel > 0
446         sub.prop(raym, "fresnel_factor", text="Blend")
447
448         split = layout.split()
449
450         col = split.column()
451         col.separator()
452         col.prop(raym, "depth")
453         col.prop(raym, "distance", text="Max Dist")
454         col.separator()
455         sub = col.split(percentage=0.4)
456         sub.active = raym.distance > 0.0
457         sub.label(text="Fade To:")
458         sub.prop(raym, "fade_to", text="")
459
460         col = split.column()
461         col.label(text="Gloss:")
462         col.prop(raym, "gloss_factor", text="Amount")
463         sub = col.column()
464         sub.active = raym.gloss_factor < 1.0
465         sub.prop(raym, "gloss_threshold", text="Threshold")
466         sub.prop(raym, "gloss_samples", text="Samples")
467         sub.prop(raym, "gloss_anisotropic", text="Anisotropic")
468
469
470 class MATERIAL_PT_sss(MaterialButtonsPanel, bpy.types.Panel):
471     bl_label = "Subsurface Scattering"
472     bl_options = {'DEFAULT_CLOSED'}
473     COMPAT_ENGINES = {'BLENDER_RENDER'}
474
475     @classmethod
476     def poll(cls, context):
477         mat = context.material
478         engine = context.scene.render.engine
479         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
480
481     def draw_header(self, context):
482         mat = active_node_mat(context.material)
483         sss = mat.subsurface_scattering
484
485         self.layout.active = (not mat.use_shadeless)
486         self.layout.prop(sss, "use", text="")
487
488     def draw(self, context):
489         layout = self.layout
490
491         mat = active_node_mat(context.material)
492         sss = mat.subsurface_scattering
493
494         layout.active = (sss.use) and (not mat.use_shadeless)
495
496         row = layout.row().split()
497         sub = row.row(align=True).split(percentage=0.75)
498         sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label)
499         sub.operator("material.sss_preset_add", text="", icon="ZOOMIN")
500         sub.operator("material.sss_preset_add", text="", icon="ZOOMOUT").remove_active = True
501
502         split = layout.split()
503
504         col = split.column()
505         col.prop(sss, "ior")
506         col.prop(sss, "scale")
507         col.prop(sss, "color", text="")
508         col.prop(sss, "radius", text="RGB Radius", expand=True)
509
510         col = split.column()
511         sub = col.column(align=True)
512         sub.label(text="Blend:")
513         sub.prop(sss, "color_factor", text="Color")
514         sub.prop(sss, "texture_factor", text="Texture")
515         sub.label(text="Scattering Weight:")
516         sub.prop(sss, "front")
517         sub.prop(sss, "back")
518         col.separator()
519         col.prop(sss, "error_threshold", text="Error")
520
521
522 class MATERIAL_PT_halo(MaterialButtonsPanel, bpy.types.Panel):
523     bl_label = "Halo"
524     COMPAT_ENGINES = {'BLENDER_RENDER'}
525
526     @classmethod
527     def poll(cls, context):
528         mat = context.material
529         engine = context.scene.render.engine
530         return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES)
531
532     def draw(self, context):
533         layout = self.layout
534
535         mat = context.material  # dont use node material
536         halo = mat.halo
537
538         def number_but(layout, toggle, number, name, color):
539             row = layout.row(align=True)
540             row.prop(halo, toggle, text="")
541             sub = row.column()
542             sub.active = getattr(halo, toggle)
543             sub.prop(halo, number, text=name)
544             if not color == "":
545                 sub.prop(mat, color, text="")
546
547         split = layout.split()
548
549         col = split.column()
550         col.prop(mat, "alpha")
551         col.prop(mat, "diffuse_color", text="")
552         col.prop(halo, "seed")
553
554         col = split.column()
555         col.prop(halo, "size")
556         col.prop(halo, "hardness")
557         col.prop(halo, "add")
558
559         layout.label(text="Options:")
560
561         split = layout.split()
562         col = split.column()
563         col.prop(halo, "use_texture")
564         col.prop(halo, "use_vertex_normal")
565         col.prop(halo, "use_extreme_alpha")
566         col.prop(halo, "use_shaded")
567         col.prop(halo, "use_soft")
568
569         col = split.column()
570         number_but(col, "use_ring", "ring_count", "Rings", "mirror_color")
571         number_but(col, "use_lines", "line_count", "Lines", "specular_color")
572         number_but(col, "use_star", "star_tip_count", "Star tips", "")
573
574
575 class MATERIAL_PT_flare(MaterialButtonsPanel, bpy.types.Panel):
576     bl_label = "Flare"
577     COMPAT_ENGINES = {'BLENDER_RENDER'}
578
579     @classmethod
580     def poll(cls, context):
581         mat = context.material
582         engine = context.scene.render.engine
583         return mat and (mat.type == 'HALO') and (engine in cls.COMPAT_ENGINES)
584
585     def draw_header(self, context):
586         halo = context.material.halo
587
588         self.layout.prop(halo, "use_flare_mode", text="")
589
590     def draw(self, context):
591         layout = self.layout
592
593         mat = context.material  # dont use node material
594         halo = mat.halo
595
596         layout.active = halo.use_flare_mode
597
598         split = layout.split()
599
600         col = split.column()
601         col.prop(halo, "flare_size", text="Size")
602         col.prop(halo, "flare_boost", text="Boost")
603         col.prop(halo, "flare_seed", text="Seed")
604
605         col = split.column()
606         col.prop(halo, "flare_subflare_count", text="Subflares")
607         col.prop(halo, "flare_subflare_size", text="Subsize")
608
609
610 class MATERIAL_PT_physics(MaterialButtonsPanel, bpy.types.Panel):
611     bl_label = "Physics"
612     COMPAT_ENGINES = {'BLENDER_GAME'}
613
614     @classmethod
615     def poll(cls, context):
616         return context.material and (context.scene.render.engine in cls.COMPAT_ENGINES)
617
618     def draw(self, context):
619         layout = self.layout
620
621         phys = context.material.physics  # dont use node material
622
623         split = layout.split()
624         row = split.row()
625         row.prop(phys, "friction")
626         row.prop(phys, "elasticity", slider=True)
627
628         row = layout.row()
629         row.label(text="Force Field:")
630
631         row = layout.row()
632         row.prop(phys, "fh_force")
633         row.prop(phys, "fh_damping", slider=True)
634
635         row = layout.row()
636         row.prop(phys, "fh_distance")
637         row.prop(phys, "use_fh_normal")
638
639
640 class MATERIAL_PT_strand(MaterialButtonsPanel, bpy.types.Panel):
641     bl_label = "Strand"
642     bl_options = {'DEFAULT_CLOSED'}
643     COMPAT_ENGINES = {'BLENDER_RENDER'}
644
645     @classmethod
646     def poll(cls, context):
647         mat = context.material
648         engine = context.scene.render.engine
649         return mat and (mat.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES)
650
651     def draw(self, context):
652         layout = self.layout
653
654         mat = context.material  # dont use node material
655         tan = mat.strand
656
657         split = layout.split()
658
659         col = split.column()
660         sub = col.column(align=True)
661         sub.label(text="Size:")
662         sub.prop(tan, "root_size", text="Root")
663         sub.prop(tan, "tip_size", text="Tip")
664         sub.prop(tan, "size_min", text="Minimum")
665         sub.prop(tan, "use_blender_units")
666         sub = col.column()
667         sub.active = (not mat.use_shadeless)
668         sub.prop(tan, "use_tangent_shading")
669         col.prop(tan, "shape")
670
671         col = split.column()
672         col.label(text="Shading:")
673         col.prop(tan, "width_fade")
674         ob = context.object
675         if ob and ob.type == 'MESH':
676             col.prop_search(tan, "uv_layer", ob.data, "uv_textures", text="")
677         else:
678             col.prop(tan, "uv_layer", text="")
679         col.separator()
680         sub = col.column()
681         sub.active = (not mat.use_shadeless)
682         sub.label("Surface diffuse:")
683         sub = col.column()
684         sub.prop(tan, "blend_distance", text="Distance")
685
686
687 class MATERIAL_PT_options(MaterialButtonsPanel, bpy.types.Panel):
688     bl_label = "Options"
689     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
690
691     @classmethod
692     def poll(cls, context):
693         mat = context.material
694         engine = context.scene.render.engine
695         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
696
697     def draw(self, context):
698         layout = self.layout
699
700         base_mat = context.material
701         mat = active_node_mat(base_mat)
702
703         split = layout.split()
704
705         col = split.column()
706         if simple_material(base_mat):
707             col.prop(mat, "use_raytrace")
708             col.prop(mat, "use_full_oversampling")
709             col.prop(mat, "use_sky")
710         col.prop(mat, "use_mist")
711         if simple_material(base_mat):
712             col.prop(mat, "invert_z")
713             sub = col.row()
714             sub.prop(mat, "offset_z")
715             sub.active = mat.use_transparency and mat.transparency_method == 'Z_TRANSPARENCY'
716         sub = col.column(align=True)
717         sub.label(text="Light Group:")
718         sub.prop(mat, "light_group", text="")
719         row = sub.row()
720         row.active = bool(mat.light_group)
721         row.prop(mat, "use_light_group_exclusive", text="Exclusive")
722
723         col = split.column()
724         col.prop(mat, "use_face_texture")
725         sub = col.column()
726         sub.active = mat.use_face_texture
727         sub.prop(mat, "use_face_texture_alpha")
728         col.separator()
729         col.prop(mat, "use_vertex_color_paint")
730         col.prop(mat, "use_vertex_color_light")
731         col.prop(mat, "use_object_color")
732         col.prop(mat, "pass_index")
733
734
735 class MATERIAL_PT_shadow(MaterialButtonsPanel, bpy.types.Panel):
736     bl_label = "Shadow"
737     bl_options = {'DEFAULT_CLOSED'}
738     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
739
740     @classmethod
741     def poll(cls, context):
742         mat = context.material
743         engine = context.scene.render.engine
744         return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)
745
746     def draw(self, context):
747         layout = self.layout
748
749         base_mat = context.material
750         mat = active_node_mat(base_mat)
751
752         split = layout.split()
753
754         col = split.column()
755         col.prop(mat, "use_shadows", text="Receive")
756         col.prop(mat, "use_transparent_shadows", text="Receive Transparent")
757         if simple_material(base_mat):
758             col.prop(mat, "use_cast_shadows_only", text="Cast Only")
759             col.prop(mat, "shadow_cast_alpha", text="Casting Alpha")
760         col.prop(mat, "use_only_shadow", text="Shadows Only")
761         sub = col.column()
762         sub.active = mat.use_only_shadow
763         sub.prop(mat, "shadow_only_type", text="")
764
765         col = split.column()
766         if simple_material(base_mat):
767             col.prop(mat, "use_cast_buffer_shadows")
768         sub = col.column()
769         sub.active = mat.use_cast_buffer_shadows
770         sub.prop(mat, "shadow_buffer_bias", text="Buffer Bias")
771         col.prop(mat, "use_ray_shadow_bias", text="Auto Ray Bias")
772         sub = col.column()
773         sub.active = (not mat.use_ray_shadow_bias)
774         sub.prop(mat, "shadow_ray_bias", text="Ray Bias")
775         if simple_material(base_mat):
776             col.prop(mat, "use_cast_approximate")
777
778
779 class MATERIAL_PT_transp_game(MaterialButtonsPanel, bpy.types.Panel):
780     bl_label = "Transparency"
781     bl_options = {'DEFAULT_CLOSED'}
782     COMPAT_ENGINES = {'BLENDER_GAME'}
783
784     @classmethod
785     def poll(cls, context):
786         mat = context.material
787         engine = context.scene.render.engine
788         return check_material(mat) and (engine in cls.COMPAT_ENGINES)
789
790     def draw_header(self, context):
791         mat = context.material
792
793         if simple_material(mat):
794             self.layout.prop(mat, "use_transparency", text="")
795
796     def draw(self, context):
797         layout = self.layout
798         base_mat = context.material
799         mat = active_node_mat(base_mat)
800
801         if simple_material(base_mat):
802             row = layout.row()
803             row.active = mat.use_transparency
804             row.prop(mat, "transparency_method", expand=True)
805
806         layout.prop(mat, "alpha")
807
808
809 class VolumeButtonsPanel():
810     bl_space_type = 'PROPERTIES'
811     bl_region_type = 'WINDOW'
812     bl_context = "material"
813     COMPAT_ENGINES = {'BLENDER_RENDER'}
814
815     @classmethod
816     def poll(cls, context):
817         mat = context.material
818         engine = context.scene.render.engine
819         return mat and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES)
820
821
822 class MATERIAL_PT_volume_density(VolumeButtonsPanel, bpy.types.Panel):
823     bl_label = "Density"
824     COMPAT_ENGINES = {'BLENDER_RENDER'}
825
826     def draw(self, context):
827         layout = self.layout
828
829         vol = context.material.volume  # dont use node material
830
831         row = layout.row()
832         row.prop(vol, "density")
833         row.prop(vol, "density_scale")
834
835
836 class MATERIAL_PT_volume_shading(VolumeButtonsPanel, bpy.types.Panel):
837     bl_label = "Shading"
838     COMPAT_ENGINES = {'BLENDER_RENDER'}
839
840     def draw(self, context):
841         layout = self.layout
842
843         vol = context.material.volume  # dont use node material
844
845         split = layout.split()
846
847         col = split.column()
848         col.prop(vol, "scattering")
849         col.prop(vol, "asymmetry")
850         col.prop(vol, "transmission_color")
851
852         col = split.column()
853         sub = col.column(align=True)
854         sub.prop(vol, "emission")
855         sub.prop(vol, "emission_color", text="")
856         sub = col.column(align=True)
857         sub.prop(vol, "reflection")
858         sub.prop(vol, "reflection_color", text="")
859
860
861 class MATERIAL_PT_volume_lighting(VolumeButtonsPanel, bpy.types.Panel):
862     bl_label = "Lighting"
863     COMPAT_ENGINES = {'BLENDER_RENDER'}
864
865     def draw(self, context):
866         layout = self.layout
867
868         vol = context.material.volume  # dont use node material
869
870         split = layout.split()
871
872         col = split.column()
873         col.prop(vol, "light_method", text="")
874
875         col = split.column()
876
877         if vol.light_method == 'SHADED':
878             col.prop(vol, "use_external_shadows")
879             col.prop(vol, "use_light_cache")
880             sub = col.column()
881             sub.active = vol.use_light_cache
882             sub.prop(vol, "cache_resolution")
883         elif vol.light_method in {'MULTIPLE_SCATTERING', 'SHADED_PLUS_MULTIPLE_SCATTERING'}:
884             sub = col.column()
885             sub.enabled = True
886             sub.active = False
887             sub.prop(vol, "use_light_cache")
888             col.prop(vol, "cache_resolution")
889
890             sub = col.column(align=True)
891             sub.prop(vol, "ms_diffusion")
892             sub.prop(vol, "ms_spread")
893             sub.prop(vol, "ms_intensity")
894
895
896 class MATERIAL_PT_volume_transp(VolumeButtonsPanel, bpy.types.Panel):
897     bl_label = "Transparency"
898     COMPAT_ENGINES = {'BLENDER_RENDER'}
899
900     @classmethod
901     def poll(cls, context):
902         mat = context.material
903         engine = context.scene.render.engine
904         return mat and simple_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES)
905
906     def draw(self, context):
907         layout = self.layout
908
909         mat = context.material  # dont use node material
910
911         layout.prop(mat, "transparency_method", expand=True)
912
913
914 class MATERIAL_PT_volume_integration(VolumeButtonsPanel, bpy.types.Panel):
915     bl_label = "Integration"
916     COMPAT_ENGINES = {'BLENDER_RENDER'}
917
918     def draw(self, context):
919         layout = self.layout
920
921         vol = context.material.volume  # dont use node material
922
923         split = layout.split()
924
925         col = split.column()
926         col.label(text="Step Calculation:")
927         col.prop(vol, "step_method", text="")
928         col = col.column(align=True)
929         col.prop(vol, "step_size")
930
931         col = split.column()
932         col.label()
933         col.prop(vol, "depth_threshold")
934
935
936 class MATERIAL_PT_volume_options(VolumeButtonsPanel, bpy.types.Panel):
937     bl_label = "Options"
938     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
939     bl_options = {'DEFAULT_CLOSED'}
940
941     @classmethod
942     def poll(cls, context):
943         mat = context.material
944         engine = context.scene.render.engine
945         return check_material(mat) and (mat.type == 'VOLUME') and (engine in cls.COMPAT_ENGINES)
946
947     def draw(self, context):
948         layout = self.layout
949
950         mat = active_node_mat(context.material)
951
952         split = layout.split()
953
954         col = split.column()
955         if simple_material(context.material):
956             col.prop(mat, "use_raytrace")
957             col.prop(mat, "use_full_oversampling")
958         col.prop(mat, "use_mist")
959
960         col = split.column()
961         col.label(text="Light Group:")
962         col.prop(mat, "light_group", text="")
963         row = col.row()
964         row.active = bool(mat.light_group)
965         row.prop(mat, "use_light_group_exclusive", text="Exclusive")
966
967
968 class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, bpy.types.Panel):
969     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
970     _context_path = "material"
971     _property_type = bpy.types.Material
972
973 if __name__ == "__main__":  # only for live edit.
974     bpy.utils.register_module(__name__)