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