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