Skip to content

Instantly share code, notes, and snippets.

@hugoledoux
Last active October 26, 2022 15:44
Show Gist options
  • Select an option

  • Save hugoledoux/b2ca3405739f49744cb3ba8018b704eb to your computer and use it in GitHub Desktop.

Select an option

Save hugoledoux/b2ca3405739f49744cb3ba8018b704eb to your computer and use it in GitHub Desktop.
fix collapsed triangles
import sys
import point_cloud_utils as pcu
import numpy as np
def main():
# Load vertices and faces for a mesh
# mv, mf = pcu.load_mesh_vf("./cube2.obj")
mv, mf = pcu.load_mesh_vf("./filled_SM_dataset_4.obj")
# print(mv)
# print(mf)
collapsed = []
for (i, f) in enumerate(mf):
if is_collapsed(f, mv):
collapsed.append(i)
while len(collapsed) > 0:
# print("len", len(collapsed))
i = collapsed.pop()
# print(i)
fi, opp = swap(i, mv, mf)
if is_collapsed(mf[fi], mv):
collapsed.append(fi)
if is_collapsed(mf[opp], mv):
collapsed.append(opp)
# print(mf)
save(mv, mf)
# pcu.save_mesh_vf("./out.obj", v=mv, f=mf)
def save(mv, mf):
#-- shift by minx, miny, minz
mins = [1e12, 1e12, 1e12]
for v in mv:
for i in range(3):
if v[i] < mins[i]:
mins[i] = v[i]
fout = open('out.obj', 'w')
for v in mv:
fout.write("v {:.15f} {:.15f} {:.15f}\n".format(v[0] - mins[0], v[1] - mins[1], v[2] - mins[2]))
for f in mf:
fout.write("f {} {} {}\n".format(f[0]+1, f[1]+1, f[2]+1))
def is_collapsed(f, mv):
a = np.array([ mv[f[1]][0] - mv[f[0]][0], mv[f[1]][1] - mv[f[0]][1], mv[f[1]][2] - mv[f[0]][2]])
b = np.array([ mv[f[2]][0] - mv[f[0]][0], mv[f[2]][1] - mv[f[0]][1], mv[f[2]][2] - mv[f[0]][2]])
cross = np.cross(a, b)
area = np.linalg.norm(cross)
if area == 0.0:
return True
else:
return False
def swap(fi, mv, mf):
#-- find middle one
f = mf[fi]
l0 = np.array([ mv[f[2]][0] - mv[f[1]][0], mv[f[2]][1] - mv[f[1]][1], mv[f[2]][2] - mv[f[1]][2]])
l1 = np.array([ mv[f[2]][0] - mv[f[0]][0], mv[f[2]][1] - mv[f[0]][1], mv[f[2]][2] - mv[f[0]][2]])
l2 = np.array([ mv[f[1]][0] - mv[f[0]][0], mv[f[1]][1] - mv[f[0]][1], mv[f[1]][2] - mv[f[0]][2]])
l0 = np.linalg.norm(l0)
l1 = np.linalg.norm(l1)
l2 = np.linalg.norm(l2)
longest = 0
mid = l0
edge = [f[2], f[1]]
if l1 > mid:
mid = l1
longest = 1
edge = [f[0], f[2]]
if l2 > mid:
mid = l2
longest = 2
edge = [f[1], f[0]]
# print(edge)
# print(mf)
#-- find adjacent triangle
opp = 0
for (i,f) in enumerate(mf):
i1 = np.where(f==edge[0])[0]
i2 = np.where(f==edge[1])[0]
# print("i1", i1)
# print("i2", i2)
if i1.size > 0 and i2.size > 0:
if ( ((i1 == 0) and (i2 == 1)) or ((i1 == 1) and (i2 == 2)) or ((i1 == 2) and (i2 == 0)) ):
# print ("got it", f)
opp = i
break
#--
# print("fi", mf[fi])
p = mf[fi][longest]
# print("p", p)
# print("edge", edge)
# print("opp", mf[opp])
q = -1
for i in range(3):
if mf[opp][i] != edge[0] and mf[opp][i] != edge[1]:
q = mf[opp][i]
# print("q", q)
#-- swap
a = np.where(mf[fi]==edge[0])[0][0]
# print("a", a)
mf[fi][a] = q
a = np.where(mf[opp]==edge[1])[0][0]
mf[opp][a] = p
# print(mf)
# print("is_collapsed", is_collapsed(mf[fi], mv))
# print("is_collapsed", is_collapsed(mf[opp], mv))
# print(mf[fi])
# print(mv[mf[fi]][0])
# print(mv[mf[fi]][1])
# print(mv[mf[fi]][2])
# print(mf[opp])
# print(mv[mf[opp]][0])
# print(mv[mf[opp]][1])
# print(mv[mf[opp]][2])
# sys.exit()
return fi, opp
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment