Fix uilists showing data names translated (reported on bf-translations ML by Satoshi...
[blender.git] / release / scripts / startup / bl_ui / properties_texture.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, UIList
22
23 from bpy.types import (Brush,
24                        Lamp,
25                        Material,
26                        Object,
27                        ParticleSettings,
28                        Texture,
29                        World)
30
31 from rna_prop_ui import PropertyPanel
32
33 from bl_ui.properties_paint_common import brush_texture_settings
34
35
36 class TEXTURE_MT_specials(Menu):
37     bl_label = "Texture Specials"
38     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
39
40     def draw(self, context):
41         layout = self.layout
42
43         layout.operator("texture.slot_copy", icon='COPYDOWN')
44         layout.operator("texture.slot_paste", icon='PASTEDOWN')
45
46
47 class TEXTURE_MT_envmap_specials(Menu):
48     bl_label = "Environment Map Specials"
49     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
50
51     def draw(self, context):
52         layout = self.layout
53
54         layout.operator("texture.envmap_save", icon='IMAGEFILE')
55         layout.operator("texture.envmap_clear", icon='FILE_REFRESH')
56         layout.operator("texture.envmap_clear_all", icon='FILE_REFRESH')
57
58
59 class TEXTURE_UL_texslots(UIList):
60     def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
61         # assert(isinstance(item, bpy.types.MaterialTextureSlot)
62         ma = data
63         slot = item
64         tex = slot.texture if slot else None
65         if self.layout_type in {'DEFAULT', 'COMPACT'}:
66             layout.label(text=tex.name if tex else "", translate=False, icon_value=icon)
67             if tex and isinstance(item, bpy.types.MaterialTextureSlot):
68                 layout.prop(ma, "use_textures", text="", index=index)
69         elif self.layout_type in {'GRID'}:
70             layout.alignment = 'CENTER'
71             layout.label(text="", icon_value=icon)
72
73
74 from bl_ui.properties_material import active_node_mat
75
76
77 def context_tex_datablock(context):
78     idblock = context.material
79     if idblock:
80         return active_node_mat(idblock)
81
82     idblock = context.lamp
83     if idblock:
84         return idblock
85
86     idblock = context.world
87     if idblock:
88         return idblock
89
90     idblock = context.brush
91     if idblock:
92         return idblock
93
94     if context.particle_system:
95         idblock = context.particle_system.settings
96
97     return idblock
98
99
100 def id_tex_datablock(bid):
101     if isinstance(bid, Object):
102         if bid.type == 'LAMP':
103             return bid.data
104         return bid.active_material
105
106     return bid
107
108
109 class TextureButtonsPanel():
110     bl_space_type = 'PROPERTIES'
111     bl_region_type = 'WINDOW'
112     bl_context = "texture"
113
114     @classmethod
115     def poll(cls, context):
116         tex = context.texture
117         return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.scene.render.engine in cls.COMPAT_ENGINES)
118
119
120 class TEXTURE_PT_context_texture(TextureButtonsPanel, Panel):
121     bl_label = ""
122     bl_options = {'HIDE_HEADER'}
123     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
124
125     @classmethod
126     def poll(cls, context):
127         engine = context.scene.render.engine
128         if not (hasattr(context, "texture_slot") or hasattr(context, "texture_node")):
129             return False
130         return ((context.material or
131                  context.world or
132                  context.lamp or
133                  context.brush or
134                  context.texture or
135                  context.particle_system or
136                  isinstance(context.space_data.pin_id, ParticleSettings)) and
137                 (engine in cls.COMPAT_ENGINES))
138
139     def draw(self, context):
140         layout = self.layout
141
142         slot = getattr(context, "texture_slot", None)
143         node = getattr(context, "texture_node", None)
144         space = context.space_data
145         tex = context.texture
146         idblock = context_tex_datablock(context)
147         pin_id = space.pin_id
148
149         if space.use_pin_id and not isinstance(pin_id, Texture):
150             idblock = id_tex_datablock(pin_id)
151             pin_id = None
152
153         if not space.use_pin_id:
154             layout.prop(space, "texture_context", expand=True)
155
156         tex_collection = (pin_id is None) and (node is None) and (not isinstance(idblock, Brush))
157
158         if tex_collection:
159             row = layout.row()
160
161             row.template_list("TEXTURE_UL_texslots", "", idblock, "texture_slots", idblock, "active_texture_index", rows=2)
162
163             col = row.column(align=True)
164             col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
165             col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
166             col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
167
168         if tex_collection:
169             layout.template_ID(idblock, "active_texture", new="texture.new")
170         elif node:
171             layout.template_ID(node, "texture", new="texture.new")
172         elif idblock:
173             layout.template_ID(idblock, "texture", new="texture.new")
174
175         if pin_id:
176             layout.template_ID(space, "pin_id")
177
178         if tex:
179             split = layout.split(percentage=0.2)
180
181             if tex.use_nodes:
182
183                 if slot:
184                     split.label(text="Output:")
185                     split.prop(slot, "output_node", text="")
186
187             else:
188                 split.label(text="Type:")
189                 split.prop(tex, "type", text="")
190
191
192 class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
193     bl_label = "Preview"
194     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
195
196     def draw(self, context):
197         layout = self.layout
198
199         tex = context.texture
200         slot = getattr(context, "texture_slot", None)
201         idblock = context_tex_datablock(context)
202
203         if idblock:
204             layout.template_preview(tex, parent=idblock, slot=slot)
205         else:
206             layout.template_preview(tex, slot=slot)
207
208         #Show Alpha Button for Brush Textures, see #29502
209         if context.space_data.texture_context == 'BRUSH':
210             layout.prop(tex, "use_preview_alpha")
211
212
213 class TEXTURE_PT_colors(TextureButtonsPanel, Panel):
214     bl_label = "Colors"
215     bl_options = {'DEFAULT_CLOSED'}
216     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
217
218     def draw(self, context):
219         layout = self.layout
220
221         tex = context.texture
222
223         layout.prop(tex, "use_color_ramp", text="Ramp")
224         if tex.use_color_ramp:
225             layout.template_color_ramp(tex, "color_ramp", expand=True)
226
227         split = layout.split()
228
229         col = split.column()
230         col.label(text="RGB Multiply:")
231         sub = col.column(align=True)
232         sub.prop(tex, "factor_red", text="R")
233         sub.prop(tex, "factor_green", text="G")
234         sub.prop(tex, "factor_blue", text="B")
235
236         col = split.column()
237         col.label(text="Adjust:")
238         col.prop(tex, "intensity")
239         col.prop(tex, "contrast")
240         col.prop(tex, "saturation")
241
242 # Texture Slot Panels #
243
244
245 class TextureSlotPanel(TextureButtonsPanel):
246     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
247
248     @classmethod
249     def poll(cls, context):
250         if not hasattr(context, "texture_slot"):
251             return False
252
253         engine = context.scene.render.engine
254         return TextureButtonsPanel.poll(cls, context) and (engine in cls.COMPAT_ENGINES)
255
256
257 # Texture Type Panels #
258
259
260 class TextureTypePanel(TextureButtonsPanel):
261
262     @classmethod
263     def poll(cls, context):
264         tex = context.texture
265         engine = context.scene.render.engine
266         return tex and ((tex.type == cls.tex_type and not tex.use_nodes) and (engine in cls.COMPAT_ENGINES))
267
268
269 class TEXTURE_PT_clouds(TextureTypePanel, Panel):
270     bl_label = "Clouds"
271     tex_type = 'CLOUDS'
272     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
273
274     def draw(self, context):
275         layout = self.layout
276
277         tex = context.texture
278
279         layout.prop(tex, "cloud_type", expand=True)
280         layout.label(text="Noise:")
281         layout.prop(tex, "noise_type", text="Type", expand=True)
282         layout.prop(tex, "noise_basis", text="Basis")
283
284         split = layout.split()
285
286         col = split.column()
287         col.prop(tex, "noise_scale", text="Size")
288         col.prop(tex, "noise_depth", text="Depth")
289
290         split.prop(tex, "nabla", text="Nabla")
291
292
293 class TEXTURE_PT_wood(TextureTypePanel, Panel):
294     bl_label = "Wood"
295     tex_type = 'WOOD'
296     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
297
298     def draw(self, context):
299         layout = self.layout
300
301         tex = context.texture
302
303         layout.prop(tex, "noise_basis_2", expand=True)
304         layout.prop(tex, "wood_type", expand=True)
305
306         col = layout.column()
307         col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'}
308         col.label(text="Noise:")
309         col.row().prop(tex, "noise_type", text="Type", expand=True)
310         layout.prop(tex, "noise_basis", text="Basis")
311
312         split = layout.split()
313         split.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'}
314
315         col = split.column()
316         col.prop(tex, "noise_scale", text="Size")
317         col.prop(tex, "turbulence")
318
319         split.prop(tex, "nabla")
320
321
322 class TEXTURE_PT_marble(TextureTypePanel, Panel):
323     bl_label = "Marble"
324     tex_type = 'MARBLE'
325     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
326
327     def draw(self, context):
328         layout = self.layout
329
330         tex = context.texture
331
332         layout.prop(tex, "marble_type", expand=True)
333         layout.prop(tex, "noise_basis_2", expand=True)
334         layout.label(text="Noise:")
335         layout.prop(tex, "noise_type", text="Type", expand=True)
336         layout.prop(tex, "noise_basis", text="Basis")
337
338         split = layout.split()
339
340         col = split.column()
341         col.prop(tex, "noise_scale", text="Size")
342         col.prop(tex, "noise_depth", text="Depth")
343
344         col = split.column()
345         col.prop(tex, "turbulence")
346         col.prop(tex, "nabla")
347
348
349 class TEXTURE_PT_magic(TextureTypePanel, Panel):
350     bl_label = "Magic"
351     tex_type = 'MAGIC'
352     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
353
354     def draw(self, context):
355         layout = self.layout
356
357         tex = context.texture
358
359         row = layout.row()
360         row.prop(tex, "noise_depth", text="Depth")
361         row.prop(tex, "turbulence")
362
363
364 class TEXTURE_PT_blend(TextureTypePanel, Panel):
365     bl_label = "Blend"
366     tex_type = 'BLEND'
367     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
368
369     def draw(self, context):
370         layout = self.layout
371
372         tex = context.texture
373
374         layout.prop(tex, "progression")
375
376         sub = layout.row()
377
378         sub.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'})
379         sub.prop(tex, "use_flip_axis", expand=True)
380
381
382 class TEXTURE_PT_stucci(TextureTypePanel, Panel):
383     bl_label = "Stucci"
384     tex_type = 'STUCCI'
385     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
386
387     def draw(self, context):
388         layout = self.layout
389
390         tex = context.texture
391
392         layout.prop(tex, "stucci_type", expand=True)
393         layout.label(text="Noise:")
394         layout.prop(tex, "noise_type", text="Type", expand=True)
395         layout.prop(tex, "noise_basis", text="Basis")
396
397         row = layout.row()
398         row.prop(tex, "noise_scale", text="Size")
399         row.prop(tex, "turbulence")
400
401
402 class TEXTURE_PT_image(TextureTypePanel, Panel):
403     bl_label = "Image"
404     tex_type = 'IMAGE'
405     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
406
407     def draw(self, context):
408         layout = self.layout
409
410         tex = context.texture
411
412         layout.template_image(tex, "image", tex.image_user)
413
414
415 def texture_filter_common(tex, layout):
416     layout.label(text="Filter:")
417     layout.prop(tex, "filter_type", text="")
418     if tex.use_mipmap and tex.filter_type in {'AREA', 'EWA', 'FELINE'}:
419         if tex.filter_type == 'FELINE':
420             layout.prop(tex, "filter_probes", text="Probes")
421         else:
422             layout.prop(tex, "filter_eccentricity", text="Eccentricity")
423
424     layout.prop(tex, "filter_size")
425     layout.prop(tex, "use_filter_size_min")
426
427
428 class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
429     bl_label = "Image Sampling"
430     bl_options = {'DEFAULT_CLOSED'}
431     tex_type = 'IMAGE'
432     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
433
434     def draw(self, context):
435         if context.scene.render.engine == 'BLENDER_GAME':
436             self.draw_bge(context)
437         else:
438             self.draw_bi(context)
439
440     def draw_bi(self, context):
441         layout = self.layout
442
443         idblock = context_tex_datablock(context)
444         tex = context.texture
445         slot = getattr(context, "texture_slot", None)
446
447         split = layout.split()
448
449         col = split.column()
450         col.label(text="Alpha:")
451         col.prop(tex, "use_calculate_alpha", text="Calculate")
452         col.prop(tex, "invert_alpha", text="Invert")
453         col.separator()
454         col.prop(tex, "use_flip_axis", text="Flip X/Y Axis")
455
456         col = split.column()
457
458         #Only for Material based textures, not for Lamp/World...
459         if slot and isinstance(idblock, Material):
460             col.prop(tex, "use_normal_map")
461             row = col.row()
462             row.active = tex.use_normal_map
463             row.prop(slot, "normal_map_space", text="")
464
465             row = col.row()
466             row.active = not tex.use_normal_map
467             row.prop(tex, "use_derivative_map")
468
469         col.prop(tex, "use_mipmap")
470         row = col.row()
471         row.active = tex.use_mipmap
472         row.prop(tex, "use_mipmap_gauss")
473         col.prop(tex, "use_interpolation")
474
475         texture_filter_common(tex, col)
476
477     def draw_bge(self, context):
478         layout = self.layout
479
480         idblock = context_tex_datablock(context)
481         tex = context.texture
482         slot = getattr(context, "texture_slot", None)
483
484         split = layout.split()
485
486         col = split.column()
487         col.label(text="Alpha:")
488         col.prop(tex, "use_calculate_alpha", text="Calculate")
489         col.prop(tex, "invert_alpha", text="Invert")
490
491         col = split.column()
492
493         #Only for Material based textures, not for Lamp/World...
494         if slot and isinstance(idblock, Material):
495             col.prop(tex, "use_normal_map")
496             row = col.row()
497             row.active = tex.use_normal_map
498             row.prop(slot, "normal_map_space", text="")
499
500             row = col.row()
501             row.active = not tex.use_normal_map
502             row.prop(tex, "use_derivative_map")
503
504
505 class TEXTURE_PT_image_mapping(TextureTypePanel, Panel):
506     bl_label = "Image Mapping"
507     bl_options = {'DEFAULT_CLOSED'}
508     tex_type = 'IMAGE'
509     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
510
511     def draw(self, context):
512         layout = self.layout
513
514         tex = context.texture
515
516         layout.prop(tex, "extension")
517
518         split = layout.split()
519
520         if tex.extension == 'REPEAT':
521             col = split.column(align=True)
522             col.label(text="Repeat:")
523             col.prop(tex, "repeat_x", text="X")
524             col.prop(tex, "repeat_y", text="Y")
525
526             col = split.column(align=True)
527             col.label(text="Mirror:")
528             row = col.row()
529             row.prop(tex, "use_mirror_x", text="X")
530             row.active = (tex.repeat_x > 1)
531             row = col.row()
532             row.prop(tex, "use_mirror_y", text="Y")
533             row.active = (tex.repeat_y > 1)
534             layout.separator()
535
536         elif tex.extension == 'CHECKER':
537             col = split.column(align=True)
538             row = col.row()
539             row.prop(tex, "use_checker_even", text="Even")
540             row.prop(tex, "use_checker_odd", text="Odd")
541
542             col = split.column()
543             col.prop(tex, "checker_distance", text="Distance")
544
545             layout.separator()
546
547         split = layout.split()
548
549         col = split.column(align=True)
550         #col.prop(tex, "crop_rectangle")
551         col.label(text="Crop Minimum:")
552         col.prop(tex, "crop_min_x", text="X")
553         col.prop(tex, "crop_min_y", text="Y")
554
555         col = split.column(align=True)
556         col.label(text="Crop Maximum:")
557         col.prop(tex, "crop_max_x", text="X")
558         col.prop(tex, "crop_max_y", text="Y")
559
560
561 class TEXTURE_PT_envmap(TextureTypePanel, Panel):
562     bl_label = "Environment Map"
563     tex_type = 'ENVIRONMENT_MAP'
564     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
565
566     def draw(self, context):
567         layout = self.layout
568
569         tex = context.texture
570         env = tex.environment_map
571
572         row = layout.row()
573         row.prop(env, "source", expand=True)
574         row.menu("TEXTURE_MT_envmap_specials", icon='DOWNARROW_HLT', text="")
575
576         if env.source == 'IMAGE_FILE':
577             layout.template_ID(tex, "image", open="image.open")
578             layout.template_image(tex, "image", tex.image_user, compact=True)
579         else:
580             layout.prop(env, "mapping")
581             if env.mapping == 'PLANE':
582                 layout.prop(env, "zoom")
583             layout.prop(env, "viewpoint_object")
584
585             split = layout.split()
586
587             col = split.column()
588             col.prop(env, "layers_ignore")
589             col.prop(env, "resolution")
590             col.prop(env, "depth")
591
592             col = split.column(align=True)
593
594             col.label(text="Clipping:")
595             col.prop(env, "clip_start", text="Start")
596             col.prop(env, "clip_end", text="End")
597
598
599 class TEXTURE_PT_envmap_sampling(TextureTypePanel, Panel):
600     bl_label = "Environment Map Sampling"
601     bl_options = {'DEFAULT_CLOSED'}
602     tex_type = 'ENVIRONMENT_MAP'
603     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
604
605     def draw(self, context):
606         layout = self.layout
607
608         tex = context.texture
609
610         texture_filter_common(tex, layout)
611
612
613 class TEXTURE_PT_musgrave(TextureTypePanel, Panel):
614     bl_label = "Musgrave"
615     tex_type = 'MUSGRAVE'
616     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
617
618     def draw(self, context):
619         layout = self.layout
620
621         tex = context.texture
622
623         layout.prop(tex, "musgrave_type")
624
625         split = layout.split()
626
627         col = split.column()
628         col.prop(tex, "dimension_max", text="Dimension")
629         col.prop(tex, "lacunarity")
630         col.prop(tex, "octaves")
631
632         musgrave_type = tex.musgrave_type
633         col = split.column()
634         if musgrave_type in {'HETERO_TERRAIN', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}:
635             col.prop(tex, "offset")
636         if musgrave_type in {'MULTIFRACTAL', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}:
637             col.prop(tex, "noise_intensity", text="Intensity")
638         if musgrave_type in {'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}:
639             col.prop(tex, "gain")
640
641         layout.label(text="Noise:")
642
643         layout.prop(tex, "noise_basis", text="Basis")
644
645         row = layout.row()
646         row.prop(tex, "noise_scale", text="Size")
647         row.prop(tex, "nabla")
648
649
650 class TEXTURE_PT_voronoi(TextureTypePanel, Panel):
651     bl_label = "Voronoi"
652     tex_type = 'VORONOI'
653     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
654
655     def draw(self, context):
656         layout = self.layout
657
658         tex = context.texture
659
660         split = layout.split()
661
662         col = split.column()
663         col.label(text="Distance Metric:")
664         col.prop(tex, "distance_metric", text="")
665         sub = col.column()
666         sub.active = tex.distance_metric == 'MINKOVSKY'
667         sub.prop(tex, "minkovsky_exponent", text="Exponent")
668         col.label(text="Coloring:")
669         col.prop(tex, "color_mode", text="")
670         col.prop(tex, "noise_intensity", text="Intensity")
671
672         col = split.column()
673         sub = col.column(align=True)
674         sub.label(text="Feature Weights:")
675         sub.prop(tex, "weight_1", text="1", slider=True)
676         sub.prop(tex, "weight_2", text="2", slider=True)
677         sub.prop(tex, "weight_3", text="3", slider=True)
678         sub.prop(tex, "weight_4", text="4", slider=True)
679
680         layout.label(text="Noise:")
681         row = layout.row()
682         row.prop(tex, "noise_scale", text="Size")
683         row.prop(tex, "nabla")
684
685
686 class TEXTURE_PT_distortednoise(TextureTypePanel, Panel):
687     bl_label = "Distorted Noise"
688     tex_type = 'DISTORTED_NOISE'
689     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
690
691     def draw(self, context):
692         layout = self.layout
693
694         tex = context.texture
695
696         layout.prop(tex, "noise_distortion")
697         layout.prop(tex, "noise_basis", text="Basis")
698
699         split = layout.split()
700
701         col = split.column()
702         col.prop(tex, "distortion", text="Distortion")
703         col.prop(tex, "noise_scale", text="Size")
704
705         split.prop(tex, "nabla")
706
707
708 class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel):
709     bl_label = "Voxel Data"
710     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
711
712     @classmethod
713     def poll(cls, context):
714         tex = context.texture
715         engine = context.scene.render.engine
716         return tex and (tex.type == 'VOXEL_DATA' and (engine in cls.COMPAT_ENGINES))
717
718     def draw(self, context):
719         layout = self.layout
720
721         tex = context.texture
722         vd = tex.voxel_data
723
724         layout.prop(vd, "file_format")
725         if vd.file_format in {'BLENDER_VOXEL', 'RAW_8BIT'}:
726             layout.prop(vd, "filepath")
727         if vd.file_format == 'RAW_8BIT':
728             layout.prop(vd, "resolution")
729         elif vd.file_format == 'SMOKE':
730             layout.prop(vd, "domain_object")
731             layout.prop(vd, "smoke_data_type")
732         elif vd.file_format == 'IMAGE_SEQUENCE':
733             layout.template_ID(tex, "image", open="image.open")
734             layout.template_image(tex, "image", tex.image_user, compact=True)
735             #layout.prop(vd, "frame_duration")
736
737         if vd.file_format in {'BLENDER_VOXEL', 'RAW_8BIT'}:
738             layout.prop(vd, "use_still_frame")
739             row = layout.row()
740             row.active = vd.use_still_frame
741             row.prop(vd, "still_frame")
742
743         layout.prop(vd, "interpolation")
744         layout.prop(vd, "extension")
745         layout.prop(vd, "intensity")
746
747
748 class TEXTURE_PT_pointdensity(TextureButtonsPanel, Panel):
749     bl_label = "Point Density"
750     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
751
752     @classmethod
753     def poll(cls, context):
754         tex = context.texture
755         engine = context.scene.render.engine
756         return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES))
757
758     def draw(self, context):
759         layout = self.layout
760
761         tex = context.texture
762         pd = tex.point_density
763
764         layout.prop(pd, "point_source", expand=True)
765
766         split = layout.split()
767
768         col = split.column()
769         if pd.point_source == 'PARTICLE_SYSTEM':
770             col.label(text="Object:")
771             col.prop(pd, "object", text="")
772
773             sub = col.column()
774             sub.enabled = bool(pd.object)
775             if pd.object:
776                 sub.label(text="System:")
777                 sub.prop_search(pd, "particle_system", pd.object, "particle_systems", text="")
778             sub.label(text="Cache:")
779             sub.prop(pd, "particle_cache_space", text="")
780         else:
781             col.label(text="Object:")
782             col.prop(pd, "object", text="")
783             col.label(text="Cache:")
784             col.prop(pd, "vertex_cache_space", text="")
785
786         col.separator()
787
788         if pd.point_source == 'PARTICLE_SYSTEM':
789             col.label(text="Color Source:")
790             col.prop(pd, "color_source", text="")
791             if pd.color_source in {'PARTICLE_SPEED', 'PARTICLE_VELOCITY'}:
792                 col.prop(pd, "speed_scale")
793             if pd.color_source in {'PARTICLE_SPEED', 'PARTICLE_AGE'}:
794                 layout.template_color_ramp(pd, "color_ramp", expand=True)
795
796         col = split.column()
797         col.label()
798         col.prop(pd, "radius")
799         col.label(text="Falloff:")
800         col.prop(pd, "falloff", text="")
801         if pd.falloff == 'SOFT':
802             col.prop(pd, "falloff_soft")
803         if pd.falloff == 'PARTICLE_VELOCITY':
804             col.prop(pd, "falloff_speed_scale")
805
806         col.prop(pd, "use_falloff_curve")
807
808         if pd.use_falloff_curve:
809             col = layout.column()
810             col.label(text="Falloff Curve")
811             col.template_curve_mapping(pd, "falloff_curve", brush=False)
812
813
814 class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel):
815     bl_label = "Turbulence"
816     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
817
818     @classmethod
819     def poll(cls, context):
820         tex = context.texture
821         engine = context.scene.render.engine
822         return tex and (tex.type == 'POINT_DENSITY' and (engine in cls.COMPAT_ENGINES))
823
824     def draw_header(self, context):
825         pd = context.texture.point_density
826
827         self.layout.prop(pd, "use_turbulence", text="")
828
829     def draw(self, context):
830         layout = self.layout
831
832         tex = context.texture
833         pd = tex.point_density
834         layout.active = pd.use_turbulence
835
836         split = layout.split()
837
838         col = split.column()
839         col.label(text="Influence:")
840         col.prop(pd, "turbulence_influence", text="")
841         col.label(text="Noise Basis:")
842         col.prop(pd, "noise_basis", text="")
843
844         col = split.column()
845         col.label()
846         col.prop(pd, "turbulence_scale")
847         col.prop(pd, "turbulence_depth")
848         col.prop(pd, "turbulence_strength")
849
850
851 class TEXTURE_PT_ocean(TextureTypePanel, Panel):
852     bl_label = "Ocean"
853     tex_type = 'OCEAN'
854     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
855
856     def draw(self, context):
857         layout = self.layout
858
859         tex = context.texture
860         ot = tex.ocean
861
862         col = layout.column()
863         col.prop(ot, "ocean_object")
864         col.prop(ot, "output")
865
866
867 class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
868     bl_label = "Mapping"
869     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
870
871     @classmethod
872     def poll(cls, context):
873         idblock = context_tex_datablock(context)
874         if isinstance(idblock, Brush) and not context.sculpt_object:
875             return False
876
877         if not getattr(context, "texture_slot", None):
878             return False
879
880         engine = context.scene.render.engine
881         return (engine in cls.COMPAT_ENGINES)
882
883     def draw(self, context):
884         layout = self.layout
885
886         idblock = context_tex_datablock(context)
887
888         tex = context.texture_slot
889
890         if not isinstance(idblock, Brush):
891             split = layout.split(percentage=0.3)
892             col = split.column()
893             col.label(text="Coordinates:")
894             col = split.column()
895             col.prop(tex, "texture_coords", text="")
896
897             if tex.texture_coords == 'ORCO':
898                 """
899                 ob = context.object
900                 if ob and ob.type == 'MESH':
901                     split = layout.split(percentage=0.3)
902                     split.label(text="Mesh:")
903                     split.prop(ob.data, "texco_mesh", text="")
904                 """
905             elif tex.texture_coords == 'UV':
906                 split = layout.split(percentage=0.3)
907                 split.label(text="Map:")
908                 ob = context.object
909                 if ob and ob.type == 'MESH':
910                     split.prop_search(tex, "uv_layer", ob.data, "uv_textures", text="")
911                 else:
912                     split.prop(tex, "uv_layer", text="")
913
914             elif tex.texture_coords == 'OBJECT':
915                 split = layout.split(percentage=0.3)
916                 split.label(text="Object:")
917                 split.prop(tex, "object", text="")
918
919         if isinstance(idblock, Brush):
920             if context.sculpt_object or context.image_paint_object:
921                 brush_texture_settings(layout, idblock, context.sculpt_object)
922         else:
923             if isinstance(idblock, Material):
924                 split = layout.split(percentage=0.3)
925                 split.label(text="Projection:")
926                 split.prop(tex, "mapping", text="")
927
928                 split = layout.split()
929
930                 col = split.column()
931                 if tex.texture_coords in {'ORCO', 'UV'}:
932                     col.prop(tex, "use_from_dupli")
933                     if (idblock.type == 'VOLUME' and tex.texture_coords == 'ORCO'):
934                         col.prop(tex, "use_map_to_bounds")
935                 elif tex.texture_coords == 'OBJECT':
936                     col.prop(tex, "use_from_original")
937                     if (idblock.type == 'VOLUME'):
938                         col.prop(tex, "use_map_to_bounds")
939                 else:
940                     col.label()
941
942                 col = split.column()
943                 row = col.row()
944                 row.prop(tex, "mapping_x", text="")
945                 row.prop(tex, "mapping_y", text="")
946                 row.prop(tex, "mapping_z", text="")
947
948             row = layout.row()
949             row.column().prop(tex, "offset")
950             row.column().prop(tex, "scale")
951
952
953 class TEXTURE_PT_influence(TextureSlotPanel, Panel):
954     bl_label = "Influence"
955     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
956
957     @classmethod
958     def poll(cls, context):
959         idblock = context_tex_datablock(context)
960         if isinstance(idblock, Brush):
961             return False
962
963         if not getattr(context, "texture_slot", None):
964             return False
965
966         engine = context.scene.render.engine
967         return (engine in cls.COMPAT_ENGINES)
968
969     def draw(self, context):
970
971         layout = self.layout
972
973         idblock = context_tex_datablock(context)
974
975         tex = context.texture_slot
976
977         def factor_but(layout, toggle, factor, name):
978             row = layout.row(align=True)
979             row.prop(tex, toggle, text="")
980             sub = row.row()
981             sub.active = getattr(tex, toggle)
982             sub.prop(tex, factor, text=name, slider=True)
983             return sub  # XXX, temp. use_map_normal needs to override.
984
985         if isinstance(idblock, Material):
986             if idblock.type in {'SURFACE', 'WIRE'}:
987                 split = layout.split()
988
989                 col = split.column()
990                 col.label(text="Diffuse:")
991                 factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity")
992                 factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
993                 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
994                 factor_but(col, "use_map_translucency", "translucency_factor", "Translucency")
995
996                 col.label(text="Specular:")
997                 factor_but(col, "use_map_specular", "specular_factor", "Intensity")
998                 factor_but(col, "use_map_color_spec", "specular_color_factor", "Color")
999                 factor_but(col, "use_map_hardness", "hardness_factor", "Hardness")
1000
1001                 col = split.column()
1002                 col.label(text="Shading:")
1003                 factor_but(col, "use_map_ambient", "ambient_factor", "Ambient")
1004                 factor_but(col, "use_map_emit", "emit_factor", "Emit")
1005                 factor_but(col, "use_map_mirror", "mirror_factor", "Mirror")
1006                 factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror")
1007
1008                 col.label(text="Geometry:")
1009                 # XXX replace 'or' when displacement is fixed to not rely on normal influence value.
1010                 sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal")
1011                 sub_tmp.active = (tex.use_map_normal or tex.use_map_displacement)
1012                 # END XXX
1013
1014                 factor_but(col, "use_map_warp", "warp_factor", "Warp")
1015                 factor_but(col, "use_map_displacement", "displacement_factor", "Displace")
1016
1017                 #~ sub = col.column()
1018                 #~ sub.active = tex.use_map_translucency or tex.map_emit or tex.map_alpha or tex.map_raymir or tex.map_hardness or tex.map_ambient or tex.map_specularity or tex.map_reflection or tex.map_mirror
1019                 #~ sub.prop(tex, "default_value", text="Amount", slider=True)
1020             elif idblock.type == 'HALO':
1021                 layout.label(text="Halo:")
1022
1023                 split = layout.split()
1024
1025                 col = split.column()
1026                 factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
1027                 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
1028
1029                 col = split.column()
1030                 factor_but(col, "use_map_raymir", "raymir_factor", "Size")
1031                 factor_but(col, "use_map_hardness", "hardness_factor", "Hardness")
1032                 factor_but(col, "use_map_translucency", "translucency_factor", "Add")
1033             elif idblock.type == 'VOLUME':
1034                 split = layout.split()
1035
1036                 col = split.column()
1037                 factor_but(col, "use_map_density", "density_factor", "Density")
1038                 factor_but(col, "use_map_emission", "emission_factor", "Emission")
1039                 factor_but(col, "use_map_scatter", "scattering_factor", "Scattering")
1040                 factor_but(col, "use_map_reflect", "reflection_factor", "Reflection")
1041
1042                 col = split.column()
1043                 col.label(text=" ")
1044                 factor_but(col, "use_map_color_emission", "emission_color_factor", "Emission Color")
1045                 factor_but(col, "use_map_color_transmission", "transmission_color_factor", "Transmission Color")
1046                 factor_but(col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color")
1047
1048         elif isinstance(idblock, Lamp):
1049             split = layout.split()
1050
1051             col = split.column()
1052             factor_but(col, "use_map_color", "color_factor", "Color")
1053
1054             col = split.column()
1055             factor_but(col, "use_map_shadow", "shadow_factor", "Shadow")
1056
1057         elif isinstance(idblock, World):
1058             split = layout.split()
1059
1060             col = split.column()
1061             factor_but(col, "use_map_blend", "blend_factor", "Blend")
1062             factor_but(col, "use_map_horizon", "horizon_factor", "Horizon")
1063
1064             col = split.column()
1065             factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up")
1066             factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down")
1067         elif isinstance(idblock, ParticleSettings):
1068             split = layout.split()
1069
1070             col = split.column()
1071             col.label(text="General:")
1072             factor_but(col, "use_map_time", "time_factor", "Time")
1073             factor_but(col, "use_map_life", "life_factor", "Lifetime")
1074             factor_but(col, "use_map_density", "density_factor", "Density")
1075             factor_but(col, "use_map_size", "size_factor", "Size")
1076
1077             col = split.column()
1078             col.label(text="Physics:")
1079             factor_but(col, "use_map_velocity", "velocity_factor", "Velocity")
1080             factor_but(col, "use_map_damp", "damp_factor", "Damp")
1081             factor_but(col, "use_map_gravity", "gravity_factor", "Gravity")
1082             factor_but(col, "use_map_field", "field_factor", "Force Fields")
1083
1084             layout.label(text="Hair:")
1085
1086             split = layout.split()
1087
1088             col = split.column()
1089             factor_but(col, "use_map_length", "length_factor", "Length")
1090             factor_but(col, "use_map_clump", "clump_factor", "Clump")
1091
1092             col = split.column()
1093             factor_but(col, "use_map_kink", "kink_factor", "Kink")
1094             factor_but(col, "use_map_rough", "rough_factor", "Rough")
1095
1096         layout.separator()
1097
1098         if not isinstance(idblock, ParticleSettings):
1099             split = layout.split()
1100
1101             col = split.column()
1102             col.prop(tex, "blend_type", text="Blend")
1103             col.prop(tex, "use_rgb_to_intensity")
1104             # color is used on gray-scale textures even when use_rgb_to_intensity is disabled.
1105             col.prop(tex, "color", text="")
1106
1107             col = split.column()
1108             col.prop(tex, "invert", text="Negative")
1109             col.prop(tex, "use_stencil")
1110
1111         if isinstance(idblock, Material) or isinstance(idblock, World):
1112             col.prop(tex, "default_value", text="DVar", slider=True)
1113
1114         if isinstance(idblock, Material):
1115             layout.label(text="Bump Mapping:")
1116
1117             # only show bump settings if activated but not for normal-map images
1118             row = layout.row()
1119
1120             sub = row.row()
1121             sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and (tex.texture.use_normal_map or tex.texture.use_derivative_map))
1122             sub.prop(tex, "bump_method", text="Method")
1123
1124             # the space setting is supported for: derivative-maps + bump-maps (DEFAULT,BEST_QUALITY), not for normal-maps
1125             sub = row.row()
1126             sub.active = (tex.use_map_normal or tex.use_map_warp) and not (tex.texture.type == 'IMAGE' and tex.texture.use_normal_map) and ((tex.bump_method in {'BUMP_LOW_QUALITY', 'BUMP_MEDIUM_QUALITY', 'BUMP_BEST_QUALITY'}) or (tex.texture.type == 'IMAGE' and tex.texture.use_derivative_map))
1127             sub.prop(tex, "bump_objectspace", text="Space")
1128
1129
1130 class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel):
1131     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
1132     _context_path = "texture"
1133     _property_type = Texture
1134
1135 if __name__ == "__main__":  # only for live edit.
1136     bpy.utils.register_module(__name__)