Created
January 22, 2017 17:39
-
-
Save kythyria/9accae4f6239808293046734c4e660e6 to your computer and use it in GitHub Desktop.
Blender reader for SL sculpts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import bmesh | |
import bmesh.ops | |
import bpy | |
import bpy.ops | |
import itertools | |
def chunks(l, n): | |
return [l[i:i+n] for i in range(0, len(l), n)] | |
def sculpt_mesh_from_coords_wiki_64(data, name, sculpttype, mirror, invert): | |
if mirror: | |
invert = not invert | |
template = list(itertools.chain(range(0,64,2), [63])) | |
# [[(x,y,u,v), ...], ...] | |
coordinates = [] | |
for v,y in enumerate(template): | |
row = [] | |
for u,x in enumerate(template): | |
row.append((x,y,u,v)) | |
coordinates.append(row) | |
if sculpttype == "SPHERE": | |
row = coordinates[0] | |
for i, v in enumerate(row): | |
row[i] = (32, v[1], v[2], v[3]) | |
row = coordinates[len(coordinates) - 1] | |
for i, v in enumerate(row): | |
row[i] = (32, v[1], v[2], v[3]) | |
if sculpttype == "CYLINDER" or sculpttype == "TORUS" or sculpttype == "SPHERE": | |
for i, row in enumerate(coordinates): | |
v = row[32] | |
row[32] = (0, v[1], v[2], v[3]) | |
if sculpttype == "TORUS": | |
for i, v in enumerate(coordinates[31]): | |
coordinates[32][i] = (v[0], 0, v[2], v[3]) | |
me = bpy.data.meshes.new(name) | |
me.uv_textures.new("UVMap") | |
bm = bmesh.new() | |
bm.from_mesh(me) | |
uv_layer = bm.loops.layers.uv[0] | |
vertices = [] | |
vcache = {} | |
for row in coordinates: | |
vr = [] | |
for c in row: | |
if mirror: | |
px = data[c[1]][63 - c[0]] | |
else: | |
px = data[c[1]][c[0]] | |
pos = (px[0] - 0.5, px[1] - 0.5, px[2] - 0.5) | |
xy = c[0:2] | |
existing = vcache.get(xy) | |
if existing != None: | |
vr.append(existing) | |
else: | |
v = bm.verts.new(pos) | |
vr.append(v) | |
vcache[xy] = v | |
vertices.append(vr) | |
def get_verts(coll,x,y): | |
a = coll[y][x] | |
b = coll[y][x+1] | |
c = coll[y+1][x] | |
d = coll[y+1][x+1] | |
return a,b,c,d | |
def set_face_uv(face, vertex, uv): | |
loops = [l for l in face.loops if l.vert == vertex] | |
if len(loops) == 0: | |
return | |
loop = loops[0] | |
u = uv[0] / 32 | |
v = uv[1] / 32 | |
loop[uv_layer].uv = (u,v) | |
for y, row in enumerate(coordinates): | |
if y == len(coordinates) - 1: | |
break | |
for x, c in enumerate(row): | |
if x == len(row) - 1: | |
break | |
# | |
# p1---p2 | |
# | | | |
# | | | |
# p3---p4 | |
c1, c2, c3, c4 = get_verts(coordinates, x, y) | |
p1, p2, p3, p4 = get_verts(vertices, x, y) | |
if invert: | |
face = bm.faces.new(dedup((p1,p3,p4,p2))) | |
else: | |
face = bm.faces.new(dedup((p1,p2,p4,p3))) | |
face.smooth = True | |
set_face_uv(face, p1, c1[2:4]) | |
set_face_uv(face, p2, c2[2:4]) | |
set_face_uv(face, p3, c3[2:4]) | |
set_face_uv(face, p4, c4[2:4]) | |
#for vrow, crow in zip(vertices,coordinates): | |
# for vert, c in zip(vrow,crow): | |
# u = c[2] / 32 | |
# v = c[3] / 32 | |
# for loop in vert.link_loops: | |
# loop[uv_layer].uv = (u,v) | |
bm.to_mesh(me) | |
me.update() | |
return me | |
def sculpt_mesh_from_file(name, stype, imagepath, mirror, invert): | |
oname = name | |
if mirror or invert: | |
oname = name + "." | |
if mirror: | |
oname += "m" | |
if invert: | |
oname += "i" | |
idx = bpy.data.meshes.find(oname) | |
if idx != -1: | |
mdata = bpy.data.meshes[idx] | |
else: | |
image = bpy.data.images.load(imagepath) | |
pxlist = chunks(chunks(image.pixels, 4),64) | |
mdata = sculpt_mesh_from_coords_wiki_64(pxlist, oname, stype, mirror, invert) | |
return mdata | |
def sculpt_from_file(name, sculpt_type, imagepath, mirror, invert): | |
me = sculpt_mesh_from_file(name, stype, fn, mirror, invert) | |
ob = bpy.data.objects.new(name, me) | |
bpy.context.scene.objects.link(ob) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment