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