示例#1
0
def carve_tetrahedron(curTetId, faceIDsInCurTet):
    #remove the known TMP face of this tetrahedron and locally keep the adjacent FIX tetrahedron
    for i in faceIDsInCurTet:
        if ModelData.dictFaces[i].get_tag() == ClassFace.TMP:
            #on the shell
            ModelDataFuncs.pre_remove_face_by_faceids([i])
            #update the list of shell faces (TMP face must be on the shell)
            ModelData.listShellFaceIDs.remove(i)
        else:
            #deal with adjacent fixed tetrahedron
            if i not in ModelData.listShellFaceIDs:
                ModelData.listShellFaceIDs.append(i)
                tetList = TetraFunc.find_tetids_by_faceid(i)
                for tetId in tetList:
                    if tetId != curTetId:
                        #keep the tet with fixed or keep shell face
                        keep_tetrahedron(tetId, TetraFunc.get_faceids_from_tetid(tetId))
            else:
                print 'weird!!'
    if len(faceIDsInCurTet) < 4:
        #add the undefined dictFaces as TMP dictFaces
        vertexList = ModelData.dictTetrahedrons[curTetId].get_vids()
        faceList = []
        faceList.append((vertexList[0], vertexList[1], vertexList[2]))
        faceList.append((vertexList[0], vertexList[2], vertexList[3]))
        faceList.append((vertexList[0], vertexList[3], vertexList[1]))
        faceList.append((vertexList[1], vertexList[2], vertexList[3]))
        for f in faceList:
            isDefined = False
            for i in faceIDsInCurTet:
                if ModelData.dictFaces[i].is_equal_geometry(ClassFace.Class_face(f)):
                    isDefined = True
                    break
            if not isDefined :
                #add the tmp face and update the list of shell faces
                ModelData.listShellFaceIDs.append(ModelDataFuncs.add_face(ClassFace.Class_face(f)))
    #remove the tetrahedron
    ModelData.dictTetrahedrons.pop(curTetId)
示例#2
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")
示例#3
0
def update_stack():
    #init
    sortedTetIDStack = []

    #building a list with all the dictTetrahedrons attached with TMP dictFaces and their volume
    tmpTetIDs = {}
    for fkey in ModelData.listShellFaceIDs:
        #all the facets of a fixed tet are already fix
        if ModelData.dictFaces[fkey].get_tag() == ClassFace.TMP:
            #if (375 in ModelData.dictFaces[fkey].get_vids() or 382 in ModelData.dictFaces[fkey].get_vids()) and 371 in ModelData.dictFaces[fkey].get_vids() and 685 in ModelData.dictFaces[fkey].get_vids():
            #    aaa = 9
            tetList = TetraFunc.find_tetids_by_faceid(fkey, 1)
            tetid = tetList[0]
            tetShellFaceidList = TetraFunc.get_shell_faceids_from_tetid(tetid)
            tetFaceidList = TetraFunc.get_faceids_from_tetid(tetid)#all the known face of this tet
            #degree of freedom
            DoF = 4 - len(tetFaceidList)
            #Carving differential
            CDif = 0
            for f in tetFaceidList:
                if ModelData.dictFaces[f].get_tag() == ClassFace.TMP:
                    CDif = CDif + 1
            CDif = CDif - DoF
            #different configurations of heuristics
            #no heuristics (speedup)
            if not globalHeuristic['validity']:
                sortedTetIDStack.append((tetid,tetShellFaceidList, tetFaceidList))
                return sortedTetIDStack
            #with heuristics (normal)
            if not tmpTetIDs.has_key(tetid):
                if globalHeuristic['volume']:
                    tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, ModelData.dictTetrahedrons[tetid].get_volume()) #volume
                elif globalHeuristic['flatness']:
                    tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, ModelData.dictTetrahedrons[tetid].get_depth(ModelData.dictFaces[fkey].get_vids())/ModelData.dictFaces[fkey].get_area())#flatness
                elif globalHeuristic['depth']:
                    tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, ModelData.dictTetrahedrons[tetid].get_depth(ModelData.dictFaces[fkey].get_vids()))#depth
                elif globalHeuristic['distanceToCenter']:
                    #face center to the model center
                    vids = ModelData.dictFaces[fkey].get_vids()
                    midPt = SimpleMath.tuple_plus(ModelData.dictVertices[vids[0]], ModelData.dictVertices[vids[1]])
                    midPt = SimpleMath.tuple_plus(ModelData.dictVertices[vids[2]], midPt)
                    midPt = SimpleMath.tuple_numproduct(1.0/3.0, midPt)
                    tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, 1.0/SimpleMath.square_dist_point_to_point(midPt, [0.0, 0.0, 0.0]))#reciprocal distanceToCenter
                #tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, ModelData.dictFaces[fkey].get_area())#face area
                else:
                    tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif)#simplest
            else:
                #update the exisiting information
                if globalHeuristic['volume']:
                    volume = ModelData.dictTetrahedrons[tetid].get_volume()
                    if DoF < tmpTetIDs[tetid][3] or CDif > tmpTetIDs[tetid][4] or volume > tmpTetIDs[tetid][5]:
                        tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, 1.0/volume) #reciprocal volume
                elif globalHeuristic['flatness']:
                    flatness = ModelData.dictTetrahedrons[tetid].get_depth(ModelData.dictFaces[fkey].get_vids())/ModelData.dictFaces[fkey].get_area()
                    if DoF < tmpTetIDs[tetid][3] or CDif > tmpTetIDs[tetid][4] or flatness < tmpTetIDs[tetid][5]:
                        tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, flatness)#flatness
                elif globalHeuristic['depth']:
                    depth = ModelData.dictTetrahedrons[tetid].get_depth(ModelData.dictFaces[fkey].get_vids())
                    if DoF < tmpTetIDs[tetid][3] or CDif > tmpTetIDs[tetid][4] or depth < tmpTetIDs[tetid][5]:
                        tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, depth)#depth
                elif globalHeuristic['distanceToCenter']:
                    #face center to the model center
                    vids = ModelData.dictFaces[fkey].get_vids()
                    midPt = SimpleMath.tuple_plus(ModelData.dictVertices[vids[0]], ModelData.dictVertices[vids[1]])
                    midPt = SimpleMath.tuple_plus(ModelData.dictVertices[vids[2]], midPt)
                    midPt = SimpleMath.tuple_numproduct(1.0/3.0, midPt)
                    dist = 1.0/SimpleMath.square_dist_point_to_point(midPt, [0.0, 0.0, 0.0])
                    if DoF < tmpTetIDs[tetid][3] or CDif > tmpTetIDs[tetid][4] or dist > tmpTetIDs[tetid][5]: 
                        tmpTetIDs[tetid] = (tetShellFaceidList, tetFaceidList, ModelData.dictTetrahedrons[tetid].get_tag(), DoF, CDif, dist)#reciprocal distanceToCenter

    #sort the dict by the value (volume) and number of neigbour dictFaces into a desascending order
    if not globalHeuristic['volume'] and not globalHeuristic['flatness'] and not globalHeuristic['depth'] and not globalHeuristic['distanceToCenter']:
        for key in tmpTetIDs:
            sortedTetIDStack.append((key, tmpTetIDs[key][0], tmpTetIDs[key][1], tmpTetIDs[key][2], tmpTetIDs[key][3], tmpTetIDs[key][4]))
    else:
        for key in tmpTetIDs:
            sortedTetIDStack.append((key, tmpTetIDs[key][0], tmpTetIDs[key][1], tmpTetIDs[key][2], tmpTetIDs[key][3], tmpTetIDs[key][4], tmpTetIDs[key][5]))
        #sort firstly by fix/tmp, secondly by DoF, thirdly by Cd, lastly by volume
        sortedTetIDStack = sorted(sortedTetIDStack, key=lambda tet: tet[6], reverse = False)#smaller ratio first
        #sortedTetIDStack = sorted(sortedTetIDStack, key=lambda tet: tet[5], reverse = True)#large CDif first
        sortedTetIDStack = sorted(sortedTetIDStack, key=lambda tet: tet[4], reverse = False)#smaller DoF first
        sortedTetIDStack = sorted(sortedTetIDStack, key=lambda tet: tet[5], reverse = True)#large CDif first
        sortedTetIDStack = sorted(sortedTetIDStack, key=lambda tet: tet[3], reverse = True)#TMP tetrahedron first, then INF

    str_out = ("number of candidate tetrahedron: {}").format(len(sortedTetIDStack))
    os.sys.stdout.write(str_out + "\r")
    os.sys.stdout.flush()

    return sortedTetIDStack