Last active
October 26, 2022 15:44
-
-
Save hugoledoux/b2ca3405739f49744cb3ba8018b704eb to your computer and use it in GitHub Desktop.
fix collapsed triangles
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 | |
| 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