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