Created
March 18, 2011 07:22
-
-
Save z0w0/875726 to your computer and use it in GitHub Desktop.
A python program for converting a Blockland save file (.bls) to a 3d wavefront model (.obj). @blockland.us
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 sys,decimal,os,math,Image | |
def convert(input,output,offset,angle,brickName,color): | |
global posCount,uvCount,normalCount,posCache,uvCache,normalCache,brickCache,currentTex | |
try: | |
input = open(input,"r") | |
lines = input.readlines() | |
input.close() | |
except: | |
return | |
offset = str(str(decimal.Decimal(offset[0]) * 2) + " " + str(decimal.Decimal(offset[1]) * 2) + " " + str(decimal.Decimal(offset[2]) * decimal.Decimal("1.668"))).split() | |
linecount = -1 | |
for line in lines: | |
linecount = linecount + 1 | |
if len(line) >= 4: | |
if line[0:4] == "TEX:" and len(lines)-linecount >= 15: | |
if currentTex != line[4:].strip() + "_" + str(color) and line[4:].strip() != "PRINT": | |
currentTex = line[4:].strip() + "_" + str(color) | |
output.write("usemtl " + currentTex + "\n") | |
if lines[linecount+1][0:9].strip() == "POSITION:": | |
lines[linecount+2] = lines[linecount+2].strip().split() | |
arrayone = [str(decimal.Decimal(lines[linecount+2][0]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(lines[linecount+2][1]) + decimal.Decimal(offset[1])) + " " + str((decimal.Decimal(lines[linecount+2][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(lines[linecount+2][1]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+2][0])) + " " + str((decimal.Decimal(lines[linecount+2][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+2][0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+2][1])) + " " + str((decimal.Decimal(lines[linecount+2][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+2][1])) + " " + str(decimal.Decimal(offset[1]) + decimal.Decimal(lines[linecount+2][0])) + " " + str((decimal.Decimal(lines[linecount+2][2]) / 3) + decimal.Decimal(offset[2]))] | |
lines[linecount+2] = arrayone[angle] | |
posOne = posCount + 1 | |
posOneAdd = 1 | |
if lines[linecount+2] in posCache: | |
posOneAdd = 0 | |
posOne = posCache[lines[linecount+2]] | |
else: | |
output.write("v " + lines[linecount+2] + "\n") | |
posCache[lines[linecount+2]] = posOne | |
lines[linecount+3] = lines[linecount+3].strip().split() | |
arraytwo = [str(decimal.Decimal(lines[linecount+3][0]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(lines[linecount+3][1]) + decimal.Decimal(offset[1])) + " " + str((decimal.Decimal(lines[linecount+3][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(lines[linecount+3][1]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+3][0])) + " " + str((decimal.Decimal(lines[linecount+3][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+3][0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+3][1])) + " " + str((decimal.Decimal(lines[linecount+3][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+3][1])) + " " + str(decimal.Decimal(offset[1]) + decimal.Decimal(lines[linecount+3][0])) + " " + str((decimal.Decimal(lines[linecount+3][2]) / 3) + decimal.Decimal(offset[2]))] | |
lines[linecount+3] = arraytwo[angle] | |
posTwo = posCount + (1 + posOneAdd) | |
posTwoAdd = 1 | |
if lines[linecount+3] in posCache: | |
posTwoAdd = 0 | |
posTwo = posCache[lines[linecount+3]] | |
else: | |
output.write("v " + lines[linecount+3] + "\n") | |
posCache[lines[linecount+3]] = posTwo | |
lines[linecount+4] = lines[linecount+4].strip().split() | |
arraythree = [str(decimal.Decimal(lines[linecount+4][0]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(lines[linecount+4][1]) + decimal.Decimal(offset[1])) + " " + str((decimal.Decimal(lines[linecount+4][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(lines[linecount+4][1]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+4][0])) + " " + str((decimal.Decimal(lines[linecount+4][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+4][0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+4][1])) + " " + str((decimal.Decimal(lines[linecount+4][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+4][1])) + " " + str(decimal.Decimal(offset[1]) + decimal.Decimal(lines[linecount+4][0])) + " " + str((decimal.Decimal(lines[linecount+4][2]) / 3) + decimal.Decimal(offset[2]))] | |
lines[linecount+4] = arraythree[angle] | |
posThree = posCount + (1 + posOneAdd + posTwoAdd) | |
posThreeAdd = 1 | |
if lines[linecount+4] in posCache: | |
posThreeAdd = 0 | |
posThree = posCache[lines[linecount+4]] | |
else: | |
output.write("v " + lines[linecount+4] + "\n") | |
posCache[lines[linecount+4]] = posThree | |
lines[linecount+5] = lines[linecount+5].strip().split() | |
arrayfour = [str(decimal.Decimal(lines[linecount+5][0]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(lines[linecount+5][1]) + decimal.Decimal(offset[1])) + " " + str((decimal.Decimal(lines[linecount+5][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(lines[linecount+5][1]) + decimal.Decimal(offset[0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+5][0])) + " " + str((decimal.Decimal(lines[linecount+5][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+5][0])) + " " + str(decimal.Decimal(offset[1]) - decimal.Decimal(lines[linecount+5][1])) + " " + str((decimal.Decimal(lines[linecount+5][2]) / 3) + decimal.Decimal(offset[2])), | |
str(decimal.Decimal(offset[0]) - decimal.Decimal(lines[linecount+5][1])) + " " + str(decimal.Decimal(offset[1]) + decimal.Decimal(lines[linecount+5][0])) + " " + str((decimal.Decimal(lines[linecount+5][2]) / 3) + decimal.Decimal(offset[2]))] | |
lines[linecount+5] = arrayfour[angle] | |
posFour = posCount + (1 + posOneAdd + posTwoAdd + posThreeAdd) | |
posFourAdd = 1 | |
if lines[linecount+5] in posCache: | |
posFourAdd = 0 | |
posFour = posCache[lines[linecount+5]] | |
else: | |
output.write("v " + lines[linecount+5] + "\n") | |
posCache[lines[linecount+5]] = posFour | |
posCount = posCount + (posOneAdd + posTwoAdd + posThreeAdd + posFourAdd) | |
if lines[linecount+6][0:10].strip() == "UV COORDS:": | |
uvOne = uvCount + 1 | |
uvOneAdd = 1 | |
if lines[linecount+7].strip() in uvCache: | |
uvOneAdd = 0 | |
uvOne = uvCache[lines[linecount+7].strip()] | |
else: | |
output.write("vt " + lines[linecount+7].strip() + "\n") | |
uvCache[lines[linecount+7].strip()] = uvOne | |
uvTwo = uvCount + (1 + uvOneAdd) | |
uvTwoAdd = 1 | |
if lines[linecount+8].strip() in uvCache: | |
uvTwoAdd = 0 | |
uvTwo = uvCache[lines[linecount+8].strip()] | |
else: | |
output.write("vt " + lines[linecount+8].strip() + "\n") | |
uvCache[lines[linecount+8].strip()] = uvTwo | |
uvThree = uvCount + (1 + uvOneAdd + uvTwoAdd) | |
uvThreeAdd = 1 | |
if lines[linecount+9].strip() in uvCache: | |
uvThreeAdd = 0 | |
uvThree = uvCache[lines[linecount+9].strip()] | |
else: | |
output.write("vt " + lines[linecount+9].strip() + "\n") | |
uvCache[lines[linecount+9].strip()] = uvThree | |
uvFour = uvCount + (1 + uvOneAdd + uvTwoAdd + uvThreeAdd) | |
uvFourAdd = 1 | |
if lines[linecount+10].strip() in uvCache: | |
uvFourAdd = 0 | |
uvFour = uvCache[lines[linecount+10].strip()] | |
else: | |
output.write("vt " + lines[linecount+10].strip() + "\n") | |
uvCache[lines[linecount+10].strip()] = uvFour | |
uvCount = uvCount + (uvOneAdd + uvTwoAdd + uvThreeAdd + uvFourAdd) | |
if lines[linecount+11][0:8].strip() == "NORMALS:": | |
normalOne = normalCount + 1 | |
normalOneAdd = 1 | |
if lines[linecount+12].strip() in normalCache: | |
normalOneAdd = 0 | |
normalOne = normalCache[lines[linecount+12].strip()] | |
else: | |
output.write("vn " + lines[linecount+12].strip() + "\n") | |
normalCache[lines[linecount+12].strip()] = normalOne | |
normalTwo = normalCount + (1 + normalOneAdd) | |
normalTwoAdd = 1 | |
if lines[linecount+13].strip() in normalCache: | |
normalTwoAdd = 0 | |
normalTwo = normalCache[lines[linecount+13].strip()] | |
else: | |
output.write("vn " + lines[linecount+13].strip() + "\n") | |
normalCache[lines[linecount+13].strip()] = normalTwo | |
normalThree = normalCount + (1 + normalOneAdd + normalTwoAdd) | |
normalThreeAdd = 1 | |
if lines[linecount+14].strip() in normalCache: | |
normalThreeAdd = 0 | |
normalThree = normalCache[lines[linecount+14].strip()] | |
else: | |
output.write("vn " + lines[linecount+14].strip() + "\n") | |
normalCache[lines[linecount+14].strip()] = normalThree | |
normalFour = normalCount + (1 + normalOneAdd + normalTwoAdd + normalThreeAdd) | |
normalFourAdd = 1 | |
if lines[linecount+15].strip() in normalCache: | |
normalFourAdd = 0 | |
normalFour = normalCache[lines[linecount+15].strip()] | |
else: | |
output.write("vn " + lines[linecount+15].strip() + "\n") | |
normalCache[lines[linecount+15].strip()] = normalFour | |
normalCount = normalCount + (normalOneAdd + normalTwoAdd + normalThreeAdd + normalFourAdd) | |
try: | |
output.write("f " + str(posOne) + "/" + str(uvOne) + "/" + str(normalOne) + " " + str(posTwo) + "/" + str(uvTwo) + "/" + str(normalTwo) + " " + str(posThree) + "/" + str(uvThree) + "/" + str(normalThree) + " " + str(posFour) + "/" + str(uvFour) + "/" + str(normalFour) + "\n") | |
except: | |
continue | |
if len(sys.argv) > 1: | |
try: | |
print "Converting..." | |
try: | |
runningDirectory = os.path.abspath(os.path.dirname(sys.argv[0])) + "\\" | |
outputDirectory = os.path.abspath(os.path.dirname(sys.argv[0])) + "\\" + os.path.basename(sys.argv[1][0:sys.argv[1].find(".")]) + "\\" | |
if not os.path.isdir(outputDirectory): | |
os.mkdir(outputDirectory) | |
except: | |
sys.exit() | |
posCount = 0 | |
uvCount = 0 | |
normalCount = 0 | |
posCache = {} | |
uvCache = {} | |
normalCache = {} | |
brickCache = {} | |
currentTex = "" | |
input = open(sys.argv[1],"r") | |
lines = input.readlines() | |
input.close() | |
output = open(outputDirectory + os.path.basename(sys.argv[1]).replace(".bls","") + ".obj","w") | |
material = open(outputDirectory + os.path.basename(sys.argv[1]).replace(".bls","") + ".mtl","w") | |
outputtedMaterial = 0 | |
currentLine = 0 | |
percent = 0 | |
output.write("#Exported by BLSOBJ (zack0wack0.com)\nmtllib " + os.path.basename(sys.argv[1]).replace(".bls","") + ".mtl\n") | |
colorCount = -1 | |
colorLoaded = {} | |
for line in lines: | |
currentLine = currentLine + 1 | |
pos = line.find("\"") | |
if pos > -1 and line.find("+-") == -1: | |
brick = line[0:pos] | |
line = line[pos+2:] | |
file = os.path.abspath(os.path.dirname(sys.argv[0])) + "\library\\" + brick + ".blb" | |
if os.path.isfile(file): | |
line = line.strip().split() | |
if line[10] == "0": | |
continue | |
if colorLoaded[int(line[5])] == 0: | |
continue | |
convert(file,output,line[0:3],int(line[3]),brick,int(line[5])) | |
if decimal.Decimal(str(percent + 1)) < decimal.Decimal(str(math.floor((decimal.Decimal(str(currentLine)) / len(lines)) * 100))): | |
percent = percent + 1 | |
print str(percent) + "%" | |
continue | |
else: | |
print "No such brick in the library: " + file | |
elif line.find("Linecount ") > -1: | |
outputtedMaterial = 1 | |
material.close() | |
elif not outputtedMaterial: | |
color = line.split() | |
if len(color) == 4: | |
colorCount = colorCount + 1 | |
colorIndex = str(colorCount) | |
if decimal.Decimal(color[3]) == 0: | |
colorLoaded[colorCount] = 0 | |
continue | |
colorDataIndex = -1 | |
for colorData in color: | |
colorDataIndex = colorDataIndex + 1 | |
test = decimal.Decimal(colorData) | |
if test <= 1: | |
color[colorDataIndex] = str(test * 255) | |
colorLoaded[colorCount] = 1 | |
print "Generating a material for the color " + str(colorCount + 1) + " on the colorset..." | |
colorTop = Image.new("RGB",(512,512),(decimal.Decimal(color[0]),decimal.Decimal(color[1]),decimal.Decimal(color[2]))) | |
colorTop = Image.blend(colorTop,Image.open(runningDirectory + "brickTOP.png"),0.25) | |
colorTop.save(outputDirectory + "TOP_" + colorIndex + ".png",bits=24) | |
colorBottomLoop = Image.new("RGB",(512,512),(decimal.Decimal(color[0]),decimal.Decimal(color[1]),decimal.Decimal(color[2]))) | |
colorBottomLoop = Image.blend(colorBottomLoop,Image.open(runningDirectory + "brickBOTTOMLOOP.png"),0.25) | |
colorBottomLoop.save(outputDirectory + "BOTTOMLOOP_" + colorIndex + ".png",bits=24) | |
colorBottomEdge = Image.new("RGB",(512,512),(decimal.Decimal(color[0]),decimal.Decimal(color[1]),decimal.Decimal(color[2]))) | |
colorBottomEdge = Image.blend(colorBottomEdge,Image.open(runningDirectory + "brickBOTTOMEDGE.png"),0.25) | |
colorBottomEdge.save(outputDirectory + "BOTTOMEDGE_" + colorIndex + ".png",bits=24) | |
colorSide = Image.new("RGB",(512,512),(decimal.Decimal(color[0]),decimal.Decimal(color[1]),decimal.Decimal(color[2]))) | |
colorSide = Image.blend(colorSide,Image.open(runningDirectory + "brickSIDE.png"),0.25) | |
colorSide.save(outputDirectory + "SIDE_" + colorIndex + ".png",bits=24) | |
colorRamp = Image.new("RGB",(512,512),(decimal.Decimal(color[0]),decimal.Decimal(color[1]),decimal.Decimal(color[2]))) | |
colorRamp = Image.blend(colorRamp,Image.open(runningDirectory + "brickRAMP.png"),0.25) | |
colorRamp.save(outputDirectory + "RAMP_" + colorIndex + ".png",bits=24) | |
material.write("newmtl TOP_" + colorIndex + "\nd " + color[3] + "\nmap_Kd TOP_" + colorIndex + ".png\n\nnewmtl BOTTOMLOOP_" + colorIndex + "\nd " + color[3] + "\nmap_Kd BOTTOMLOOP_" + colorIndex + ".png\n\nnewmtl BOTTOMEDGE_" + colorIndex + "\nd " + color[3] + "\nmap_Kd BOTTOMEDGE_" + colorIndex + ".png\n\nnewmtl SIDE_" + colorIndex + "\nd " + color[3] + "\nmap_Kd SIDE_" + colorIndex + ".png\n\nnewmtl RAMP_" + colorIndex + "\nd " + color[3] + "\nmap_Kd RAMP_" + colorIndex + ".png\n\n") | |
output.close() | |
print "Complete" | |
os.system("pause") | |
except Exception,error: | |
print error | |
os.system("pause") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
sooo, how do i use it?