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