Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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