|
from unicodedata import decimal |
|
from PIL import Image |
|
|
|
objFilePath = "obj&color/monu1.vox.obj" |
|
pngFilePath = "obj&color/monu1.vox.png" |
|
mtlFilePath = "obj&color/monu1.vox.mtl" |
|
|
|
def loadPng(): |
|
image = Image.open(pngFilePath) |
|
pixels = image.load() |
|
rgbs = [] |
|
for x in range(image.size[0]): |
|
rgbs.append(pixels[x, 0]) |
|
return rgbs |
|
|
|
def writeMtl(): |
|
rgbs = loadPng() |
|
with open(mtlFilePath, "w") as w: |
|
for i, rgb in enumerate(rgbs): |
|
w.write("newmtl mtl{}\n".format(i)) |
|
w.write("Kd {} {} {}\n".format(rgb[0], rgb[1], rgb[2])) |
|
w.write("Ks 0.50 0.50 0.50\n") |
|
w.write("\n") |
|
return len(rgbs) |
|
|
|
def calSurface(v1, v2, v3): |
|
a = (v2[1] - v1[1]) * (v3[2] - v1[2]) - (v2[2] - v1[2]) * (v3[1] - v1[1]) |
|
b = (v2[2] - v1[2]) * (v3[0] - v1[0]) - (v2[0] - v1[0]) * (v3[2] - v1[2]) |
|
c = (v2[0] - v1[0]) * (v3[1] - v1[1]) - (v2[1] - v1[1]) * (v3[0] - v1[0]) |
|
d = -(a * v1[0] + b * v1[1] + c * v1[2]) |
|
# remained decimal digits, the less decimal the less surfaces |
|
decimal = 2 |
|
a, b, c, d = round(a, decimal), round(b, decimal), round(c, decimal), round(d, decimal) |
|
if a == -0.0: a = 0.0 |
|
if b == -0.0: b = 0.0 |
|
if c == -0.0: c = 0.0 |
|
if d == -0.0: d = 0.0 |
|
return "#".join([str(a), str(b), str(c), str(d)]) |
|
|
|
def readObj(): |
|
fs, vs, fcnt, vcnt = {}, {}, 0, 1 # vcnt is the number of vertices, start with 1 |
|
surfaces, revSurfaces = {}, {} # a*x + b*y + c*z = d => <i, str(a#b#c#d)> |
|
with open(objFilePath, "r") as r: |
|
for i, line in enumerate(r.readlines()): |
|
strs = line.split(" ") |
|
if strs[0] == "f": |
|
v1, v2, v3 = int(strs[1].split("/")[0]), int(strs[2].split("/")[0]), int(strs[3].split("/")[0]) |
|
fs[i] = [fcnt, v1, v2, v3] |
|
fcnt += 1 |
|
if strs[0] == "v": |
|
vs[vcnt] = (float(strs[1]), float(strs[2]), float(strs[3])) |
|
vcnt += 1 |
|
newFs = {} |
|
for i, ps in fs.items(): |
|
v1, v2, v3 = vs[ps[1]], vs[ps[2]], vs[ps[3]] |
|
surface = calSurface(v1, v2, v3) |
|
surfaces[i] = surface |
|
if surface not in revSurfaces: revSurfaces[surface] = [i] |
|
else: revSurfaces[surface].append(i) |
|
newFs[i] = [ps[0], surface] |
|
print(len(revSurfaces)) |
|
return fs, newFs, surfaces, revSurfaces |
|
|
|
def rewriteObj(lenOfRGBs): |
|
fs, newFs, surfaces, revSurfaces = readObj() |
|
# gap = len(fs) // lenOfRGBs |
|
gap_ = len(revSurfaces) // lenOfRGBs |
|
surface2mtlindex = {} |
|
for i, (fcnt, surface) in newFs.items(): |
|
if surface not in surface2mtlindex: |
|
l = len(surface2mtlindex) |
|
if l // gap_ < lenOfRGBs: |
|
surface2mtlindex[surface] = l // gap_ |
|
else: |
|
surface2mtlindex[surface] = lenOfRGBs - 1 |
|
|
|
with open(objFilePath, "r") as r: |
|
with open("obj&color/monu1.vox.new.obj", "w") as w: |
|
for i, line in enumerate(r.readlines()): |
|
# if i in fs and fs[i][0] % gap == 0 and fs[i][0] // gap < lenOfRGBs: |
|
# w.write("usemtl mtl{}\n".format(fs[i][0] // gap)) |
|
if i in newFs: |
|
# printfile(i, newFs[i], surface2mtlindex[newFs[i][1]]) |
|
with open("surface.txt", "a") as a: |
|
a.write("{} {} {}\n".format(i, newFs[i], surface2mtlindex[newFs[i][1]])) |
|
w.write("usemtl mtl{}\n".format(surface2mtlindex[newFs[i][1]])) |
|
w.write(line) |
|
|
|
if __name__ == "__main__": |
|
lenOfRGBs = writeMtl() # total colors of .png |
|
lenOfRGBs = 50 # how many RGBs used in one mtl file, options, to make your obj less color... |
|
rewriteObj(lenOfRGBs) |