def combine(mesh1, inverted1, mesh2, inverted2, tolerance = 0.000001): class FaceRemoveException(Exception): pass possible_overlaps = list(mesh1.possible_face_collisions(mesh2)) replaced_faces1 = {} replaced_faces2 = {} print "Mesh1", mesh1.vertices print "Mesh2", mesh2.vertices print len(possible_overlaps) n=40 m=300 while possible_overlaps: face1, face2 = possible_overlaps.pop() assert n > 0 assert m > 0 try: if replaced_faces1.has_key(face1): for new_face1 in replaced_faces1[face1]: possible_overlaps.append((new_face1, face2)) raise FaceRemoveException if replaced_faces2.has_key(face2): for new_face in replaced_faces2[face2]: possible_overlaps.append((face1, new_face)) raise FaceRemoveException if face1.normal.cross(face2.normal).magnitude() < tolerance and abs(face1.normal.dot(face1.vertices[0]) - face1.normal.dot(face2.vertices[0])) < tolerance: for vertex1 in face1.vertices: if point_in_face(vertex1, face2, tolerance) and vertex1 not in mesh2.vertices: vertex2 = mesh2.add_vertex(vertex1.x, vertex1.y, vertex1.z) possible_overlaps.append((face1, face2)) #There may be more than one face intersection for this pair of points replaced_faces2[face2] = mesh2.split_face(vertex2, face2) raise FaceRemoveException for vertex2 in face2.vertices: if point_in_face(vertex2, face1, tolerance) and vertex2 not in mesh1.vertices: vertex1 = mesh1.add_vertex(vertex2.x, vertex2.y, vertex2.z) possible_overlaps.append((face1, face2)) #There may be more than one face intersection for this pair of points replaced_faces1[face1] = mesh1.split_face(vertex1, face1) raise FaceRemoveException except FaceRemoveException: m = m - 1 possible_overlaps = list(mesh1.possible_face_collisions(mesh2)) replaced_faces1 = {} replaced_faces2 = {} print "Mesh1", mesh1.vertices print "Mesh2", mesh2.vertices print len(possible_overlaps) fileio.write_ply(mesh1, "/home/martin/m1.ply") fileio.write_ply(mesh2, "/home/martin/m2.ply") n=40 m=300 while possible_overlaps: face1, face2 = possible_overlaps.pop() fileio.write_ply(mesh1, "/home/martin/m1.ply") fileio.write_ply(mesh2, "/home/martin/m2.ply") assert n > 0 assert m > 0 try: if replaced_faces1.has_key(face1): for new_face1 in replaced_faces1[face1]: if replaced_faces2.has_key(face2): for new_face2 in replaced_faces2[face2]: possible_overlaps.append((new_face1, new_face2)) else: possible_overlaps.append((new_face1, face2)) raise FaceRemoveException if replaced_faces2.has_key(face2): for new_face in replaced_faces2[face2]: possible_overlaps.append((face1, new_face)) raise FaceRemoveException if face1.normal.cross(face2.normal).magnitude() < tolerance and abs(face1.normal.dot(face1.vertices[0]) - face1.normal.dot(face2.vertices[0])) < tolerance: for edge1 in face1.edges: for edge2 in face2.edges: try: ip, s1, s2 = line_intersection_and_proportion((edge1.v1, edge1.v2), (edge2.v1, edge2.v2)) #print "Lines Cross?", edge1.v1, edge1.v2, edge2.v1, edge2.v2, ip, s1, s2 if s1 > tolerance and 1-s1 > tolerance and s2 > tolerance and 1- s2 > tolerance: n = n -1 #print "Crossed", edge1, edge2, s1, s2, ip faces1_to_be_replaced = edge1.faces() new_vertex1 = mesh1.add_vertex(ip) new_faces1 = mesh1.split_edge(new_vertex1, edge1) for face1_to_be_replaced in faces1_to_be_replaced: replaced_faces1[face1_to_be_replaced] = new_faces1 faces2_to_be_replaced = edge2.faces() new_vertex2 = mesh2.add_vertex(ip) origvol = mesh2.volume() new_faces2 = mesh2.split_edge(new_vertex2, edge2) if abs(origvol - mesh2.volume()) > tolerance: #print ip, s1, s2 assert False for face2_to_be_replaced in faces2_to_be_replaced: replaced_faces2[face2_to_be_replaced] = new_faces2 print "EDGE SPLIT" raise FaceRemoveException except (ParallelLinesException, LinesDoNotCrossException): pass except FaceRemoveException: m = m - 1 # possible_overlaps = list(mesh1.possible_face_collisions(mesh2)) # replaced_faces1 = {} # replaced_faces2 = {} # while possible_overlaps: # face1, face2 = possible_overlaps.pop() # try: # if replaced_faces1.has_key(face1): # for new_face in replaced_faces1[face1]: # possible_overlaps.append((new_face, face2)) # raise FaceRemoveException # if replaced_faces2.has_key(face2): # for new_face in replaced_faces2[face2]: # possible_overlaps.append((face1, new_face)) # raise FaceRemoveException # for edge1 in face1.edges: # for edge2 in face2.edges: # try: # ip, s1, s2 = line_intersection_and_proportion((edge1.v1, edge1.v2), (edge2.v1, edge2.v2)) # if s1 > tolerance and 1-s1 > tolerance and s2 > tolerance and 1-s2 > tolerance: # print edge1, edge2, s1, s2 # faces1_to_be_replaced = edge1.faces() # new_vertex1 = mesh1.add_vertex(ip) # new_faces1 = mesh1.split_edge(new_vertex1, edge1) # for face1_to_be_replaced in faces1_to_be_replaced: # replaced_faces1[face1_to_be_replaced] = new_faces1 # faces2_to_be_replaced = edge2.faces() # new_vertex2 = mesh2.add_vertex(ip) # new_faces2 = mesh2.split_edge(new_vertex2, edge2) # for face2_to_be_replaced in faces2_to_be_replaced: # replaced_faces2[face2_to_be_replaced] = new_faces2 # raise FaceRemoveException # except ValueError: # pass # except FaceRemoveException: # pass #fileio.write_stl(mesh1, "/home/martin/m1.ply") #fileio.write_stl(mesh2, "/home/martin/m2.ply") print "M1V", mesh1.vertices print "M1V", mesh1.vertices print "M1F", len(mesh1.faces) print "M2F", len(mesh2.faces) print "M1Vol", mesh1.volume()#Check mesh is closed print "M2Vol", mesh2.volume()#Check mesh is closed m = Mesh() vertex1_map = {} for v in mesh1.vertices: new_vertex = m.get_vertex(v) if new_vertex is None: #Vertex does not exist new_vertex = m.add_vertex(v.x, v.y, v.z) vertex1_map[v] = new_vertex for face in mesh1.faces: vertices = [vertex1_map[vertex] for vertex in face.vertices] if mesh2.contains_point(face.centroid() + face.normal * tolerance * {True: -1, False: 1}[inverted1]) != (not inverted2): if inverted1: m.add_triangle_face(vertices[0], vertices[2], vertices[1]) else: m.add_triangle_face(vertices[0], vertices[1], vertices[2]) vertex2_map = {} for v in mesh2.vertices: new_vertex = m.get_vertex(v) #print "?", m.get_vertex(v), m.get_vertex(v.x, v.y, v.z), v.x, v.y, v.z if new_vertex is None: #Vertex does not exist #print "Adding" new_vertex = m.add_vertex(v.x, v.y, v.z) #print "added" vertex2_map[v] = new_vertex edge_splits = {} for face in mesh2.faces: vertices = [vertex2_map[vertex] for vertex in face.vertices] if mesh1.contains_point(face.centroid() + face.normal * tolerance * {True: -1, False: 1}[inverted2]) != (not inverted1): if inverted2: add_splits_and_face(m, vertices[0], vertices[2], vertices[1], edge_splits) else: add_splits_and_face(m, vertices[0], vertices[1], vertices[2], edge_splits) #clean up verticies m.clean() fileio.write_ply(m, "/home/martin/m3.ply") return m
def combine(mesh1, inverted1, mesh2, inverted2, tolerance=0.000001): class FaceRemoveException(Exception): pass possible_overlaps = list(mesh1.possible_face_collisions(mesh2)) replaced_faces1 = {} replaced_faces2 = {} print "Mesh1", mesh1.vertices print "Mesh2", mesh2.vertices print len(possible_overlaps) n = 40 m = 300 while possible_overlaps: face1, face2 = possible_overlaps.pop() assert n > 0 assert m > 0 try: if replaced_faces1.has_key(face1): for new_face1 in replaced_faces1[face1]: possible_overlaps.append((new_face1, face2)) raise FaceRemoveException if replaced_faces2.has_key(face2): for new_face in replaced_faces2[face2]: possible_overlaps.append((face1, new_face)) raise FaceRemoveException if face1.normal.cross( face2.normal).magnitude() < tolerance and abs( face1.normal.dot(face1.vertices[0]) - face1.normal.dot(face2.vertices[0])) < tolerance: for vertex1 in face1.vertices: if point_in_face( vertex1, face2, tolerance) and vertex1 not in mesh2.vertices: vertex2 = mesh2.add_vertex(vertex1.x, vertex1.y, vertex1.z) possible_overlaps.append( (face1, face2) ) #There may be more than one face intersection for this pair of points replaced_faces2[face2] = mesh2.split_face( vertex2, face2) raise FaceRemoveException for vertex2 in face2.vertices: if point_in_face( vertex2, face1, tolerance) and vertex2 not in mesh1.vertices: vertex1 = mesh1.add_vertex(vertex2.x, vertex2.y, vertex2.z) possible_overlaps.append( (face1, face2) ) #There may be more than one face intersection for this pair of points replaced_faces1[face1] = mesh1.split_face( vertex1, face1) raise FaceRemoveException except FaceRemoveException: m = m - 1 possible_overlaps = list(mesh1.possible_face_collisions(mesh2)) replaced_faces1 = {} replaced_faces2 = {} print "Mesh1", mesh1.vertices print "Mesh2", mesh2.vertices print len(possible_overlaps) fileio.write_ply(mesh1, "/home/martin/m1.ply") fileio.write_ply(mesh2, "/home/martin/m2.ply") n = 40 m = 300 while possible_overlaps: face1, face2 = possible_overlaps.pop() fileio.write_ply(mesh1, "/home/martin/m1.ply") fileio.write_ply(mesh2, "/home/martin/m2.ply") assert n > 0 assert m > 0 try: if replaced_faces1.has_key(face1): for new_face1 in replaced_faces1[face1]: if replaced_faces2.has_key(face2): for new_face2 in replaced_faces2[face2]: possible_overlaps.append((new_face1, new_face2)) else: possible_overlaps.append((new_face1, face2)) raise FaceRemoveException if replaced_faces2.has_key(face2): for new_face in replaced_faces2[face2]: possible_overlaps.append((face1, new_face)) raise FaceRemoveException if face1.normal.cross( face2.normal).magnitude() < tolerance and abs( face1.normal.dot(face1.vertices[0]) - face1.normal.dot(face2.vertices[0])) < tolerance: for edge1 in face1.edges: for edge2 in face2.edges: try: ip, s1, s2 = line_intersection_and_proportion( (edge1.v1, edge1.v2), (edge2.v1, edge2.v2)) #print "Lines Cross?", edge1.v1, edge1.v2, edge2.v1, edge2.v2, ip, s1, s2 if s1 > tolerance and 1 - s1 > tolerance and s2 > tolerance and 1 - s2 > tolerance: n = n - 1 #print "Crossed", edge1, edge2, s1, s2, ip faces1_to_be_replaced = edge1.faces() new_vertex1 = mesh1.add_vertex(ip) new_faces1 = mesh1.split_edge( new_vertex1, edge1) for face1_to_be_replaced in faces1_to_be_replaced: replaced_faces1[ face1_to_be_replaced] = new_faces1 faces2_to_be_replaced = edge2.faces() new_vertex2 = mesh2.add_vertex(ip) origvol = mesh2.volume() new_faces2 = mesh2.split_edge( new_vertex2, edge2) if abs(origvol - mesh2.volume()) > tolerance: #print ip, s1, s2 assert False for face2_to_be_replaced in faces2_to_be_replaced: replaced_faces2[ face2_to_be_replaced] = new_faces2 print "EDGE SPLIT" raise FaceRemoveException except (ParallelLinesException, LinesDoNotCrossException): pass except FaceRemoveException: m = m - 1 # possible_overlaps = list(mesh1.possible_face_collisions(mesh2)) # replaced_faces1 = {} # replaced_faces2 = {} # while possible_overlaps: # face1, face2 = possible_overlaps.pop() # try: # if replaced_faces1.has_key(face1): # for new_face in replaced_faces1[face1]: # possible_overlaps.append((new_face, face2)) # raise FaceRemoveException # if replaced_faces2.has_key(face2): # for new_face in replaced_faces2[face2]: # possible_overlaps.append((face1, new_face)) # raise FaceRemoveException # for edge1 in face1.edges: # for edge2 in face2.edges: # try: # ip, s1, s2 = line_intersection_and_proportion((edge1.v1, edge1.v2), (edge2.v1, edge2.v2)) # if s1 > tolerance and 1-s1 > tolerance and s2 > tolerance and 1-s2 > tolerance: # print edge1, edge2, s1, s2 # faces1_to_be_replaced = edge1.faces() # new_vertex1 = mesh1.add_vertex(ip) # new_faces1 = mesh1.split_edge(new_vertex1, edge1) # for face1_to_be_replaced in faces1_to_be_replaced: # replaced_faces1[face1_to_be_replaced] = new_faces1 # faces2_to_be_replaced = edge2.faces() # new_vertex2 = mesh2.add_vertex(ip) # new_faces2 = mesh2.split_edge(new_vertex2, edge2) # for face2_to_be_replaced in faces2_to_be_replaced: # replaced_faces2[face2_to_be_replaced] = new_faces2 # raise FaceRemoveException # except ValueError: # pass # except FaceRemoveException: # pass #fileio.write_stl(mesh1, "/home/martin/m1.ply") #fileio.write_stl(mesh2, "/home/martin/m2.ply") print "M1V", mesh1.vertices print "M1V", mesh1.vertices print "M1F", len(mesh1.faces) print "M2F", len(mesh2.faces) print "M1Vol", mesh1.volume() #Check mesh is closed print "M2Vol", mesh2.volume() #Check mesh is closed m = Mesh() vertex1_map = {} for v in mesh1.vertices: new_vertex = m.get_vertex(v) if new_vertex is None: #Vertex does not exist new_vertex = m.add_vertex(v.x, v.y, v.z) vertex1_map[v] = new_vertex for face in mesh1.faces: vertices = [vertex1_map[vertex] for vertex in face.vertices] if mesh2.contains_point(face.centroid() + face.normal * tolerance * { True: -1, False: 1 }[inverted1]) != (not inverted2): if inverted1: m.add_triangle_face(vertices[0], vertices[2], vertices[1]) else: m.add_triangle_face(vertices[0], vertices[1], vertices[2]) vertex2_map = {} for v in mesh2.vertices: new_vertex = m.get_vertex(v) #print "?", m.get_vertex(v), m.get_vertex(v.x, v.y, v.z), v.x, v.y, v.z if new_vertex is None: #Vertex does not exist #print "Adding" new_vertex = m.add_vertex(v.x, v.y, v.z) #print "added" vertex2_map[v] = new_vertex edge_splits = {} for face in mesh2.faces: vertices = [vertex2_map[vertex] for vertex in face.vertices] if mesh1.contains_point(face.centroid() + face.normal * tolerance * { True: -1, False: 1 }[inverted2]) != (not inverted1): if inverted2: add_splits_and_face(m, vertices[0], vertices[2], vertices[1], edge_splits) else: add_splits_and_face(m, vertices[0], vertices[1], vertices[2], edge_splits) #clean up verticies m.clean() fileio.write_ply(m, "/home/martin/m3.ply") return m