Paste Code
Paste Blends
Paste Images
bl_info = {
"name": "Texture Paint Layer Manager",
"author": "Michael Wiliamson",
"version": (1, 0),
"blender": (2, 5, 7),
"location": "Texture Paint > Properties > Texture Paint Layers Panels",
"description": "Adds a layer manager for image based texture slots in paint and quick add layer tools",
"warning": "",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Texture_paint_layers",
"tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=26789",
"category": "Paint"}


import bpy
from bpy.props import*
import os
from bpy_extras.io_utils import ImportHelper


#-------------------------------------------

def load_a_brush(context, filepath):
if os.path.isdir(filepath):
return

else:

try:
fn = bpy.path.display_name_from_filepath(filepath)
#create image and load...
img = bpy.data.images.load(filepath)
img.use_fake_user =True

#create a texture
tex = bpy.data.textures.new(name =fn, type='IMAGE')
tex.use_fake_user =True
#tex.use_calculate_alpha = True

#link the img to the texture
tex.image = img

except:
print(f,'is not image?')

return {'FINISHED'}




class load_single_brush(bpy.types.Operator, ImportHelper):
''' Load an image as a brush texture'''
bl_idname = "texture.load_single_brush"
bl_label = "Load Image as Brush"


@classmethod
def poll(cls, context):
return context.active_object != None

def execute(self, context):
return load_a_brush(context, self.filepath)

#-------------------------------------------

def loadbrushes(context, filepath):
if os.path.isdir(filepath):
directory = filepath

else:
#is a file, find parent directory
li = filepath.split(os.sep)
directory = filepath.rstrip(li[-1])


files = os.listdir(directory)
for f in files:
try:
fn = f[3:]
#create image and load...
img = bpy.data.images.load(filepath = directory +os.sep + f)
img.use_fake_user =True

#create a texture
tex = bpy.data.textures.new(name =fn, type='IMAGE')
tex.use_fake_user =True
#tex.use_calculate_alpha = True

#link the img to the texture
tex.image = img

except:
print(f,'is not image?')
continue
return {'FINISHED'}




class ImportBrushes(bpy.types.Operator, ImportHelper):
''' Load a directory of images as brush textures '''
bl_idname = "texture.load_brushes"
bl_label = "Load brushes directory"


@classmethod
def poll(cls, context):
return context.active_object != None

def execute(self, context):
return loadbrushes(context, self.filepath)

#-------------------------------------------------------------------

class OBJECT_PT_LoadBrushes(bpy.types.Panel):
bl_label = "Load Brush images"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
#bl_context = "texturepaint"

@classmethod
def poll(cls, context):
return (context.sculpt_object or context.image_paint_object)

def draw(self, context):
layout = self.layout

layout.operator('texture.load_brushes')
layout.operator('texture.load_single_brush')


#======================================================================





class OBJECT_PT_Texture_paint_layers(bpy.types.Panel):
bl_label = "Texture Paint Layers"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
#bl_context = "texturepaint"

@classmethod
def poll(cls, context):
return (context.image_paint_object)

def draw(self, context):
layout = self.layout

ob = bpy.context.image_paint_object
if ob:
mat = ob.active_material
if not mat:
row = layout.row()
row.label(' Add a Material first!', icon = 'ERROR')
else:
row = layout.row()
row.template_list(ob, "material_slots", ob,
"active_material_index", rows=2 )



#list Paintable textures
#TODO add filter for channel type
i = -1
for t in mat.texture_slots:
i+=1
try:
if t.texture.type =='IMAGE':
row = layout.row(align= True)
if t.texture == mat.active_texture:
ai = 'BRUSH_DATA'
else:
ai = 'BLANK1'
row.operator('object.set_active_paint_layer',
text = "", icon = ai).tex_index =i
row.prop(t.texture,'name', text = "")


#Visibility
if t.use:
ic = 'RESTRICT_VIEW_OFF'
else:
ic = 'RESTRICT_VIEW_ON'
row.prop(t,'use', text = "",icon = ic)
except:
continue






ts = mat.texture_slots[mat.active_texture_index]

if ts:
row = layout.row()




col = layout.column(align =True)
col.label('Active Properties:', icon = 'BRUSH_DATA')

#use if rather than elif... can be mapped to multiple things
if ts.use_map_diffuse:
col.prop(ts,'diffuse_factor', slider = True)
if ts.use_map_color_diffuse:
col.prop(ts,'diffuse_color_factor', slider = True)
if ts.use_map_alpha:
col.prop(ts,'alpha_factor', slider = True)
if ts.use_map_translucency:
col.prop(ts,'translucency_factor', slider = True)
if ts.use_map_specular:
col.prop(ts,'specular_factor', slider = True)
if ts.use_map_color_spec:
col.prop(ts,'specular_color_factor', slider = True)
if ts.use_map_hardness:
col.prop(ts,'hardness_factor', slider = True)

if ts.use_map_normal:
col.prop(ts,'normal_factor', slider = True)
if ts.use_map_warp:
col.prop(ts,'warp_factor', slider = True)
if ts.use_map_displacement:
col.prop(ts,'displacement_factor', slider = True)

if ts.use_map_ambient:
col.prop(ts,'ambient_factor', slider = True)
if ts.use_map_emit:
col.prop(ts,'emit_factor', slider = True)
if ts.use_map_mirror:
col.prop(ts,'mirror_factor', slider = True)
if ts.use_map_raymir:
col.prop(ts,'raymir_factor', slider = True)


col.prop(ts,'blend_type',text='')

else:
row=layout.row()
row.label('No paint layers in material', icon = 'ERROR')

#
# row = layout.row()
# row.label('')
# row = layout.row()
# row.label('WIP: Use the X to delete!:')
# row = layout.row()
# row.template_ID(mat, "active_texture", new="texture.new")


class OBJECT_PT_Texture_paint_add(bpy.types.Panel):
bl_label = "Add Paint Layers"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
#bl_context = "texturepaint"

@classmethod
def poll(cls, context):
return (context.image_paint_object)

def draw(self, context):
layout = self.layout

ob = bpy.context.image_paint_object
if ob:
mat = ob.active_material

if mat:
col = layout.column(align =True)

col.operator('object.add_paint_layer',
text = "Add Color").ttype = 'COLOR'
col.operator('object.add_paint_layer',
text = "Add Bump").ttype = 'NORMAL'

col = layout.column(align =True)
col.operator('object.add_paint_layer',
text = "Add Specular").ttype = 'SPECULAR'
col.operator('object.add_paint_layer',
text = "Add Spec Col").ttype = 'SPEC_COL'
col.operator('object.add_paint_layer',
text = "Add Hardness").ttype = 'HARDNESS'

col = layout.column(align =True)
col.operator('object.add_paint_layer',
text = "Add Alpha").ttype = 'ALPHA'
col.operator('object.add_paint_layer',
text = "Add Translucency").ttype = 'TRANSLUCENCY'

# col = layout.column(align =True)
# col.operator('object.add_paint_layer',
# text = "Add Mirror").ttype = 'MIRROR'
# col.operator('object.add_paint_layer',
# text = "Add Ray Mirror").ttype = 'RAY_MIRROR'

col = layout.column(align =True)
col.operator('object.add_paint_layer',
text = "Add Emit").ttype = 'EMIT'
col.operator('object.add_paint_layer',
text = "Add Diffuse").ttype = 'DIFFUSE'
col.operator('object.add_paint_layer',
text = "Add Ambient").ttype = 'AMBIENT'

else:
layout.label(' Add a Material first!', icon = 'ERROR')



def main(context,tn):
#tn is the index of the texture in the active material
ob = context.active_object
me = ob.data
mat = ob.active_material
mat.active_texture_index = tn
ts = mat.texture_slots[tn]

#make sure it's visible
ts.use = True

#Mesh use UVs?
if not me.uv_textures:
bpy.ops.mesh.uv_texture_add()

# texture Slot uses UVs?
if ts.texture_coords == 'UV':
if ts.uv_layer:
uvtex = me.uv_textures[ts.uv_layer]

else:
uvtex = me.uv_textures.active
me.uv_textures.active= uvtex
else:
ts.texture_coords ='UV'
uvtex = me.uv_textures.active


uvtex = uvtex.data.values()


#get image from texture slot
img = ts.texture.image

#get material index
m_id = ob.active_material_index

if img:
for f in me.polygons:
if f.material_index == m_id:
uvtex[f.index].image = img
print('if')


else:
for f in me.polygons:
if f.material_index == m_id:
uvtex[f.index].image = None
print('else')
me.update()







class set_active_paint_layer(bpy.types.Operator):
''''''
bl_idname = "object.set_active_paint_layer"
bl_label = "set_active_paint_layer"
tex_index = IntProperty(name = 'tex_index',
description = "", default = 0)

@classmethod
def poll(cls, context):
return context.active_object != None

def execute(self, context):
tn = self.tex_index
main(context, tn)
return {'FINISHED'}



def add_image_kludge(iname = 'grey', iwidth = 256, iheight = 256,
icolor = (0.5,0.5,0.5,1.0)):
#evil kludge to get index of new image created using bpy.ops
#store current images
tl =[]
for i in bpy.data.images:
tl.append(i.name)


#create a new image

bpy.ops.image.new(name =iname,width =iwidth,height =iheight,
color = icolor)

#find its creation index
it = 0
for i in bpy.data.images:
if i.name not in tl:
return(bpy.data.images[it])
break
it += 1


def add_paint(context, size =2048, typ = 'NORMAL'):

ob = bpy.context.object
mat = ob.active_material
ts = mat.texture_slots.add()

if typ =='NORMAL':
color =(0.5,0.5,0.5,1.0)
iname = 'Bump'
elif typ =='COLOR':
iname ='Color'
color = (1.0,1.0,1.0,0.0)

elif typ =='ALPHA':
iname ='Alpha'
color = (1.0,1.0,1.0,0.0)
else:
color =(0.0,0.0,0.0,1.0)
iname = typ.capitalize()

# bn = bpy.context.blend_data.filepath.split(bpy.utils._os.sep)[-1]
# bn = bn.replace('.blend', '')
bn = ob.name

iname = bn +'_' + iname

tex = bpy.data.textures.new(name = iname, type = 'IMAGE')
ts.texture = tex
img = add_image_kludge(iname = typ,
iwidth = size,iheight = size, icolor= color )
tex.image = img

if typ == 'COLOR':
ts.use_map_color_diffuse =True


elif typ == 'NORMAL':
ts.use_map_normal = True
ts.use_map_color_diffuse =False
ts.normal_factor = -1
ts.bump_method='BUMP_DEFAULT'
ts.bump_objectspace='BUMP_OBJECTSPACE'

elif typ == 'SPECULAR':
ts.use_map_specular = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True
#ts.blend_type = 'MULTIPLY'

elif typ == 'EMIT':
ts.use_map_emit = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'ALPHA':
mat.use_transparency = True
ts.use_map_alpha = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True
ts.blend_type = 'MULTIPLY'

elif typ == 'SPEC_COL':
ts.use_map_color_spec = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'HARDNESS':
ts.use_map_hardness = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'DIFFUSE':
ts.use_map_diffuse = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'TRANSLUCENCY':
ts.use_map_translucency = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'AMBIENT':
ts.use_map_ambient = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'MIRROR':
ts.use_map_mirror = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

elif typ == 'RAY_MIRROR':
mat.raytrace_mirror.use = True
ts.use_map_ray_mirror = True
ts.use_map_color_diffuse =False
ts.use_rgb_to_intensity = True

#set new texture slot to active
i = 0
ts_index = None
for t in mat.texture_slots:
if t == ts:

ts_index = i
break
i += 1
if ts_index != None:
mat.active_texture_index = ts_index

#set the texfaces using this material.
main(context,ts_index)





class add_paint_layer(bpy.types.Operator):
''''''
bl_idname = "object.add_paint_layer"
bl_label = "Add Paint Layer"
ttype = StringProperty(name ='ttype',default ='NORMAL')

@classmethod
def poll(cls, context):
return context.active_object != None

def execute(self, context):
ttype = self.ttype
add_paint(context,typ= ttype)
return {'FINISHED'}




#----------------------------------------------
def save_painted(ts):
#generated images don't have a path
#so don't get saved with "save_dirty"
#ts is a texture slot object.

sep = bpy.utils._os.sep
if ts:
if ts.texture.type =='IMAGE':
i = ts.texture.image
if i.source =='GENERATED':
if i.is_dirty:
name = ts.name
if i.file_format =='PNG':
name = name + '.png'
elif i.file_format =='TARGA':
name = name +'.tga'

bpy.context.scene.render.image_settings.color_mode = 'RGBA'
fp =bpy.path.abspath('//textures' + sep + name)
try:
i.save_render(fp)
i.source = 'FILE'
if bpy.context.user_preferences.filepaths.use_relative_paths:
i.filepath = bpy.path.relpath(fp)
else:
i.filepath = fp
i.name = name
i.use_premultiply = True
except:
print("something wrong with", fp)
#THAT'S THE GENERATED FILES saved, pathed and reloaded
#now save other painted textures
bpy.ops.image.save_dirty()



def save_active_paint():
#for materials in current object
ob = bpy.context.object
for m in ob.material_slots:
for ts in m.material.texture_slots:
save_painted(ts)
return {'FINISHED'}

def save_all_paint():
#for all materials
for m in bpy.data.materials:
for ts in m.texture_slots:
save_painted(ts)
return {'FINISHED'}


class save_all_generated(bpy.types.Operator):
'''Saves painted layers to disc '''
bl_idname = "paint.save_all_generated"

bl_label = "SAVE PAINT LAYERS"


@classmethod
def poll(cls, context):
return context.active_object != None

def execute(self, context):
return save_active_paint()




#-----------------------------------
class OBJECT_PT_SavePainted(bpy.types.Panel):
bl_label = "Save All Painted"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
#bl_context = "texturepaint"

@classmethod
def poll(cls, context):
return (context.image_paint_object)

def draw(self, context):
self.layout.operator('paint.save_all_generated')

def register():
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
register()
  1. bl_info = {
  2.     "name": "Texture Paint Layer Manager",
  3.     "author": "Michael Wiliamson",
  4.     "version": (1, 0),
  5.     "blender": (2, 5, 7),
  6.     "location": "Texture Paint > Properties > Texture Paint Layers Panels",
  7.     "description": "Adds a layer manager for image based texture slots in paint and quick add layer tools",
  8.     "warning": "",
  9.     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Texture_paint_layers",
  10.     "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=26789",
  11.     "category": "Paint"}
  12.        
  13.        
  14. import bpy
  15. from bpy.props import*
  16. import os
  17. from bpy_extras.io_utils import ImportHelper
  18.  
  19.  
  20. #-------------------------------------------
  21.  
  22. def load_a_brush(context, filepath):
  23.     if os.path.isdir(filepath):
  24.         return
  25.        
  26.     else:
  27.  
  28.         try:
  29.             fn = bpy.path.display_name_from_filepath(filepath)
  30.             #create image and load...
  31.             img = bpy.data.images.load(filepath)
  32.             img.use_fake_user =True
  33.            
  34.             #create a texture
  35.             tex = bpy.data.textures.new(name =fn, type='IMAGE')
  36.             tex.use_fake_user =True
  37.             #tex.use_calculate_alpha = True
  38.            
  39.             #link the img to the texture
  40.             tex.image = img
  41.            
  42.         except:
  43.             print(f,'is not image?')
  44.  
  45.     return {'FINISHED'}
  46.  
  47.  
  48.  
  49.  
  50. class load_single_brush(bpy.types.Operator, ImportHelper):
  51.     ''' Load an image as a brush texture'''
  52.     bl_idname = "texture.load_single_brush"  
  53.     bl_label = "Load Image as Brush"
  54.  
  55.  
  56.     @classmethod
  57.     def poll(cls, context):
  58.         return context.active_object != None
  59.  
  60.     def execute(self, context):
  61.         return load_a_brush(context, self.filepath)
  62.  
  63. #-------------------------------------------
  64.  
  65. def loadbrushes(context, filepath):
  66.     if os.path.isdir(filepath):
  67.         directory = filepath
  68.        
  69.     else:
  70.         #is a file, find parent directory    
  71.         li = filepath.split(os.sep)
  72.         directory = filepath.rstrip(li[-1])
  73.        
  74.        
  75.     files = os.listdir(directory)
  76.     for f in files:
  77.         try:
  78.             fn = f[3:]
  79.             #create image and load...
  80.             img = bpy.data.images.load(filepath = directory +os.sep + f)
  81.             img.use_fake_user =True
  82.            
  83.             #create a texture
  84.             tex = bpy.data.textures.new(name =fn, type='IMAGE')
  85.             tex.use_fake_user =True
  86.             #tex.use_calculate_alpha = True
  87.            
  88.             #link the img to the texture
  89.             tex.image = img
  90.            
  91.         except:
  92.             print(f,'is not image?')
  93.             continue
  94.     return {'FINISHED'}
  95.  
  96.  
  97.  
  98.  
  99. class ImportBrushes(bpy.types.Operator, ImportHelper):
  100.     ''' Load a directory of images as brush textures '''
  101.     bl_idname = "texture.load_brushes"  
  102.     bl_label = "Load brushes directory"
  103.  
  104.  
  105.     @classmethod
  106.     def poll(cls, context):
  107.         return context.active_object != None
  108.  
  109.     def execute(self, context):
  110.         return loadbrushes(context, self.filepath)
  111.  
  112. #-------------------------------------------------------------------
  113.  
  114. class OBJECT_PT_LoadBrushes(bpy.types.Panel):
  115.     bl_label = "Load Brush images"
  116.     bl_space_type = "VIEW_3D"
  117.     bl_region_type = "TOOLS"
  118.     #bl_context = "texturepaint"
  119.    
  120.     @classmethod
  121.     def poll(cls, context):
  122.         return (context.sculpt_object or context.image_paint_object)
  123.    
  124.     def draw(self, context):
  125.         layout = self.layout
  126.  
  127.         layout.operator('texture.load_brushes')
  128.         layout.operator('texture.load_single_brush')
  129.  
  130.  
  131. #======================================================================
  132.  
  133.  
  134.  
  135.  
  136.  
  137. class OBJECT_PT_Texture_paint_layers(bpy.types.Panel):
  138.     bl_label = "Texture Paint Layers"
  139.     bl_space_type = "VIEW_3D"
  140.     bl_region_type = "UI"
  141.     #bl_context = "texturepaint"
  142.    
  143.     @classmethod
  144.     def poll(cls, context):
  145.         return (context.image_paint_object)
  146.    
  147.     def draw(self, context):
  148.         layout = self.layout
  149.  
  150.         ob = bpy.context.image_paint_object
  151.         if ob:
  152.             mat = ob.active_material
  153.             if not mat:
  154.                 row = layout.row()
  155.                 row.label(' Add a Material first!', icon = 'ERROR')
  156.             else:
  157.                 row = layout.row()        
  158.                 row.template_list(ob, "material_slots", ob,
  159.                     "active_material_index", rows=2 )
  160.                
  161.        
  162.                
  163.                 #list Paintable textures
  164.                 #TODO add filter for channel type
  165.                 i = -1
  166.                 for t in mat.texture_slots:
  167.                     i+=1
  168.                     try:
  169.                         if t.texture.type =='IMAGE':                
  170.                             row = layout.row(align= True)                
  171.                             if t.texture == mat.active_texture:
  172.                                 ai =  'BRUSH_DATA'
  173.                             else:
  174.                                 ai = 'BLANK1'
  175.                             row.operator('object.set_active_paint_layer',
  176.                                 text = "", icon = ai).tex_index =i  
  177.                             row.prop(t.texture,'name', text = "")
  178.            
  179.        
  180.                             #Visibility
  181.                             if t.use:
  182.                                 ic = 'RESTRICT_VIEW_OFF'
  183.                             else:
  184.                                 ic = 'RESTRICT_VIEW_ON'
  185.                             row.prop(t,'use', text = "",icon = ic)
  186.                     except:
  187.                         continue
  188.    
  189.            
  190.    
  191.  
  192.  
  193.            
  194.             ts = mat.texture_slots[mat.active_texture_index]
  195.    
  196.             if ts:
  197.                 row = layout.row()
  198.  
  199.    
  200.                
  201.                
  202.                 col = layout.column(align =True)
  203.                 col.label('Active Properties:', icon = 'BRUSH_DATA')
  204.                    
  205.                 #use if rather than elif... can be mapped to multiple things                                  
  206.                 if ts.use_map_diffuse:
  207.                     col.prop(ts,'diffuse_factor', slider = True)
  208.                 if ts.use_map_color_diffuse:
  209.                     col.prop(ts,'diffuse_color_factor', slider = True)
  210.                 if ts.use_map_alpha:
  211.                     col.prop(ts,'alpha_factor', slider = True)
  212.                 if ts.use_map_translucency:
  213.                     col.prop(ts,'translucency_factor', slider = True)
  214.                 if ts.use_map_specular:
  215.                     col.prop(ts,'specular_factor', slider = True)
  216.                 if ts.use_map_color_spec:
  217.                     col.prop(ts,'specular_color_factor', slider = True)
  218.                 if ts.use_map_hardness:
  219.                     col.prop(ts,'hardness_factor', slider = True)
  220.                    
  221.                 if ts.use_map_normal:
  222.                     col.prop(ts,'normal_factor', slider = True)
  223.                 if ts.use_map_warp:
  224.                     col.prop(ts,'warp_factor', slider = True)
  225.                 if ts.use_map_displacement:
  226.                     col.prop(ts,'displacement_factor', slider = True)  
  227.                    
  228.                 if ts.use_map_ambient:
  229.                     col.prop(ts,'ambient_factor', slider = True)              
  230.                 if ts.use_map_emit:
  231.                     col.prop(ts,'emit_factor', slider = True)                  
  232.                 if ts.use_map_mirror:
  233.                     col.prop(ts,'mirror_factor', slider = True)    
  234.                 if ts.use_map_raymir:
  235.                     col.prop(ts,'raymir_factor', slider = True)    
  236.                  
  237.                                    
  238.                 col.prop(ts,'blend_type',text='')  
  239.        
  240.             else:
  241.                 row=layout.row()
  242.                 row.label('No paint layers in material', icon = 'ERROR')        
  243.  
  244. #            
  245. #        row = layout.row()
  246. #        row.label('')              
  247. #        row = layout.row()
  248. #        row.label('WIP: Use the X to delete!:')                  
  249. #        row = layout.row()                
  250. #        row.template_ID(mat, "active_texture", new="texture.new")
  251.  
  252.  
  253. class OBJECT_PT_Texture_paint_add(bpy.types.Panel):
  254.     bl_label = "Add Paint Layers"
  255.     bl_space_type = "VIEW_3D"
  256.     bl_region_type = "UI"
  257.     #bl_context = "texturepaint"
  258.    
  259.     @classmethod
  260.     def poll(cls, context):
  261.         return (context.image_paint_object)
  262.  
  263.     def draw(self, context):
  264.         layout = self.layout
  265.  
  266.         ob = bpy.context.image_paint_object
  267.         if ob:
  268.             mat = ob.active_material
  269.            
  270.             if mat:  
  271.                 col = layout.column(align =True)
  272.        
  273.                 col.operator('object.add_paint_layer',
  274.                     text = "Add Color").ttype = 'COLOR'
  275.                 col.operator('object.add_paint_layer',
  276.                     text = "Add Bump").ttype = 'NORMAL'
  277.                    
  278.                 col = layout.column(align =True)
  279.                 col.operator('object.add_paint_layer',
  280.                     text = "Add Specular").ttype = 'SPECULAR'
  281.                 col.operator('object.add_paint_layer',
  282.                     text = "Add Spec Col").ttype = 'SPEC_COL'
  283.                 col.operator('object.add_paint_layer',
  284.                     text = "Add Hardness").ttype = 'HARDNESS'
  285.                    
  286.                 col = layout.column(align =True)    
  287.                 col.operator('object.add_paint_layer',
  288.                     text = "Add Alpha").ttype = 'ALPHA'
  289.                 col.operator('object.add_paint_layer',
  290.                     text = "Add Translucency").ttype = 'TRANSLUCENCY'
  291.                    
  292. #                col = layout.column(align =True)                      
  293. #                col.operator('object.add_paint_layer',
  294. #                    text = "Add Mirror").ttype = 'MIRROR'
  295. #                col.operator('object.add_paint_layer',
  296. #                    text = "Add Ray Mirror").ttype = 'RAY_MIRROR'  
  297.                    
  298.                 col = layout.column(align =True)                      
  299.                 col.operator('object.add_paint_layer',
  300.                     text = "Add Emit").ttype = 'EMIT'
  301.                 col.operator('object.add_paint_layer',
  302.                     text = "Add Diffuse").ttype = 'DIFFUSE'  
  303.                 col.operator('object.add_paint_layer',
  304.                     text = "Add Ambient").ttype = 'AMBIENT'
  305.                                        
  306.             else:
  307.                 layout.label(' Add a Material first!', icon = 'ERROR')
  308.        
  309.        
  310.  
  311. def main(context,tn):
  312.     #tn is the index of the texture in the active material
  313.     ob = context.active_object
  314.     me = ob.data
  315.     mat = ob.active_material
  316.     mat.active_texture_index = tn    
  317.     ts = mat.texture_slots[tn]
  318.  
  319.     #make sure it's visible
  320.     ts.use = True
  321.  
  322.     #Mesh use UVs?
  323.     if not me.uv_textures:
  324.         bpy.ops.mesh.uv_texture_add()
  325.        
  326.     # texture Slot uses UVs?
  327.     if ts.texture_coords  == 'UV':
  328.         if ts.uv_layer:
  329.             uvtex = me.uv_textures[ts.uv_layer]
  330.        
  331.         else:
  332.             uvtex = me.uv_textures.active
  333.             me.uv_textures.active= uvtex
  334.     else:
  335.         ts.texture_coords ='UV'
  336.         uvtex = me.uv_textures.active
  337.        
  338.        
  339.     uvtex = uvtex.data.values()
  340.    
  341.    
  342.     #get image from texture slot
  343.     img = ts.texture.image
  344.    
  345.     #get material index
  346.     m_id = ob.active_material_index
  347.  
  348.     if img:
  349.         for f in me.polygons:  
  350.             if f.material_index == m_id:
  351.                 uvtex[f.index].image = img
  352.         print('if')
  353.            
  354.  
  355.     else:
  356.         for f in me.polygons:  
  357.             if f.material_index == m_id:
  358.                 uvtex[f.index].image = None
  359.         print('else')
  360.     me.update()
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368. class set_active_paint_layer(bpy.types.Operator):
  369.     ''''''
  370.     bl_idname = "object.set_active_paint_layer"
  371.     bl_label = "set_active_paint_layer"
  372.     tex_index = IntProperty(name = 'tex_index',
  373.         description = "", default = 0)
  374.  
  375.     @classmethod
  376.     def poll(cls, context):
  377.         return context.active_object != None
  378.  
  379.     def execute(self, context):
  380.         tn = self.tex_index
  381.         main(context, tn)
  382.         return {'FINISHED'}
  383.  
  384.  
  385.  
  386. def add_image_kludge(iname = 'grey', iwidth = 256, iheight = 256,
  387.         icolor = (0.5,0.5,0.5,1.0)):
  388.     #evil kludge to get index of new image created using bpy.ops
  389.     #store current images
  390.     tl =[]
  391.     for i in bpy.data.images:
  392.         tl.append(i.name)
  393.    
  394.    
  395.     #create a new image
  396.  
  397.     bpy.ops.image.new(name =iname,width =iwidth,height =iheight,
  398.             color = icolor)
  399.        
  400.     #find its creation index
  401.     it = 0
  402.     for i in bpy.data.images:
  403.         if i.name not in tl:
  404.             return(bpy.data.images[it])
  405.             break
  406.         it += 1
  407.        
  408.    
  409. def add_paint(context, size =2048, typ = 'NORMAL'):
  410.    
  411.     ob = bpy.context.object
  412.     mat = ob.active_material
  413.     ts = mat.texture_slots.add()
  414.  
  415.     if typ =='NORMAL':
  416.         color =(0.5,0.5,0.5,1.0)
  417.         iname = 'Bump'
  418.     elif typ =='COLOR':
  419.         iname ='Color'
  420.         color = (1.0,1.0,1.0,0.0)
  421.  
  422.     elif typ =='ALPHA':
  423.         iname ='Alpha'
  424.         color = (1.0,1.0,1.0,0.0)                  
  425.     else:
  426.         color =(0.0,0.0,0.0,1.0)
  427.         iname = typ.capitalize()
  428.        
  429. #    bn = bpy.context.blend_data.filepath.split(bpy.utils._os.sep)[-1]
  430. #    bn = bn.replace('.blend', '')
  431.     bn = ob.name
  432.    
  433.     iname = bn +'_' + iname
  434.      
  435.     tex = bpy.data.textures.new(name = iname, type = 'IMAGE')
  436.     ts.texture = tex
  437.     img = add_image_kludge(iname = typ,
  438.         iwidth = size,iheight = size, icolor= color )
  439.     tex.image = img
  440.    
  441.     if typ == 'COLOR':
  442.         ts.use_map_color_diffuse =True
  443.  
  444.        
  445.     elif typ == 'NORMAL':
  446.         ts.use_map_normal = True
  447.         ts.use_map_color_diffuse =False
  448.         ts.normal_factor = -1
  449.         ts.bump_method='BUMP_DEFAULT'
  450.         ts.bump_objectspace='BUMP_OBJECTSPACE'
  451.        
  452.     elif typ == 'SPECULAR':
  453.         ts.use_map_specular = True
  454.         ts.use_map_color_diffuse =False
  455.         ts.use_rgb_to_intensity = True
  456.         #ts.blend_type = 'MULTIPLY'
  457.        
  458.     elif typ == 'EMIT':
  459.         ts.use_map_emit = True
  460.         ts.use_map_color_diffuse =False
  461.         ts.use_rgb_to_intensity = True
  462.        
  463.     elif typ == 'ALPHA':
  464.         mat.use_transparency = True
  465.         ts.use_map_alpha = True
  466.         ts.use_map_color_diffuse =False
  467.         ts.use_rgb_to_intensity = True
  468.         ts.blend_type = 'MULTIPLY'
  469.        
  470.     elif typ == 'SPEC_COL':
  471.         ts.use_map_color_spec = True
  472.         ts.use_map_color_diffuse =False
  473.         ts.use_rgb_to_intensity = True
  474.        
  475.     elif typ == 'HARDNESS':
  476.         ts.use_map_hardness = True
  477.         ts.use_map_color_diffuse =False
  478.         ts.use_rgb_to_intensity = True        
  479.        
  480.     elif typ == 'DIFFUSE':
  481.         ts.use_map_diffuse = True
  482.         ts.use_map_color_diffuse =False
  483.         ts.use_rgb_to_intensity = True        
  484.  
  485.     elif typ == 'TRANSLUCENCY':
  486.         ts.use_map_translucency = True
  487.         ts.use_map_color_diffuse =False
  488.         ts.use_rgb_to_intensity = True
  489.  
  490.     elif typ == 'AMBIENT':
  491.         ts.use_map_ambient = True
  492.         ts.use_map_color_diffuse =False
  493.         ts.use_rgb_to_intensity = True
  494.          
  495.     elif typ == 'MIRROR':
  496.         ts.use_map_mirror = True
  497.         ts.use_map_color_diffuse =False
  498.         ts.use_rgb_to_intensity = True
  499.                        
  500.     elif typ == 'RAY_MIRROR':
  501.         mat.raytrace_mirror.use = True
  502.         ts.use_map_ray_mirror = True
  503.         ts.use_map_color_diffuse =False
  504.         ts.use_rgb_to_intensity = True
  505.                                                
  506.     #set new texture slot to active
  507.     i = 0
  508.     ts_index = None
  509.     for t in mat.texture_slots:
  510.         if t == ts:
  511.            
  512.             ts_index = i
  513.             break
  514.         i += 1
  515.     if ts_index != None:
  516.         mat.active_texture_index = ts_index
  517.    
  518.     #set the texfaces using this material.
  519.         main(context,ts_index)
  520.    
  521.    
  522.    
  523.    
  524.  
  525. class add_paint_layer(bpy.types.Operator):
  526.     ''''''
  527.     bl_idname = "object.add_paint_layer"
  528.     bl_label = "Add Paint Layer"
  529.     ttype = StringProperty(name ='ttype',default ='NORMAL')
  530.    
  531.     @classmethod
  532.     def poll(cls, context):
  533.         return context.active_object != None
  534.  
  535.     def execute(self, context):
  536.         ttype = self.ttype
  537.         add_paint(context,typ= ttype)
  538.         return {'FINISHED'}
  539.        
  540.  
  541.  
  542.  
  543. #----------------------------------------------
  544. def save_painted(ts):
  545.     #generated images don't  have a path
  546.     #so don't get saved with "save_dirty"
  547.     #ts is a texture slot object.
  548.    
  549.     sep = bpy.utils._os.sep
  550.     if ts:
  551.         if ts.texture.type =='IMAGE':
  552.             i = ts.texture.image
  553.             if i.source =='GENERATED':
  554.                 if i.is_dirty:
  555.                     name = ts.name
  556.                     if i.file_format =='PNG':
  557.                         name = name + '.png'
  558.                     elif i.file_format =='TARGA':  
  559.                         name = name +'.tga'
  560.                        
  561.                     bpy.context.scene.render.image_settings.color_mode = 'RGBA'                          
  562.                     fp =bpy.path.abspath('//textures' + sep + name)
  563.                     try:
  564.                         i.save_render(fp)
  565.                         i.source = 'FILE'
  566.                         if bpy.context.user_preferences.filepaths.use_relative_paths:
  567.                             i.filepath = bpy.path.relpath(fp)
  568.                         else:
  569.                             i.filepath = fp
  570.                         i.name = name
  571.                         i.use_premultiply = True
  572.                     except:
  573.                         print("something wrong with", fp)
  574.     #THAT'S THE GENERATED FILES saved, pathed and reloaded
  575.     #now save other painted textures
  576.     bpy.ops.image.save_dirty()
  577.  
  578.  
  579.  
  580. def save_active_paint():
  581.     #for materials in current object
  582.     ob = bpy.context.object
  583.     for m in ob.material_slots:
  584.         for ts in m.material.texture_slots:
  585.             save_painted(ts)
  586.     return {'FINISHED'}                          
  587.  
  588. def save_all_paint():
  589.     #for all materials
  590.     for m in bpy.data.materials:
  591.         for ts in m.texture_slots:
  592.             save_painted(ts)      
  593.     return {'FINISHED'}  
  594.            
  595.            
  596. class save_all_generated(bpy.types.Operator):
  597.     '''Saves painted layers to disc '''
  598.     bl_idname = "paint.save_all_generated"
  599.      
  600.     bl_label = "SAVE PAINT LAYERS"
  601.  
  602.  
  603.     @classmethod
  604.     def poll(cls, context):
  605.         return context.active_object != None
  606.  
  607.     def execute(self, context):
  608.         return save_active_paint()
  609.  
  610.  
  611.  
  612.  
  613. #-----------------------------------
  614. class OBJECT_PT_SavePainted(bpy.types.Panel):
  615.     bl_label = "Save All Painted"
  616.     bl_space_type = "VIEW_3D"
  617.     bl_region_type = "UI"
  618.     #bl_context = "texturepaint"
  619.    
  620.     @classmethod
  621.     def poll(cls, context):
  622.         return (context.image_paint_object)
  623.    
  624.     def draw(self, context):
  625.         self.layout.operator('paint.save_all_generated')        
  626.        
  627. def register():
  628.     bpy.utils.register_module(__name__)
  629.  
  630. def unregister():
  631.     bpy.utils.unregister_module(__name__)
  632.  
  633. if __name__ == "__main__":
  634.     register()
go to heaven