remove use of gettext: _("...") style translation now its handled by rna.
[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 bl_ui.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_mapping(TextureSlotPanel, Panel):
778     bl_label = "Mapping"
779     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
780
781     @classmethod
782     def poll(cls, context):
783         idblock = context_tex_datablock(context)
784         if isinstance(idblock, bpy.types.Brush) and not context.sculpt_object:
785             return False
786
787         if not getattr(context, "texture_slot", None):
788             return False
789
790         engine = context.scene.render.engine
791         return (engine in cls.COMPAT_ENGINES)
792
793     def draw(self, context):
794         layout = self.layout
795
796         idblock = context_tex_datablock(context)
797
798         tex = context.texture_slot
799         # textype = context.texture
800
801         if not isinstance(idblock, bpy.types.Brush):
802             split = layout.split(percentage=0.3)
803             col = split.column()
804             col.label(text="Coordinates:")
805             col = split.column()
806             col.prop(tex, "texture_coords", text="")
807
808             if tex.texture_coords == 'ORCO':
809                 """
810                 ob = context.object
811                 if ob and ob.type == 'MESH':
812                     split = layout.split(percentage=0.3)
813                     split.label(text="Mesh:")
814                     split.prop(ob.data, "texco_mesh", text="")
815                 """
816             elif tex.texture_coords == 'UV':
817                 split = layout.split(percentage=0.3)
818                 split.label(text="Layer:")
819                 ob = context.object
820                 if ob and ob.type == 'MESH':
821                     split.prop_search(tex, "uv_layer", ob.data, "uv_textures", text="")
822                 else:
823                     split.prop(tex, "uv_layer", text="")
824
825             elif tex.texture_coords == 'OBJECT':
826                 split = layout.split(percentage=0.3)
827                 split.label(text="Object:")
828                 split.prop(tex, "object", text="")
829
830         if isinstance(idblock, bpy.types.Brush):
831             if context.sculpt_object:
832                 layout.label(text="Brush Mapping:")
833                 layout.prop(tex, "map_mode", expand=True)
834
835                 row = layout.row()
836                 row.active = tex.map_mode in {'FIXED', 'TILED'}
837                 row.prop(tex, "angle")
838         else:
839             if isinstance(idblock, bpy.types.Material):
840                 split = layout.split(percentage=0.3)
841                 split.label(text="Projection:")
842                 split.prop(tex, "mapping", text="")
843
844                 split = layout.split()
845
846                 col = split.column()
847                 if tex.texture_coords in {'ORCO', 'UV'}:
848                     col.prop(tex, "use_from_dupli")
849                 elif tex.texture_coords == 'OBJECT':
850                     col.prop(tex, "use_from_original")
851                 else:
852                     col.label()
853
854                 col = split.column()
855                 row = col.row()
856                 row.prop(tex, "mapping_x", text="")
857                 row.prop(tex, "mapping_y", text="")
858                 row.prop(tex, "mapping_z", text="")
859
860         row = layout.row()
861         row.column().prop(tex, "offset")
862         row.column().prop(tex, "scale")
863
864
865 class TEXTURE_PT_influence(TextureSlotPanel, Panel):
866     bl_label = "Influence"
867     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
868
869     @classmethod
870     def poll(cls, context):
871         idblock = context_tex_datablock(context)
872         if isinstance(idblock, bpy.types.Brush):
873             return False
874
875         if not getattr(context, "texture_slot", None):
876             return False
877
878         engine = context.scene.render.engine
879         return (engine in cls.COMPAT_ENGINES)
880
881     def draw(self, context):
882
883         layout = self.layout
884
885         idblock = context_tex_datablock(context)
886
887         # textype = context.texture
888         tex = context.texture_slot
889
890         def factor_but(layout, toggle, factor, name):
891             row = layout.row(align=True)
892             row.prop(tex, toggle, text="")
893             sub = row.row()
894             sub.active = getattr(tex, toggle)
895             sub.prop(tex, factor, text=name, slider=True)
896             return sub  # XXX, temp. use_map_normal needs to override.
897
898         if isinstance(idblock, bpy.types.Material):
899             if idblock.type in {'SURFACE', 'WIRE'}:
900                 split = layout.split()
901
902                 col = split.column()
903                 col.label(text="Diffuse:")
904                 factor_but(col, "use_map_diffuse", "diffuse_factor", "Intensity")
905                 factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
906                 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
907                 factor_but(col, "use_map_translucency", "translucency_factor", "Translucency")
908
909                 col.label(text="Specular:")
910                 factor_but(col, "use_map_specular", "specular_factor", "Intensity")
911                 factor_but(col, "use_map_color_spec", "specular_color_factor", "Color")
912                 factor_but(col, "use_map_hardness", "hardness_factor", "Hardness")
913
914                 col = split.column()
915                 col.label(text="Shading:")
916                 factor_but(col, "use_map_ambient", "ambient_factor", "Ambient")
917                 factor_but(col, "use_map_emit", "emit_factor", "Emit")
918                 factor_but(col, "use_map_mirror", "mirror_factor", "Mirror")
919                 factor_but(col, "use_map_raymir", "raymir_factor", "Ray Mirror")
920
921                 col.label(text="Geometry:")
922                 # XXX replace 'or' when displacement is fixed to not rely on normal influence value.
923                 sub_tmp = factor_but(col, "use_map_normal", "normal_factor", "Normal")
924                 sub_tmp.active = (tex.use_map_normal or tex.use_map_displacement)
925                 # END XXX
926
927                 factor_but(col, "use_map_warp", "warp_factor", "Warp")
928                 factor_but(col, "use_map_displacement", "displacement_factor", "Displace")
929
930                 #sub = col.column()
931                 #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
932                 #sub.prop(tex, "default_value", text="Amount", slider=True)
933             elif idblock.type == 'HALO':
934                 layout.label(text="Halo:")
935
936                 split = layout.split()
937
938                 col = split.column()
939                 factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
940                 factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
941
942                 col = split.column()
943                 factor_but(col, "use_map_raymir", "raymir_factor", "Size")
944                 factor_but(col, "use_map_hardness", "hardness_factor", "Hardness")
945                 factor_but(col, "use_map_translucency", "translucency_factor", "Add")
946             elif idblock.type == 'VOLUME':
947                 split = layout.split()
948
949                 col = split.column()
950                 factor_but(col, "use_map_density", "density_factor", "Density")
951                 factor_but(col, "use_map_emission", "emission_factor", "Emission")
952                 factor_but(col, "use_map_scatter", "scattering_factor", "Scattering")
953                 factor_but(col, "use_map_reflect", "reflection_factor", "Reflection")
954
955                 col = split.column()
956                 col.label(text=" ")
957                 factor_but(col, "use_map_color_emission", "emission_color_factor", "Emission Color")
958                 factor_but(col, "use_map_color_transmission", "transmission_color_factor", "Transmission Color")
959                 factor_but(col, "use_map_color_reflection", "reflection_color_factor", "Reflection Color")
960
961         elif isinstance(idblock, bpy.types.Lamp):
962             split = layout.split()
963
964             col = split.column()
965             factor_but(col, "use_map_color", "color_factor", "Color")
966
967             col = split.column()
968             factor_but(col, "use_map_shadow", "shadow_factor", "Shadow")
969
970         elif isinstance(idblock, bpy.types.World):
971             split = layout.split()
972
973             col = split.column()
974             factor_but(col, "use_map_blend", "blend_factor", "Blend")
975             factor_but(col, "use_map_horizon", "horizon_factor", "Horizon")
976
977             col = split.column()
978             factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up")
979             factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down")
980         elif isinstance(idblock, bpy.types.ParticleSettings):
981             split = layout.split()
982
983             col = split.column()
984             col.label(text="General:")
985             factor_but(col, "use_map_time", "time_factor", "Time")
986             factor_but(col, "use_map_life", "life_factor", "Lifetime")
987             factor_but(col, "use_map_density", "density_factor", "Density")
988             factor_but(col, "use_map_size", "size_factor", "Size")
989
990             col = split.column()
991             col.label(text="Physics:")
992             factor_but(col, "use_map_velocity", "velocity_factor", "Velocity")
993             factor_but(col, "use_map_damp", "damp_factor", "Damp")
994             factor_but(col, "use_map_gravity", "gravity_factor", "Gravity")
995             factor_but(col, "use_map_field", "field_factor", "Force Fields")
996
997             layout.label(text="Hair:")
998
999             split = layout.split()
1000
1001             col = split.column()
1002             factor_but(col, "use_map_length", "length_factor", "Length")
1003             factor_but(col, "use_map_clump", "clump_factor", "Clump")
1004
1005             col = split.column()
1006             factor_but(col, "use_map_kink", "kink_factor", "Kink")
1007             factor_but(col, "use_map_rough", "rough_factor", "Rough")
1008
1009         layout.separator()
1010
1011         if not isinstance(idblock, bpy.types.ParticleSettings):
1012             split = layout.split()
1013
1014             col = split.column()
1015             col.prop(tex, "blend_type", text="Blend")
1016             col.prop(tex, "use_rgb_to_intensity")
1017             # color is used on grayscale textures even when use_rgb_to_intensity is disabled.
1018             col.prop(tex, "color", text="")
1019
1020             col = split.column()
1021             col.prop(tex, "invert", text="Negative")
1022             col.prop(tex, "use_stencil")
1023
1024         if isinstance(idblock, bpy.types.Material) or isinstance(idblock, bpy.types.World):
1025             col.prop(tex, "default_value", text="DVar", slider=True)
1026
1027         if isinstance(idblock, bpy.types.Material):
1028             layout.label(text="Bump Mapping:")
1029
1030             # only show bump settings if activated but not for normalmap images
1031             row = layout.row()
1032
1033             sub = row.row()
1034             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))
1035             sub.prop(tex, "bump_method", text="Method")
1036
1037             # the space setting is supported for: derivmaps + bumpmaps (DEFAULT,BEST_QUALITY), not for normalmaps
1038             sub = row.row()
1039             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))
1040             sub.prop(tex, "bump_objectspace", text="Space")
1041
1042
1043 class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel):
1044     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
1045     _context_path = "texture"
1046     _property_type = bpy.types.Texture
1047
1048 if __name__ == "__main__":  # only for live edit.
1049     bpy.utils.register_module(__name__)