model_generator2/texture_sampler.py

112 lines
2.6 KiB
Python

from PIL import Image
from obj import VertexTexture, parse_obj_file
import sys
def fpf(fp):
return fp.s * (fp.w + (fp.f / 10 ** fp.b))
def fpv(v):
return VertexTexture(fpf(v.x), fpf(v.y))
def v_add(a, b):
return VertexTexture(a.x + b.x, a.y + b.y)
def v_sub(a, b):
return VertexTexture(a.x - b.x, a.y - b.y)
def v_mul(a, s):
return VertexTexture(a.x * s, a.y * s)
def lerp(a, b, x):
return v_add(a, v_mul(v_sub(b, a), x))
def remap(x, input_start, input_end, output_start, output_end):
return (x - input_start) / (input_end - input_start) * (output_end - output_start) + output_start
def sample(im, l):
width, height = im.size
x = l.x
y = l.y
while x > 1:
x -= 1
while y > 1:
y -= 1
while x < 0:
x += 1
while y < 0:
y += 1
#x = 1 - x
y = 1 - y
px, py = remap(x, 0, 1, 0, width - 1), remap(y, 0, 1, 0, height - 1)
assert px < width and py < height
color = im.getpixel((px, py))
return color
count = 0
def sample_texture(obj_file, ptn, im):
at = fpv(obj_file.texture[ptn[0].texture])
bt = fpv(obj_file.texture[ptn[1].texture])
ct = fpv(obj_file.texture[ptn[2].texture])
dt = fpv(obj_file.texture[ptn[3].texture])
"""
at bt
dt ct
"""
out = Image.new("P", (16, 16))
out.putpalette(im.getpalette())
for vi in range(0, 16):
v = remap(vi + 0.5, 0, 16, 0, 1)
for ui in range(0, 16):
u = remap(ui + 0.5, 0, 16, 0, 1)
lab = lerp(at, bt, u)
ldc = lerp(dt, ct, u)
l = lerp(lab, ldc, v)
value = sample(im, l)
out.putpixel((ui, vi), value)
return out
def main(obj_file, im):
im_list = {}
#face_map = {}
face_map = []
def out_ix(out):
data = tuple(out.getdata())
if data in im_list:
return im_list[data]
else:
im_list[data] = len(im_list)
return im_list[data]
for oi, object in enumerate(obj_file.objects):
for fi, face in enumerate(object.faces):
out = sample_texture(obj_file, face.ptn, im)
#face_map[(oi, fi)] = out_ix(out)
face_map.append(out_ix(out))
break
im_list_vk = {v: k for k, v in im_list.items()}
for im_ix in range(len(im_list_vk)):
data = im_list_vk[im_ix]
out = Image.new("P", (16, 16))
out.putpalette(im.getpalette())
out.putdata(data)
out.save(f"{str(im_ix).rjust(3, '0')}.png")
print(", ".join(map(str, face_map)))
obj_file = parse_obj_file(sys.argv[1])
im = Image.open(sys.argv[2])
main(obj_file, im)