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