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