Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
63c4d67e3This file is pinned to the selected release. Download the original to open it in your design tool.
from __future__ import print_function
import numpy as np
class Obj:
def __init__(self, fn):
self.ind_v = 0
self.ind_vt = 0
self.ind_vn = 0
self.fn = fn
self.out = open(fn + ".tmp", "w")
self.out.write("mtllib dinnerware.mtl\n")
def __del__(self):
self.out.close()
import shutil
shutil.move(self.fn + ".tmp", self.fn)
def push_v(self, v):
self.out.write("v %f %f %f\n" % (v[0], v[1], v[2]))
self.ind_v += 1
return self.ind_v
def push_vt(self, vt):
self.out.write("vt %f %f\n" % (vt[0], vt[1]))
self.ind_vt += 1
return self.ind_vt
def push_vn(self, vn):
vn /= np.linalg.norm(vn)
self.out.write("vn %f %f %f\n" % (vn[0], vn[1], vn[2]))
self.ind_vn += 1
return self.ind_vn
def convex_hull(points, vind, nind, tind, obj):
"super ineffective"
cnt = len(points)
for a in range(cnt):
for b in range(a + 1, cnt):
for c in range(b + 1, cnt):
vec1 = points[a] - points[b]
vec2 = points[a] - points[c]
n = np.cross(vec1, vec2)
n /= np.linalg.norm(n)
C = np.dot(n, points[a])
inner = np.inner(n, points)
pos = (inner <= C + 0.0001).all()
neg = (inner >= C - 0.0001).all()
if not pos and not neg: continue
obj.out.write("f %i//%i %i//%i %i//%i\n" %
((vind[a], nind[a], vind[b], nind[b], vind[c], nind[c]) if
(inner - C).sum() < 0 else
(vind[a], nind[a], vind[c], nind[c], vind[b], nind[b])))
#obj.out.write("f %i/%i/%i %i/%i/%i %i/%i/%i\n" % (
# (vind[a], tind[a], nind[a], vind[b], tind[b], nind[b], vind[c], tind[c], nind[c])
# if (inner - C).sum() < 0 else
# (vind[a], tind[a], nind[a], vind[c], tind[c], nind[c], vind[b], tind[b], nind[b]) ) )
def test_convex_hull():
obj = Obj("convex_test.obj")
vlist = np.random.uniform(low=-0.1, high=+0.1, size=(100, 3))
nlist = vlist.copy()
tlist = np.random.uniform(low=0, high=+1, size=(100, 2))
vind = [obj.push_v(xyz) for xyz in vlist]
nind = [obj.push_vn(xyz) for xyz in nlist]
tind = [obj.push_vt(uv) for uv in tlist]
convex_hull(vlist, vind, nind, tind, obj)
class Contour:
def __init__(self):
self.vprev_vind = None
def f(self, obj, vlist_vind, vlist_tind, vlist_nind):
cnt = len(vlist_vind)
for i1 in range(cnt):
i2 = i1 - 1
obj.out.write("f %i/%i/%i %i/%i/%i %i/%i/%i\n" % (
vlist_vind[i2],
vlist_tind[i2],
vlist_nind[i2],
vlist_vind[i1],
vlist_tind[i1],
vlist_nind[i1],
self.vprev_vind[i1],
self.vprev_tind[i1],
self.vprev_nind[i1],
))
obj.out.write("f %i/%i/%i %i/%i/%i %i/%i/%i\n" % (
vlist_vind[i2],
vlist_tind[i2],
vlist_nind[i2],
self.vprev_vind[i1],
self.vprev_tind[i1],
self.vprev_nind[i1],
self.vprev_vind[i2],
self.vprev_tind[i2],
self.vprev_nind[i2],
))
def belt(self, obj, vlist, nlist, tlist):
vlist_vind = [obj.push_v(xyz) for xyz in vlist]
vlist_tind = [obj.push_vt(xyz) for xyz in tlist]
vlist_nind = [obj.push_vn(xyz) for xyz in nlist]
if self.vprev_vind:
self.f(obj, vlist_vind, vlist_tind, vlist_nind)
else:
self.first_vind = vlist_vind
self.first_tind = vlist_tind
self.first_nind = vlist_nind
self.vprev_vind = vlist_vind
self.vprev_tind = vlist_tind
self.vprev_nind = vlist_nind
def finish(self, obj):
self.f(obj, self.first_vind, self.first_tind, self.first_nind)
def test_contour():
RAD1 = 2.0
RAD2 = 1.5
obj = Obj("torus.obj")
obj.out.write("usemtl porcelain\n")
contour = Contour()
for step in range(100):
angle = step / 100.0 * 2 * np.pi
belt_v = []
belt_n = []
belt_t = []
for b in range(50):
beta = b / 50.0 * 2 * np.pi
r = RAD2 * np.cos(beta) + RAD1
z = RAD2 * np.sin(beta)
belt_v.append(np.array([np.cos(angle) * r, np.sin(angle) * r, z]))
belt_n.append(
np.array([np.cos(angle) * np.cos(beta),
np.sin(angle) * np.cos(beta),
np.sin(beta)]))
belt_t.append((0, 0))
contour.belt(obj, belt_v, belt_n, belt_t)
contour.finish(obj)
#test_convex_hull()
#test_contour()
class RotationFigureParams:
pass
def generate_plate(p, obj, collision_prefix):
contour = Contour()
belt_vlist_3d_prev = None
for step in range(p.N_VIZ + 1):
angle = step / float(p.N_VIZ) * 2 * np.pi
if step % p.COLLISION_EVERY == 0:
vlist_3d = []
for x, y in p.belt_simple:
vlist_3d.append([np.cos(angle) * x * 1.06, np.sin(angle) * x * 1.06, y])
if belt_vlist_3d_prev:
obj2 = Obj(collision_prefix % (step / p.COLLISION_EVERY))
obj2.out.write("usemtl pan_tefal\n")
vlist = np.array(vlist_3d + belt_vlist_3d_prev)
vlist[len(vlist_3d):] *= 1.01 # break points on one plane
vlist[0, 0:2] += 0.01 * vlist[len(vlist_3d), 0:2]
vlist[len(vlist_3d), 0:2] += 0.01 * vlist[0, 0:2]
nlist = np.random.uniform(low=-1, high=+1, size=vlist.shape)
tlist = np.random.uniform(low=0, high=+1, size=(len(vlist), 2))
vind = [obj2.push_v(xyz) for xyz in vlist]
nind = [obj2.push_vn(xyz) for xyz in nlist]
convex_hull(vlist, vind, nind, None, obj2)
belt_vlist_3d_prev = vlist_3d
if step == p.N_VIZ: break
belt_v = []
belt_n = []
belt_t = []
for x, y, nx, ny in p.belt:
belt_v.append(np.array([np.cos(angle) * x, np.sin(angle) * x, y]))
belt_n.append(np.array([np.cos(angle) * nx, np.sin(angle) * nx, ny]))
if ny - nx >= 0:
belt_t.append((127.0 / 512 + np.cos(angle) * x / p.RAD_HIGH * 105 / 512,
(512 - 135.0) / 512 + np.sin(angle) * x / p.RAD_HIGH * 105 / 512))
else:
belt_t.append((382.0 / 512 + np.cos(angle) * x / p.RAD_HIGH * 125 / 512,
(512 - 380.0) / 512 + np.sin(angle) * x / p.RAD_HIGH * 125 / 512))
contour.belt(obj, belt_v, belt_n, belt_t)
contour.finish(obj)
def tefal():
p = RotationFigureParams()
p.RAD_LOW = 0.240 / 2
p.RAD_HIGH = 0.255 / 2
p.H = 0.075
p.THICK = 0.005
p.N_VIZ = 30
p.COLLISION_EVERY = 5
p.belt = [
(p.RAD_HIGH - p.THICK, p.H, -1, 0), # x y norm
(p.RAD_HIGH, p.H, 0, 1),
(p.RAD_HIGH + p.THICK, p.H, +1, 0),
(p.RAD_LOW + p.THICK, p.THICK, +1, 0),
(p.RAD_LOW, 0, 0, -1),
(0, 0, 0, -1),
(0, p.THICK, 0, 1),
(p.RAD_LOW - p.THICK, p.THICK, 0, 1),
(p.RAD_LOW - p.THICK, 3 * p.THICK, -1, 0),
]
p.belt.reverse()
p.belt_simple = [(p.RAD_HIGH - p.THICK, p.H), (p.RAD_HIGH + p.THICK, p.H), (p.RAD_LOW, 0),
(p.RAD_LOW - p.THICK, 0)]
obj = Obj("pan_tefal.obj")
obj.out.write("usemtl pan_tefal\n")
generate_plate(p, obj, "pan_tefal-collision%02i.obj")
def plate():
p = RotationFigureParams()
p.RAD_LOW = 0.110 / 2
p.RAD_HIGH = 0.190 / 2
p.H = 0.060
p.THICK = 0.003
p.N_VIZ = 30
p.COLLISION_EVERY = 5
p.belt = [
(p.RAD_HIGH - p.THICK, p.H, -0.9, 0.5), # x y norm
(p.RAD_HIGH, p.H, 0, 1),
(p.RAD_HIGH + p.THICK, p.H, +1, 0),
(p.RAD_LOW + p.THICK, p.THICK, +1, 0),
(p.RAD_LOW, 0, 0, -1),
(0, 0, 0, -1),
(0, p.THICK, 0, 1),
(p.RAD_LOW - 3 * p.THICK, p.THICK, 0, 1),
(p.RAD_LOW - p.THICK, 3 * p.THICK, -0.5, 1.0),
]
p.belt.reverse()
p.belt_simple = [(p.RAD_HIGH - p.THICK, p.H), (p.RAD_HIGH + p.THICK, p.H), (p.RAD_LOW, 0),
(p.RAD_LOW - p.THICK, 0)]
obj = Obj("plate.obj")
obj.out.write("usemtl solid_color\n")
generate_plate(p, obj, "plate-collision%02i.obj")
plate()