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