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?