import bpy
import bmesh
# this assumes you have copied the vertexAccumulator.py script
# into another text buffer named 'vertexAccumulator'
exec(bpy.data.texts['vertexAccumulator.py'].as_string())
def getAlpha(img, x, y):
w,h = img.size
if x<0 or x>= w or y<0 or y>=h:
return 0
o = x + y * w
return img.pixels[o*4+3]
def addFaceAndUV(verts, faces, uvs, va, width, height, uv_adj_x=0, uv_adj_y=0):
faces.append([ va.idxFor(v) for v in verts])
uvForFace = [ [(v[0]+uv_adj_x)/width, (v[1]+uv_adj_y)/height] for v in verts ]
uvs.append(uvForFace)
def addFaces(x, y, width, height, faces, img, uvs, va):
a = getAlpha(img, x, y)
if (a > 0):
addFaceAndUV([[x, y, 0],
[x + 1, y, 0],
[x + 1, y + 1, 0],
[x, y + 1, 0]], faces, uvs, va, width, height)
addFaceAndUV([ [x, y, -1],
[x, y + 1, -1],
[x + 1, y + 1, -1],
[x + 1, y, -1] ], faces, uvs, va, width, height)
if getAlpha(img, x - 1, y) <= 0:
addFaceAndUV([[x, y, 0],
[x, y +1, 0],
[x, y +1, -1],
[x, y, -1],], faces, uvs, va, width, height, 0.01, 0)
if getAlpha(img, x + 1, y) <= 0:
addFaceAndUV([[x + 1, y, 0],
[x + 1, y, -1],
[x + 1, y + 1, -1],
[x + 1, y + 1, 0],], faces, uvs, va, width, height, -0.01,0)
if getAlpha(img, x, y - 1) <= 0:
addFaceAndUV([[x, y, 0],
[x, y, -1],
[x + 1, y, -1],
[x + 1, y, 0],], faces, uvs, va, width, height, 0, 0.01)
if getAlpha(img, x, y +1) <= 0:
addFaceAndUV([[x, y + 1, 0],
[x + 1, y + 1, 0],
[x + 1, y + 1, -1],
[x, y + 1, -1],], faces, uvs, va, width, height, 0, -0.01)
def makeMeshForImage(img, name):
width,height = img.size
print (height)
va = VertexAccumulator()
faces = []
uvs = []
for y in range(height):
for x in range(width):
addFaces(x, y, width, height, faces, img, uvs, va)
mesh = bpy.data.meshes.new(name)
mesh.from_pydata(va.verts(), [] , faces)
apply_UVs(mesh, uvs)
set_preview_tex(mesh, img)
return mesh
def apply_UVs(mesh, uvs):
# add a UV layer called "spiral" and make it slanted.
mesh.uv_textures.new("simple")
bm = bmesh.new()
bm.from_mesh(mesh)
bm.faces.ensure_lookup_table()
uv_layer = bm.loops.layers.uv[0]
nFaces = len(bm.faces)
for fi in range(nFaces):
x0 = fi*2/nFaces
x1 = (fi+1)*2/nFaces
for j in range(len(uvs[fi])):
bm.faces[fi].loops[j][uv_layer].uv = uvs[fi][j]
bm.to_mesh(mesh)
# put the image behind the UV layer for the times when you're using the Multitexture shader on the 3D view.
def set_preview_tex(mesh, img):
bm = bmesh.new()
bm.from_mesh(mesh)
tl = bm.faces.layers.tex.active
if tl:
for f in bm.faces:
f[tl].image = img
bm.to_mesh(mesh)
def material_for(img):
rval = bpy.data.materials.get(img.name)
if rval is None:
tex = bpy.data.textures.new(img.name, 'IMAGE')
tex.image = img
tex.use_interpolation=False
tex.filter_type = 'BOX'
rval = bpy.data.materials.new(img.name)
rval.texture_slots.add()
rval.texture_slots[0].texture = tex
rval.texture_slots[0].texture_coords = 'UV'
rval.texture_slots[0].uv_layer = 'simple'
return rval
def makeObjForImage(img, name):
mesh = makeMeshForImage(img, name)
obj = bpy.data.objects.new(name, mesh)
w,h = img.size
obj.scale = [1.0/w, 1.0/h, 1.0/w]
mesh.materials.append(material_for(img))
return obj
img = bpy.data.images["sapling_jungle.png"]
obj = makeObjForImage(img, img.name)
scn = bpy.context.scene
scn.objects.link(obj)
scn.objects.active = obj
|
Blender python API quick-start
Syntax highlighting by Pygments.