Added options to use material colors (can be multiplied with vcol) Added wire option for UV Export type functionality. (implys no bleeding) Added Option to render with no oversampling changed alpha blending
238 lines
6.5 KiB
Python
Executable File
238 lines
6.5 KiB
Python
Executable File
#!BPY
|
|
"""
|
|
Name: 'Bake Image from UVs (vcol/img)'
|
|
Blender: 241
|
|
Group: 'UV'
|
|
Tooltip: 'Save the active or selected meshes meshes images, vertex colors or normals to an image.'
|
|
"""
|
|
__author__= ['Campbell Barton']
|
|
__url__= ('blender', 'elysiun', 'http://www.gametutorials.com')
|
|
__version__= '0.95'
|
|
__bpydoc__= '''\
|
|
|
|
Bake from UVs to image
|
|
|
|
This script makes an image from a meshes vertex colors, using the UV coordinates
|
|
to draw the faces into the image.
|
|
|
|
This makes it possible to bake radiosity into a texture.
|
|
Make sure your UV Coordinates do not overlap. LSCM Unwrapper or archimap unwrapper work well
|
|
to automaticaly do this.
|
|
'''
|
|
|
|
|
|
import Blender
|
|
import BPyRender
|
|
import BPyMesh
|
|
Vector= Blender.Mathutils.Vector
|
|
Create= Blender.Draw.Create
|
|
|
|
|
|
def vcol2image(me_s,\
|
|
PREF_IMAGE_PATH,\
|
|
PREF_IMAGE_SIZE,\
|
|
PREF_IMAGE_BLEED,\
|
|
PREF_IMAGE_SMOOTH,\
|
|
PREF_IMAGE_WIRE,\
|
|
PREF_USE_IMAGE,\
|
|
PREF_USE_VCOL,\
|
|
PREF_USE_MATCOL,\
|
|
PREF_USE_NORMAL):
|
|
|
|
|
|
def rnd_mat():
|
|
render_mat= Blender.Material.New()
|
|
mode= render_mat.mode
|
|
|
|
# Dont use lights ever
|
|
mode |= Blender.Material.Modes.SHADELESS
|
|
|
|
if PREF_IMAGE_WIRE:
|
|
mode |= Blender.Material.Modes.WIRE
|
|
if PREF_USE_VCOL or PREF_USE_MATCOL: # both vcol and material color use vertex cols to avoid the 16 max limit in materials
|
|
mode |= Blender.Material.Modes.VCOL_PAINT
|
|
if PREF_USE_IMAGE:
|
|
mode |= Blender.Material.Modes.TEXFACE
|
|
|
|
# Copy back the mode
|
|
render_mat.mode |= mode
|
|
return render_mat
|
|
|
|
|
|
BLEED_PIXEL= 1.0/PREF_IMAGE_SIZE
|
|
render_me= Blender.Mesh.New()
|
|
render_me.verts.extend( [Vector(0,0,0),] ) # 0 vert uv bugm dummy vert
|
|
|
|
|
|
for me in me_s:
|
|
|
|
# Multiple mesh support.
|
|
|
|
if PREF_USE_NORMAL:
|
|
BPyMesh.meshCalcNormals(me)
|
|
|
|
vert_offset= len(render_me.verts)
|
|
render_me.verts.extend( [ Vector(uv.x-BLEED_PIXEL, uv.y-BLEED_PIXEL/2, 0) for f in me.faces for uv in f.uv ] )
|
|
|
|
tmp_faces= []
|
|
for f in me.faces:
|
|
tmp_faces.append( [ii+vert_offset for ii in xrange(len(f))] )
|
|
vert_offset+= len(f)
|
|
|
|
face_offset= len(render_me.faces)
|
|
render_me.faces.extend(tmp_faces)
|
|
|
|
if PREF_USE_MATCOL:
|
|
materials= []
|
|
for mat in me.materials:
|
|
if mat==None:
|
|
materials.append((1.0, 1.0, 1.0)) # white
|
|
else:
|
|
materials.append(mat.rgbCol)
|
|
|
|
if not materials: # Well need a dummy material so the index works if we have no materials.
|
|
materials= [(1.0, 1.0, 1.0)]
|
|
|
|
for i, f in enumerate(me.faces):
|
|
frnd= render_me.faces[face_offset+i]
|
|
if PREF_USE_IMAGE:
|
|
ima= f.image
|
|
if ima:
|
|
frnd.image= ima
|
|
|
|
frnd.uv= f.uv
|
|
|
|
# Use normals excludes other color operations
|
|
if PREF_USE_NORMAL:
|
|
for ii, v in enumerate(f.v):
|
|
nx, ny, nz= v.no
|
|
c= frnd.col[ii]
|
|
# Modified to adjust from the current color
|
|
c.r= int((nx+1)*128)-1
|
|
c.g= int((ny+1)*128)-1
|
|
c.b= int((nz+1)*128)-1
|
|
else:
|
|
# Initialize color
|
|
if PREF_USE_VCOL:
|
|
frnd.col= f.col
|
|
|
|
# Mix with vert color
|
|
if PREF_USE_MATCOL:
|
|
# Multiply with existing color
|
|
r,g,b= materials[f.mat]
|
|
for col in frnd.col:
|
|
col.r= int(col.r*r)
|
|
col.g= int(col.g*g)
|
|
col.b= int(col.b*b)
|
|
|
|
elif PREF_USE_MATCOL: # Mat color only
|
|
# Multiply with existing color
|
|
r,g,b= materials[f.mat]
|
|
for col in frnd.col:
|
|
col.r= int(255*r)
|
|
col.g= int(255*g)
|
|
col.b= int(255*b)
|
|
|
|
render_ob= Blender.Object.New('Mesh')
|
|
render_ob.link(render_me)
|
|
obs= [render_ob]
|
|
|
|
# EVIL BLEEDING CODE!! - Just do copys of the mesh and place behind. Crufty but better then many other methods I have seen.
|
|
if PREF_IMAGE_BLEED and not PREF_IMAGE_WIRE:
|
|
z_offset= 0.0
|
|
for i in xrange(PREF_IMAGE_BLEED):
|
|
for diag1, diag2 in ((-1,-1),(-1,1),(1,-1),(1,1), (1,0), (0,1), (-1,0), (0, -1)): # This line extends the object in 8 different directions, top avoid bleeding.
|
|
|
|
render_ob= Blender.Object.New('Mesh')
|
|
render_ob.link(render_me)
|
|
|
|
render_ob.LocX= (i+1)*diag1*BLEED_PIXEL
|
|
render_ob.LocY= (i+1)*diag2*BLEED_PIXEL
|
|
render_ob.LocZ= -z_offset
|
|
|
|
obs.append(render_ob)
|
|
z_offset += 0.01
|
|
|
|
|
|
render_me.materials= [rnd_mat()]
|
|
im= BPyRender.imageFromObjectsOrtho(obs, PREF_IMAGE_PATH, PREF_IMAGE_SIZE, PREF_IMAGE_SIZE, PREF_IMAGE_SMOOTH)
|
|
|
|
# Clear from memory as best as we can
|
|
render_me.verts= None
|
|
|
|
|
|
|
|
|
|
def main():
|
|
# Create the variables.
|
|
# Filename without path or extension.
|
|
scn= Blender.Scene.GetCurrent()
|
|
act_ob= scn.getActiveObject()
|
|
obsel= [ob for ob in Blender.Object.GetSelected() if ob.getType()=='Mesh']
|
|
|
|
if not act_ob or act_ob.getType() != 'Mesh':
|
|
Blender.Draw.PupMenu('Error, no active mesh selected.')
|
|
return
|
|
|
|
|
|
newpath= Blender.Get('filename').split('/')[-1].split('\\')[-1].replace('.blend', '')
|
|
|
|
PREF_IMAGE_PATH = Create('//%s_grp' % newpath)
|
|
PREF_IMAGE_SIZE = Create(1024)
|
|
PREF_IMAGE_BLEED = Create(6)
|
|
PREF_IMAGE_SMOOTH= Create(1)
|
|
PREF_IMAGE_WIRE= Create(0)
|
|
|
|
PREF_USE_IMAGE = Create(1)
|
|
PREF_USE_VCOL = Create(1)
|
|
PREF_USE_MATCOL = Create(0)
|
|
PREF_USE_NORMAL = Create(0)
|
|
if len(obsel)>1: PREF_USE_MULIOB = Create(0)
|
|
|
|
pup_block = [\
|
|
'Image Path: (no ext)',\
|
|
('', PREF_IMAGE_PATH, 3, 100, 'Path to new Image. "//" for curent blend dir.'),\
|
|
'Image Options',
|
|
('Pixel Size:', PREF_IMAGE_SIZE, 64, 4096, 'Image Width and Height.'),\
|
|
('Pixel Bleed:', PREF_IMAGE_BLEED, 0, 64, 'Extend pixels from boundry edges to avoid mipmapping errors on rendering.'),\
|
|
('Smooth lines', PREF_IMAGE_SMOOTH, 'Render smooth lines.'),\
|
|
('Wire Only', PREF_IMAGE_WIRE, 'Renders a wireframe from the mesh, implys bleed is zero.'),\
|
|
|
|
'Color Source',\
|
|
('Image Texface', PREF_USE_IMAGE, 'Render the faces image in the output.'),\
|
|
('Vertex Colors', PREF_USE_VCOL, 'Use Normals instead of VCols.'),\
|
|
('Material Color', PREF_USE_MATCOL, 'Use the materials color.'),\
|
|
('Normal Map', PREF_USE_NORMAL, 'Use Normals instead of VCols.'),\
|
|
]
|
|
|
|
if len(obsel)>1:
|
|
pup_block.append('')
|
|
pup_block.append(('All Selected Meshes', PREF_USE_MULIOB, 'Use faces from all selcted meshes, Make sure UV coords dont overlap between objects.'))
|
|
|
|
|
|
if not Blender.Draw.PupBlock('VCol to Image', pup_block):
|
|
return
|
|
|
|
if not PREF_USE_MULIOB.val:
|
|
me_s= [act_ob.getData(mesh=1)]
|
|
else:
|
|
# Make double sure datas unique
|
|
me_s = dict([(ob.getData(name_only=1), ob.getData(mesh=1)) for ob in obsel]).values()
|
|
|
|
|
|
vcol2image(me_s,\
|
|
PREF_IMAGE_PATH.val,\
|
|
PREF_IMAGE_SIZE.val,\
|
|
PREF_IMAGE_BLEED.val,\
|
|
PREF_IMAGE_SMOOTH.val,\
|
|
PREF_IMAGE_WIRE.val,\
|
|
PREF_USE_IMAGE.val,\
|
|
PREF_USE_VCOL.val,\
|
|
PREF_USE_MATCOL.val,\
|
|
PREF_USE_NORMAL.val)
|
|
|
|
Blender.Window.RedrawAll()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|