Пример #1
0
def extract_mesh_from_tet(bIsSemantics = False):
    print("----Extract the output mesh----")
    #check
    if len(ModelData.dictTetrahedrons) == 0:
        print("invalid call extract Mesh")
        return

    #deletion and deduce semantics
    for fkey in ModelData.dictFaces:
        if fkey not in ModelData.listShellFaceIDs:
            ModelDataFuncs.pre_remove_face_by_faceids([fkey])

    #clearup
    if ModelDataFuncs.remove_faces() > 0:
        print ("Mesh extracted")
    
    #optimisazation
    if ModelDataFuncs.optimise_illshaped_shellfaces():
        ModelDataFuncs.remove_faces()
    ModelDataFuncs.clean_duplicated_vertices()
    ModelDataFuncs.clean_unreferenced_vertices()
    ModelDataFuncs.restore_normals()

    #deduce semantics
    deduce_semantics_of_poly(bIsSemantics)
Пример #2
0
def CDT():
    print("Start tetrahedralization....")
    curDirBefore = os.getcwd() 
    path = os.path.dirname(os.path.realpath(__file__))
    if sizeof(c_voidp) == 4:
        #win32
        path = os.path.join(path, '..\\tetgendll\\Release')
        os.chdir(path)
        if not os.path.exists("tetgendll.dll"):
            print("DLL missing: " + path + "tetgendll.dll")
        Tetrahedralator = CDLL("tetgendll.dll")
    elif sizeof(c_voidp) == 8:
        #x64
        path = os.path.join(path, '..\\tetgendll\\x64\\Release')
        os.chdir(path)
        if not os.path.exists("tetgendll.dll"):
            print("DLL missing: " + path + "tetgendll.dll")
        Tetrahedralator = CDLL("tetgendll.dll")
    os.chdir(curDirBefore)
    #be careful with the indices
    #record the indices of inserted dictVertices and map the indices in the dictFaces and tetrahedron to the finally added indices
    mapVertTet = {}
    iCount = 0
    cVertices = (c_double * (len(ModelData.dictVertices) * 3))() #the size of dictVertices *3
    for key in ModelData.dictVertices:
        cVertices[3*iCount] = c_double(ModelData.dictVertices[key][0])
        cVertices[3*iCount+1] = c_double(ModelData.dictVertices[key][1])
        cVertices[3*iCount+2] = c_double(ModelData.dictVertices[key][2])
        mapVertTet[iCount] = key
        iCount += 1

    iCount = 0
    cFaces = (c_int * (len(ModelData.dictFaces) * 3))() #the size of dictFaces * 3
    for key in ModelData.dictFaces:
        #be careful with the indices
        cFaces[3*iCount] = c_int(ModelDataFuncs.find_key_from_dict_by_exact_value(mapVertTet, ModelData.dictFaces[key].get_vids()[0]))
        cFaces[3*iCount+1] = c_int(ModelDataFuncs.find_key_from_dict_by_exact_value(mapVertTet, ModelData.dictFaces[key].get_vids()[1]))
        cFaces[3*iCount+2] = c_int(ModelDataFuncs.find_key_from_dict_by_exact_value(mapVertTet, ModelData.dictFaces[key].get_vids()[2]))
        iCount += 1

    numberOfOutputVerts = c_int(0);
    numberOfOutputTriangles = c_int(0);
    numberOfOutputTetrahedrons = c_int(0);

    try:
        Tetrahedralator.simpleTetrahedralize(byref(cVertices), c_int(len(ModelData.dictVertices)), byref(cFaces), c_int(len(ModelData.dictFaces)),
                                         byref(numberOfOutputVerts), byref(numberOfOutputTriangles), byref(numberOfOutputTetrahedrons))
    except ValueError:
        print("CDT failed")
        return False

    #check
    if numberOfOutputTetrahedrons.value == 0:
        print("tetrahedralization failed")
        return False
    #Get the results
    outputVerts = (c_double * (numberOfOutputVerts.value *3))()
    outputConvexhullTris = (c_int * (numberOfOutputTriangles.value *3))()
    outputTetrahedrons = (c_int * (numberOfOutputTetrahedrons.value *4))()

    Tetrahedralator.getResults(pointer(outputVerts), pointer(outputConvexhullTris), pointer(outputTetrahedrons))
   
    #update the ModelData
    #dictVertices
    if numberOfOutputVerts.value > len(ModelData.dictVertices):
        print("{} steiner points inserted (at the back of the original list)").format(numberOfOutputVerts.value - len(ModelData.dictVertices))
        for i in range(len(ModelData.dictVertices) * 3, numberOfOutputVerts.value * 3, 3):
            #be carefull with the indices (start with 0)
            mapVertTet[len(mapVertTet)] = ModelDataFuncs.add_vertex((outputVerts[i], outputVerts[i+1], outputVerts[i+2]))

    #dictTetrahedrons
    for i in range(0, numberOfOutputTetrahedrons.value * 4, 4):
        ModelData.dictTetrahedrons[i/4] = Class_tetrahedron((mapVertTet[outputTetrahedrons[i]], mapVertTet[outputTetrahedrons[i+1]], mapVertTet[outputTetrahedrons[i+2]], mapVertTet[outputTetrahedrons[i+3]]))

    #record the the triangles on the shell
    isFaceDeleted = False
    for i in range(0, numberOfOutputTriangles.value*3, 3):
        tris = (mapVertTet[outputConvexhullTris[i]], mapVertTet[outputConvexhullTris[i+1]], mapVertTet[outputConvexhullTris[i+2]])
        isExt = False
        for f in ModelData.dictFaces:
            if ModelData.dictFaces[f].is_equal_geometry(ClassFace.Class_face(tris)):
                #found the existing face
                isExt = True
                #add to the list of shell face
                ModelData.listShellFaceIDs.append(f)
                break
        if isExt == False:
            #distance mapping in case this geometry is produced by flipping the coplanar triangle
            fId = ModelDataFuncs.find_face_by_mapping(tris)
            if fId:
                ModelData.listShellFaceIDs.append(ModelDataFuncs.add_face(ClassFace.Class_face(tris, ClassFace.FIX, ModelData.dictFaces[fId].get_id(), ModelData.dictFaces[fId].get_type())))
                ModelDataFuncs.pre_remove_face_by_faceids([fId])
                isFaceDeleted = True
            else:
                #add the new face and add the face to the list of shell face
                ModelData.listShellFaceIDs.append(ModelDataFuncs.add_face(ClassFace.Class_face(tris)))
    #remove faces 
    if isFaceDeleted:
        ModelDataFuncs.remove_faces()
    #
    print ("After CDT: " + str(len(ModelData.dictTetrahedrons)) + " tetrahedra and " + str(len(ModelData.dictFaces)) + " dictFaces and " + str(len(ModelData.dictVertices)) + " dictVertices")
    return True
Пример #3
0
def heuristic_tet_carving():
    print("----Heuristic shrinking-wrapping----")

    #keep all the tetrahedra that have fix facets on the shell
    #in update_stack() this step is not needed because it has already been handled in carving
    for fId in ModelData.listShellFaceIDs:
        if ModelData.dictFaces[fId].get_tag() == ClassFace.FIX:
            tetId = TetraFunc.find_tetids_by_faceid(fId, 1)
            keep_tetrahedron(tetId[0], TetraFunc.get_faceids_from_tetid(tetId[0]))
    #count
    numCount = 0
    #initiate Stack and lists
    sortedTetIDStack = update_stack()
    #heruistic carving
    while len(sortedTetIDStack) > 0:
        #pop the first not fix element of stack if possible
        curTet = sortedTetIDStack.pop(0)
        curTetId = curTet[0]
        print curTetId
        
        #fetch all the shellFaces (indices) from a given Tet
        shellFaceIDsInCurTet = curTet[1]
        #fetch all the dictFaces (indices) from a given Tet
        faceIDsInCurTet = curTet[2]

        #classify the tetrahedron
        numTMP = len(shellFaceIDsInCurTet)#equal to the no. of faces on the shell
        numFIX = 0
        for fid in faceIDsInCurTet:
            if ModelData.dictFaces[fid].get_tag() == ClassFace.FIX:
                numFIX += 1
        numKEEP = len(faceIDsInCurTet) - numTMP - numFIX#keep face is not constrainted as fixed ones
        numPRESERV = numFIX + numKEEP
        #test by a set of constraints
        bStop = False
        bPostponed = False
        carveTetList = [] #for infinite tetehedra
        keepFaceList = [] #for coplanar bounded facets
        unboundFaceList = [] #for coplanar unbouned facets
        
        # new code
        #if numFIX == 0 and numTMP == 1:
        #    #constraint3
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])
        #elif numFIX == 1 and numTMP == 3:
        #    #constraint5
        #    if constraintsCtrl['Constraint5'] and not bStop:
        #            bStop = constraint_5(curTetId, faceIDsInCurTet)
        #    #check all faces with constraint 3 not needed in theory (flat tetrahedra)
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[1])
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[2])
        #elif numFIX in (1, 2) and numTMP == 2:
        #    #c1 5
        #    if constraintsCtrl['Constraint5'] and not bStop:
        #            bStop = constraint_5(curTetId, faceIDsInCurTet)

        #    if constraintsCtrl['Constraint1'] and not bStop:
        #        #extract the opposite edge
        #        eList = []
        #        for i in shellFaceIDsInCurTet:
        #            for j in range(0, 3):
        #                if ModelData.dictFaces[i].get_vids()[j] not in eList:
        #                    eList.append(ModelData.dictFaces[i].get_vids()[j])
        #                else:
        #                    eList.remove(ModelData.dictFaces[i].get_vids()[j])
        #    
        #        if not bStop:
        #            bStop, bPostponed, carveTetList = constraint_1(curTetId, eList)
        #    
        #    #check all faces with constraint 3 not needed in theory (flat tetrahedra)
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[1])
        #elif numFIX in (1, 2, 3) and numTMP == 1:
        #    #c1 2 3 5
        #    #constraint5
        #    if constraintsCtrl['Constraint5'] and not bStop:
        #        bStop = constraint_5(curTetId, faceIDsInCurTet)
        #   
        #    #constraint3
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])

        #    if (constraintsCtrl['Constraint2'] or constraintsCtrl['Constraint1']) and not bStop:
        #        #extract the candidate face, the opposite edge list (three) the and opposite vert
        #        tmpFace = shellFaceIDsInCurTet[0]
        #        #the opposite vertex
        #        oppVert = -1
        #        #the opposite edge list
        #        eList = []
        #        for v in ModelData.dictTetrahedrons[curTetId].get_vids():
        #            if v not in ModelData.dictFaces[tmpFace].get_vids():
        #                oppVert = v
        #                if numFIX == 1:
        #                    #only two edges
        #                    fixFace = list(set(faceIDsInCurTet) - set(shellFaceIDsInCurTet))
        #                    for v_1 in ModelData.dictFaces[fixFace[0]].get_vids():
        #                        if v_1 != oppVert:
        #                            eList.append((v, v_1))
        #                else:
        #                    #three edges
        #                    for n in ModelData.dictFaces[tmpFace].get_vids():
        #                        eList.append((v, n))
        #                break
        #        #check with constraints 1 2
        #        #2
        #        if constraintsCtrl['Constraint2'] and not bStop:
        #            bStop, bPostponed, carveTetList = constraint_2(curTetId, oppVert)
        #        #1
        #        if numFIX == 1:
        #            #two edges
        #            if constraintsCtrl['Constraint1'] and not bStop:
        #                bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[0])
        #            if constraintsCtrl['Constraint1'] and not bStop:
        #                bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[1])
        #        else:
        #            #three edges
        #            if constraintsCtrl['Constraint1'] and not bStop:
        #                bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[0])
        #            if constraintsCtrl['Constraint1'] and not bStop:
        #                bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[1])
        #            if constraintsCtrl['Constraint1'] and not bStop:
        #                bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[2])
        #elif numFIX == 0:
        #    #check all faces with constraint 3 not needed in theory (flat tetrahedra)
        #    if constraintsCtrl['Constraint3'] and not bStop:
        #        for fID in shellFaceIDsInCurTet:
        #            bStop, keepFaceList, unboundFaceList = constraint_3(fID)


        #old code
        #every carving step is constrainted, esp. those without fixed faces
        if numTMP == 4:
            print('Isolated tetrahedron')
            pass
            #check all faces with constraint 3 not needed in theory
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[1])
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[2])
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[3])
        elif numTMP == 3:
            #check with constraints 5
            if numFIX == 1:
                if constraintsCtrl['Constraint5'] and not bStop:
                    bStop = constraint_5(curTetId, faceIDsInCurTet)
            #check all faces with constraint 3 not needed in theory
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[1])
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[2])
        elif numTMP == 2:
            if constraintsCtrl['Constraint1']:
                #extract the opposite edge
                eList = []
                for i in shellFaceIDsInCurTet:
                    for j in range(0, 3):
                        if ModelData.dictFaces[i].get_vids()[j] not in eList:
                            eList.append(ModelData.dictFaces[i].get_vids()[j])
                        else:
                            eList.remove(ModelData.dictFaces[i].get_vids()[j])
            
                #1 different with new code
                if constraintsCtrl['Constraint1'] and not bStop:
                    bStop, bPostponed, carveTetList = constraint_1(curTetId, eList)
            #5
            if numFIX != 0:
                if constraintsCtrl['Constraint5'] and not bStop:
                    bStop = constraint_5(curTetId, faceIDsInCurTet)
                
            #check both faces with constraint 3 not needed in theory
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[0])
            if constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(shellFaceIDsInCurTet[1])

        elif numTMP == 1:
            if constraintsCtrl['Constraint2'] or constraintsCtrl['Constraint1']:
                #extract the candidate face, the opposite edge list (three) the and opposite vert
                tmpFace = shellFaceIDsInCurTet[0]
                #the opposite vertex
                oppVert = -1
                #the opposite edge list
                eList = []
                for v in ModelData.dictTetrahedrons[curTetId].get_vids():
                    if v not in ModelData.dictFaces[tmpFace].get_vids():
                        oppVert = v
                        for n in ModelData.dictFaces[tmpFace].get_vids():
                            eList.append((v, n))
                        break
                #check with constraints 1 2 3 5
                #2 different with new code
                if constraintsCtrl['Constraint2'] and not bStop:
                    bStop, bPostponed, carveTetList = constraint_2(curTetId, oppVert)
                #1 different with new code
                if constraintsCtrl['Constraint1'] and not bStop:
                    bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[0])
                if constraintsCtrl['Constraint1'] and not bStop:
                    bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[1])
                if constraintsCtrl['Constraint1'] and not bStop:
                    bStop, bPostponed, carveTetList = constraint_1(curTetId, eList[2])
           
            if numFIX != 0 and constraintsCtrl['Constraint5'] and not bStop:
               #5
                bStop = constraint_5(curTetId, faceIDsInCurTet)   
               
            #3
            if numFIX != 3 and constraintsCtrl['Constraint3'] and not bStop:
                bStop, keepFaceList, unboundFaceList = constraint_3(tmpFace)
             
        else:
            print("Isolated Tetrahedron!", numTMP, numKNOWN)
            #raise Exception
        
        #manipulate the tetrahedron
        numTet = len(ModelData.dictTetrahedrons)
        if bStop:
            #keep
            if len(keepFaceList) != 0:
                #keep a bunch of "coplanar" tetrehedra
                for faceId in keepFaceList:
                    tetId = TetraFunc.find_tetids_by_faceid(faceId, 1)
                    if tetId != []:
                        keep_tetrahedron(tetId[0], TetraFunc.get_faceids_from_tetid(tetId[0]))
                #carve a bunch of "coplanar" unbouned tetrehedra
                if len(unboundFaceList) != 0:
                    for faceId in unboundFaceList:
                        tetId = TetraFunc.find_tetids_by_faceid(faceId, 1)
                        if tetId != []:
                            carve_tetrahedron(tetId[0], TetraFunc.get_faceids_from_tetid(tetId[0]))
            else:
                #keep
                keep_tetrahedron(curTetId, faceIDsInCurTet)
        else:
            #carve or postpone
            if not bPostponed:
                #Carve
                bIsCarved = True
                carve_tetrahedron(curTetId, faceIDsInCurTet)
            else:
                #postpone
                if ModelData.dictTetrahedrons[curTetId].get_tag() == ClassFace.INF:
                    #all the tetrehedra are infinite (INF)
                    for tetId in carveTetList:
                        #carve a bunch of tetrahedra
                        carve_tetrahedron(tetId, TetraFunc.get_faceids_from_tetid(tetId))
                else:
                    #postphone the tetrahedron
                    ModelData.dictTetrahedrons[curTetId].set_tag(ClassFace.INF)

        #Update the dictFaces
        ModelDataFuncs.remove_faces()
        #Update the stack and lists
        sortedTetIDStack = update_stack()

        #Output intermediate results
        if globalOutputCarve  and numTet > len(ModelData.dictTetrahedrons) and len(ModelData.dictTetrahedrons) % globalOutputFreq == 0:
            ModelDataFuncs.writer_obj(ModelData.strInputFileName + '_' + str(len(ModelData.dictTetrahedrons)) + "_CARVE_.obj")