Beispiel #1
0
 def get_area(self):
     pt1 = ModelData.dictVertices[self.__v[0]]
     pt2 = ModelData.dictVertices[self.__v[1]]
     pt3 = ModelData.dictVertices[self.__v[2]]
     pt1pt2 = SimpleMath.tuple_minus(pt2, pt1)
     pt1pt3 = SimpleMath.tuple_minus(pt3, pt1)
     return 0.5 * SimpleMath.vector_length_3(SimpleMath.cross_product_3(pt1pt2, pt1pt3))
Beispiel #2
0
 def get_depth(self, vIds):
     #check
     for v in vIds:
         if v not in self.__v:
             return -1
     #
     for v in self.__v:
         if v not in vIds:
             pt = ModelData.dictVertices[v]
             return SimpleMath.sqrt(SimpleMath.square_dist_point_to_plane(pt, ModelData.dictVertices[vIds[0]],  ModelData.dictVertices[vIds[1]],  ModelData.dictVertices[vIds[2]]))
Beispiel #3
0
def create_orientated_vids(vids, normal):
    if SimpleMath.vector_length_3Ex(normal) < SimpleMath.Tol:
        print ("Degeneracy!!")
        return vids
    fNormal = SimpleMath.get_face_normal(
        [ModelData.dictVertices[vids[0]], ModelData.dictVertices[vids[1]], ModelData.dictVertices[vids[2]]]
    )
    if SimpleMath.dot_product_3(normal, fNormal) > 0:
        return vids
    else:
        return (vids[1], vids[0], vids[2])
Beispiel #4
0
def coplaner_neighbors(fid, fNormal, tag):
    vertexIds = ModelData.dictFaces[fid].get_vids()
    for i in range(0, 3):
        j = 0
        if i < 2:
            j = i + 1
        face = CarveFunc.get_neighbor_shellface([vertexIds[i], vertexIds[j]], fid)
        if face not in tag and face is not None:
            newVertids = ModelData.dictFaces[face].get_vids()
            Normal = SimpleMath.get_face_normal([ModelData.dictVertices[newVertids[0]], ModelData.dictVertices[newVertids[1]], ModelData.dictVertices[newVertids[2]]])
            if SimpleMath.vector_length_3(Normal) > SimpleMath.Tol and SimpleMath.dot_product_3(fNormal, Normal) > SimpleMath.NeighborAngle:
                tag.append(face)
                #only select the adjacent neighbors
                #coplaner_neighbors(face, Normal, tag)
Beispiel #5
0
def constraint_5(curTetId, faceIDsInCurTet):
    bIsInterior = False
    for i in faceIDsInCurTet:
        if ModelData.dictFaces[i].get_tag() == ClassFace.FIX:
            #normal check
            vIds = ModelData.dictFaces[i].get_vids()
            vectorNormal = SimpleMath.get_face_normal([ModelData.dictVertices[vIds[0]], ModelData.dictVertices[vIds[1]], ModelData.dictVertices[vIds[2]]])
            for v in ModelData.dictTetrahedrons[curTetId].get_vids():
                if v not in vIds:
                    #test whether the tetrahedron is in the interior
                    vectorTest = SimpleMath.tuple_minus(ModelData.dictVertices[v], ModelData.dictVertices[vIds[0]]);
                    if SimpleMath.dot_product_3(vectorNormal , vectorTest) < 0:
                        #find one inside
                        return True
    return bIsInterior
Beispiel #6
0
def keep_tetrahedron(curTetId, faceIDsInCurTet):
    #use the tag of the tetrahedron
    if ModelData.dictTetrahedrons[curTetId].get_tag == ClassFace.FIX:
        return
    #set the tag
    ModelData.dictTetrahedrons[curTetId].set_tag(ClassFace.FIX)
    #deal with all the known faces
    for j in faceIDsInCurTet:
        if  ModelData.dictFaces[j].get_tag() != ClassFace.FIX:
            ModelData.dictFaces[j].set_tag(ClassFace.KEEP)
    #add the unkown faces and define them as KEEP (in order to seperate KEEP and FIX)
    if len(faceIDsInCurTet) < 4:
        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 :
                tetNormal = []
                for v in vertexList:
                    if v not in f:
                        #facing outwards
                        tetNormal = SimpleMath.tuple_minus(ModelData.dictVertices[f[0]], ModelData.dictVertices[v])
                        break
                #do not have to consider semantics at this moment
                fId = ModelDataFuncs.add_face(ClassFace.Class_face(ModelDataFuncs.create_orientated_vids(f, tetNormal), ClassFace.KEEP))
Beispiel #7
0
def deduce_semantics_of_face(fid):
    #detect coplaner neighbours
    vertexList = ModelData.dictFaces[fid].get_vids()
    curNormal = SimpleMath.get_face_normal([ModelData.dictVertices[vertexList[0]], ModelData.dictVertices[vertexList[1]], ModelData.dictVertices[vertexList[2]]])
    if SimpleMath.vector_length_3(curNormal) > SimpleMath.Tol:
        #Get the normals of neighbors of this face
        tag = [fid]
        coplaner_neighbors(fid, curNormal, tag)
        #statistic of dominant semantics within tagged faces
        counterSemantics = Counter()
        for fid in tag:
            counterSemantics[(ModelData.dictFaces[fid].get_id(), ModelData.dictFaces[fid].get_type())] += 1
        res = counterSemantics.most_common(2)
        #get the semantics
        strId = ''
        strType = ''
        if len(res) == 1 and res[0][0] == ('', ''):
            #deduce the semantics based on direction 
            strId = ModelDataFuncs.generate_uuid()
            angle = SimpleMath.dot_product_3(curNormal, (0.0, 0.0, 1.0))
            if angle <= 1 and angle > 0.087:
                #roof 0 to 85
                strType = 'BUILDING_ROOF_SURFACE'
            elif angle < -0.999:
                #ground -0 to -1
                strType = 'BUILDING_GROUND_SURFACE'
            else:
                #wall
                strType = 'BUILDING_WALL_SURFACE'
        else:
            if res[0][0] != ('', ''):
                strId = res[0][0][0]
                strType = res[0][0][1]
            elif res[1][0] != ('', ''):
                strId = res[1][0][0]
                strType = res[1][0][1]
        #assign the semantics to all the raw face in tag
        for f in tag:
            if ModelData.dictFaces[f].get_id() == '' :
                 ModelData.dictFaces[f].set_id(strId)
            if ModelData.dictFaces[f].get_type() == '' :
                 ModelData.dictFaces[f].set_type(strType)
    else:
        ModelData.dictFaces[fid].set_id(ModelDataFuncs.generate_uuid())
        ModelData.dictFaces[fid].set_type('BUILDING_WALL_SURFACE')
Beispiel #8
0
def boundary_of_coplaner_neighbors(fid, fNormal, fVisited, listUnbounded, listSeedFace):
    vertexIds = ModelData.dictFaces[fid].get_vids()
    for i in range(0, 3):
        j = 0
        if i < 2:
            j = i + 1
        #test the adjacent face
        face = get_neighbor_shellface((vertexIds[i], vertexIds[j]), fid)
        #test the edge
        code = is_edge_open_fix_boundary((vertexIds[i], vertexIds[j]), fid, face)
        if code == 1:
            #is a open fixed boundary then get one unvisited face as a seed
            if ModelData.dictFaces[face].get_tag() != ClassFace.FIX and face not in fVisited:
                if TetraFunc.get_dihedral_cos_angle(ModelData.dictFaces[face].get_vids(), ModelData.dictFaces[fid].get_vids()) > SimpleMath.NeighborAngle:
                    if face not in listSeedFace:
                        listSeedFace.append(face)
        elif code == 2:
            #is a close fixed boundary
            if not globalSealConcave:
                return False
        else:
            #not a boundary
            newVertids = ModelData.dictFaces[face].get_vids()
            Normal = SimpleMath.get_face_normal((ModelData.dictVertices[newVertids[0]], ModelData.dictVertices[newVertids[1]], ModelData.dictVertices[newVertids[2]]))
            if (SimpleMath.vector_length_3(Normal) > SimpleMath.Tol and abs(SimpleMath.dot_product_3(fNormal, Normal)) > SimpleMath.NeighborAngle) or \
                SimpleMath.vector_length_3(Normal) < SimpleMath.Tol:
                if face not in fVisited:
                    fVisited.append(face)
                    
                    if SimpleMath.vector_length_3(Normal) < SimpleMath.Tol:
                        if not boundary_of_coplaner_neighbors(face, fNormal, fVisited, listUnbounded, listSeedFace):
                            return False
                    else:
                        #note: False should be not be modified to not
                        if False == boundary_of_coplaner_neighbors(face, Normal, fVisited, listUnbounded, listSeedFace):
                            return False
                else:
                    if face in listUnbounded:
                    #if in, test if it is connected to an unbounded face
                        return False
            else:
                if face not in fVisited:
                    fVisited.append(face)
                return False
Beispiel #9
0
def discard_illshaped_faces():
    iCount = 0
    for key in ModelData.dictFaces:
        if ModelData.global_DISCARD_TINY:
            if ModelData.dictFaces[key].get_area() < ModelData.global_TOL_AREA_DISCARD:
                pre_remove_face_by_faceids([key])
                iCount = iCount + 1
                continue
        if ModelData.global_DISCARD_DEG:
            vert0 = ModelData.dictVertices[ModelData.dictFaces[key].get_vids()[0]]
            vert1 = ModelData.dictVertices[ModelData.dictFaces[key].get_vids()[1]]
            vert2 = ModelData.dictVertices[ModelData.dictFaces[key].get_vids()[2]]
            if SimpleMath.vector_length_3(SimpleMath.get_face_normal([vert0, vert1, vert2])) < SimpleMath.Tol:
                pre_remove_face_by_faceids([key])
                iCount = iCount + 1
    #
    remove_faces()
    clean_unreferenced_vertices()
    return iCount
Beispiel #10
0
def sort_facesgroup_by_size(listFaceGroup):
    listSize = []
    for list in listFaceGroup:
        bbox = ModelDataFuncs.get_bbox_faces(list)
        listSize.append(SimpleMath.square_dist_point_to_point(bbox[0], bbox[1]), list)
    listSize.sort()
    #
    listFaceGroup = []
    for list in listSize:
        listFaceGroup.append(list[1])
    return listFaceGroup
Beispiel #11
0
def find_face_by_mapping(tris):
    # the mid point
    centerPoint = SimpleMath.tuple_numproduct(
        1.0 / 3.0,
        SimpleMath.tuple_plus(
            ModelData.dictVertices[tris[0]],
            SimpleMath.tuple_plus(ModelData.dictVertices[tris[1]], ModelData.dictVertices[tris[2]]),
        ),
    )
    # mapping by distance
    for fKey in ModelData.dictFaces:
        fVertices = ModelData.dictFaces[fKey].get_vids()
        if SimpleMath.is_point_in_triangle_3(
            centerPoint,
            (
                ModelData.dictVertices[fVertices[0]],
                ModelData.dictVertices[fVertices[1]],
                ModelData.dictVertices[fVertices[2]],
            ),
        ):
            return fKey
Beispiel #12
0
def writer_obj(FILEPATH1):
    if len(ModelData.dictVertices) > 0 and len(ModelData.dictFaces) > 0:
        try:
            f_obj1 = file(FILEPATH1, "w")
        except:
            print ("Invalide file: " + FILEPATH1)
            raise Exception

        # write the ModelData.dictFaces and ModelData.dictVertices
        f_obj1.write("# Created by obj2poly from ModelData.ModelData.dictFaces and ModelData.ModelData.dictVertices \n")
        f_obj1.write("# Object\n")

        # indicemap
        verticeMap = {}
        iVertCount = 1
        # ModelData.dictVertices
        for vert in ModelData.dictVertices:
            verticeMap[iVertCount] = vert
            iVertCount += 1
            f_obj1.write("v ")
            # f_obj1.write(str(SimpleMath.tuple_plus(SimpleMath.tuple_numproduct(1/ ModelData.scaleVertex, ModelData.dictVertices[vert]), ModelData.centerVertex)).replace(',', '')[1:-1] + '\n')
            f_obj1.write(
                str(SimpleMath.tuple_plus(ModelData.dictVertices[vert], ModelData.centerVertex)).replace(",", "")[1:-1]
                + "\n"
            )
        f_obj1.write("# ")
        f_obj1.write(str(len(ModelData.dictVertices)) + " ")
        f_obj1.write("ModelData.dictVertices\n")

        # ModelData.dictFaces
        for face in ModelData.dictFaces:
            # correct indice mapping
            f = []
            for vert in ModelData.dictFaces[face].get_vids():
                f.append(find_key_from_dict_by_exact_value(verticeMap, vert))
            f_obj1.write("f ")
            f_obj1.write(str(f).replace(",", "")[1:-1] + "\n")
        f_obj1.write("# ")
        f_obj1.write(str(len(ModelData.dictFaces)) + " ")
        f_obj1.write("ModelData.dictFaces\n")
        f_obj1.close()
        # end __WriteObj
    return True
Beispiel #13
0
def writer_poly_with_semantics(str_filepath):
    fout = file(str_filepath, "w")
    # write the model information
    fout.write("# " + ModelData.strModelID + "\n")
    fout.write("# " + ModelData.isSolid + "\n")
    # write all the points
    fout.write(str(len(ModelData.dictVertices)) + "  3 0 0\n")
    iVertCount = 0
    # ModelData.dictVertices
    verticeMap = {}
    for vert in ModelData.dictVertices:
        verticeMap[iVertCount] = vert
        fout.write(str(iVertCount) + "  ")
        fout.write(
            str(SimpleMath.tuple_plus(ModelData.dictVertices[vert], ModelData.centerVertex)).replace(",", "")[1:-1]
            + "\n"
        )
        iVertCount += 1
    # write ModelData.dictFaces and remapping the indices
    fout.write(str(len(ModelData.dictFaces)) + " 0\n")
    for face in ModelData.dictFaces:
        # write the face information
        fout.write("1 0 ")
        if ModelData.dictFaces[face].get_id() != "":
            fout.write("# " + ModelData.dictFaces[face].get_id() + " ")
        else:
            aaa = 99
        if ModelData.dictFaces[face].get_type() != "":
            fout.write("# " + ModelData.dictFaces[face].get_type())
        fout.write("\n")
        # correct indice mapping
        f = []
        for vert in ModelData.dictFaces[face].get_vids():
            f.append(find_key_from_dict_by_exact_value(verticeMap, vert))
        fout.write("3  ")
        fout.write(str(f).replace(",", "")[1:-1] + "\n")
    fout.write("0\n")
    fout.write("0\n")
    fout.close()
Beispiel #14
0
def reader_poly_with_semantics(str_filepath):
    fin = file(str_filepath, "r")
    # read the first line and try to extract semantics
    strFirstLine = fin.readline().split()
    if strFirstLine[0] == "#":
        # read the building id
        ModelData.strModelID = strFirstLine[1]
        # whether the geometry is a solid:1 or a multisurface:0
        ModelData.isSolid = fin.readline().split()[1]
        # the point information
        strFirstLine = int(fin.readline().split()[0])
    else:
        # no semanics
        ModelData.strModelID = "-1"
        # we assume it is a solid
        ModelData.isSolid = "1"
        # the point information
        strFirstLine = int(strFirstLine[0])
    # read all the points
    for i in range(strFirstLine):
        vertList = map(float, fin.readline().split()[1:4])
        add_vertexEx((vertList[0], vertList[1], vertList[2]))
    # read each face
    nof = int(fin.readline().split()[0])
    strPolygonid = ""
    strPolygontype = ""
    for i in range(nof):
        strPolygoninfo = fin.readline().split()
        numRings = int(strPolygoninfo[0])
        if numRings != 1:
            print ("The input has not been tesselated")
            return False
        if len(strPolygoninfo) >= 4:
            strPolygonid = strPolygoninfo[3]
        if len(strPolygoninfo) >= 6:
            strPolygontype = strPolygoninfo[5]
        oring = map(int, fin.readline().split())
        if len(oring) > 4:
            print ("The input has not been tesselated")
            return False
        oring.pop(0)
        if len(oring) == 3:
            add_face(Class_face((oring[0], oring[1], oring[2]), ClassFace.FIX, strPolygonid, strPolygontype))

    # check the content
    if len(ModelData.dictFaces) == 0 or len(ModelData.dictVertices) == 0:
        print "Invalid Poly file!\n"
        return False
    else:
        print ("Remove " + str(nof - len(ModelData.dictFaces)) + " invalid Faces")
        print ("Read " + str(len(ModelData.dictFaces)) + " Faces and " + str(len(ModelData.dictVertices)) + " Vertices")
    fin.close()

    # optimise the coordinates by translate and scale
    for key in ModelData.dictVertices:
        ModelData.centerVertex = SimpleMath.tuple_plus(ModelData.centerVertex, ModelData.dictVertices[key])
    ModelData.centerVertex = SimpleMath.tuple_numproduct(1.0 / len(ModelData.dictVertices), ModelData.centerVertex)
    for key in ModelData.dictVertices:
        ModelData.dictVertices[key] = SimpleMath.tuple_minus(ModelData.dictVertices[key], ModelData.centerVertex)
    if ModelData.global_DO_TRUNCATE:
        truncate_verts(ModelData.global_TOL_TRUNCATE)
    print ("--Eliminate degeneracies")
    clean_duplicated_vertices()
    print ("{} illshaped ModelData.dictFaces are removed").format(discard_illshaped_faces())
    print (
        "After cleaning redundant ModelData.dictVertices there are "
        + str(len(ModelData.dictFaces))
        + " Faces and "
        + str(len(ModelData.dictVertices))
        + " Vertices"
    )
    return True
Beispiel #15
0
 def get_volume(self):
     f = ClassFace.Class_face((self.__v[0], self.__v[1], self.__v[2]))
     pt = ModelData.dictVertices[self.__v[3]]
     return (1.0/3) * f.get_area() * SimpleMath.sqrt(SimpleMath.square_dist_point_to_plane(pt, ModelData.dictVertices[f.get_vids()[0]],  ModelData.dictVertices[f.get_vids()[1]],  ModelData.dictVertices[f.get_vids()[2]]))
Beispiel #16
0
import SimpleMath as mod
print(mod.__name__)
print(mod.__doc__)
print()
print(mod.addition.__name__)
print(mod.addition.__doc__)
print()
print(mod.subtraction.__name__)
print(mod.subtraction.__doc__)
print()
print(mod.addition(12, 7))
print(mod.subtraction(12, 7))
Beispiel #17
0
def constraint_3(fid):
    #Get the normal of vertexList
    vertexList = ModelData.dictFaces[fid].get_vids()
    curNormal = SimpleMath.get_face_normal((ModelData.dictVertices[vertexList[0]], ModelData.dictVertices[vertexList[1]], ModelData.dictVertices[vertexList[2]]))
    if SimpleMath.vector_length_3(curNormal) > SimpleMath.Tol:
        #the list of lists of bounded faces
        listBoundedFaceGroup = []
        #all the visited faces
        listAllVisitedFids = []
        #the seed faces
        listSeedFace = []
        #the previously visited faces
        listLastVisitedFace = []
        #the Unbounded faces
        listUnboundedFaces = []
        while (fid >= 0):
            listAllVisitedFids.append(fid)
            #note: False should be not be modified to not
            if False == boundary_of_coplaner_neighbors(fid, curNormal, listAllVisitedFids, listUnboundedFaces, listSeedFace):
                #extracted the unbounded faces
                for f in listAllVisitedFids:
                    if f not in listLastVisitedFace:
                        listUnboundedFaces.append(f)
                #
                for f in listAllVisitedFids:
                    if f not in listLastVisitedFace:
                        listLastVisitedFace.append(f)
            else:
                #extracted the bounded faces
                fGrouped = []
                for f in listAllVisitedFids:
                    if f not in listLastVisitedFace:
                        fGrouped.append(f)
                listBoundedFaceGroup.append(fGrouped)
                #
                for f in listAllVisitedFids:
                    if f not in listLastVisitedFace:
                        listLastVisitedFace.append(f)
            #
            for f in listSeedFace:
                if f in listLastVisitedFace:
                    listSeedFace.remove(f)
            #
            if len(listSeedFace) > 0:
                fid = listSeedFace.pop(0)
            else:
                fid = -1
            #check the outer neigbour faces
            if fid != -1:
                vertexList = ModelData.dictFaces[fid].get_vids()
                curNormal = SimpleMath.get_face_normal((ModelData.dictVertices[vertexList[0]], ModelData.dictVertices[vertexList[1]], ModelData.dictVertices[vertexList[2]]))
             
        if len(listBoundedFaceGroup) > 1:
            #TODO: find the nesting order of groups
            #now keep them all
            listKeepFace = []
            for iGroup in listBoundedFaceGroup:
                listKeepFace += iGroup
            #reporder the group by nesting order
            #listFaceGroup = sort_facesgroup_by_size(listFaceGroup)
            ##extact the faces to be kept
            #listKeepFace = []
            #if len(listFaceGroup) % 2 == 0:
            #    #the odd groups should be kept
            #    listFaceGroup = listFaceGroup[1::2]
            #    for iGroup in listFaceGroup:
            #        listKeepFace += listFaceGroup[iGroup]
            #else:
            #    #the even groups should be kept
            #    listFaceGroup = listFaceGroup[0::2]
            #    for iGroup in listFaceGroup:
            #        listKeepFace += listFaceGroup[iGroup]
            #keep all the tetrahedra
            return True, listKeepFace, listUnboundedFaces
        elif len(listBoundedFaceGroup) == 1:
            #keep all the tetrahedra
            return True, listBoundedFaceGroup[0], listUnboundedFaces
        else:
            return False, [], listUnboundedFaces

    else:
        print ('Degeneracy!')
        return False, [], []
Beispiel #18
0
def optimise_illshaped_shellfaces():
    iCount = 0
    for key in ModelData.listShellFaceIDs:
        if key not in ModelData.dictFaces:
            continue
        if (
            ModelData.global_OPTIMAL_SHP
            and ModelData.dictFaces[key].get_tag() != ClassFace.FLIP
            and ModelData.dictFaces[key].get_area() < ModelData.global_TOL_AREA_DISCARD
        ):
            print key
            vert0 = ModelData.dictVertices[ModelData.dictFaces[key].get_vids()[0]]
            vert1 = ModelData.dictVertices[ModelData.dictFaces[key].get_vids()[1]]
            vert2 = ModelData.dictVertices[ModelData.dictFaces[key].get_vids()[2]]
            # face collapse or flip
            # calculate vectors
            vector01 = SimpleMath.tuple_minus(vert0, vert1)
            length01 = SimpleMath.vector_length_3(vector01)
            if length01 > SimpleMath.Tol:
                vector01 = SimpleMath.tuple_numproduct(1.0 / length01, vector01)
            else:
                iCount += 1
                collapse_edge(ModelData.dictFaces[key].get_vids()[0], ModelData.dictFaces[key].get_vids()[1])
                continue

            vector21 = SimpleMath.tuple_minus(vert2, vert1)
            length21 = SimpleMath.vector_length_3(vector21)
            if length21 > SimpleMath.Tol:
                vector21 = SimpleMath.tuple_numproduct(1.0 / length21, vector21)
            else:
                iCount += 1
                collapse_edge(ModelData.dictFaces[key].get_vids()[2], ModelData.dictFaces[key].get_vids()[1])
                continue

            vector02 = SimpleMath.tuple_minus(vert0, vert2)
            length02 = SimpleMath.vector_length_3(vector02)
            if length02 > SimpleMath.Tol:
                vector02 = SimpleMath.tuple_numproduct(1.0 / length02, vector02)
            else:
                iCount += 1
                collapse_edge(ModelData.dictFaces[key].get_vids()[0], ModelData.dictFaces[key].get_vids()[2])
                continue

            # calculate angles
            Ang012 = SimpleMath.dot_product_3(vector01, vector21)
            Ang102 = SimpleMath.dot_product_3(vector01, vector02)
            vector12 = SimpleMath.tuple_numproduct(-1, vector21)
            Ang021 = SimpleMath.dot_product_3(vector02, vector12)
            # cos value
            if Ang012 < ModelData.global_TOL_LARGEST_ANGLE:
                # flip 20
                iCount += 1
                flip_edge(ModelData.dictFaces[key].get_vids()[2], ModelData.dictFaces[key].get_vids()[0])
            elif Ang102 < ModelData.global_TOL_LARGEST_ANGLE:
                # flip 12
                iCount += 1
                flip_edge(ModelData.dictFaces[key].get_vids()[1], ModelData.dictFaces[key].get_vids()[2])
            elif Ang021 < ModelData.global_TOL_LARGEST_ANGLE:
                # flip 01
                iCount += 1
                flip_edge(ModelData.dictFaces[key].get_vids()[0], ModelData.dictFaces[key].get_vids()[1])
    #
    # clean_unreferenced_vertices()
    print ("{} illshaped ModelData.dictFaces are optimized").format(iCount)
    if iCount > 0:
        return True
    else:
        return False
Beispiel #19
0
def reader_obj(FILEPATH):
    try:
        f_obj = file(FILEPATH, "r")
    except:
        print ("Invalide file: " + MIDFILEPATH)
        return False
    # read vertics and ModelData.dictFaces
    statFace = 0
    for line in f_obj:
        if line.startswith("v") and line[1] == " ":
            line = line[1:-1].strip()
            vertList = map(float, line.split(" "))
            add_vertexEx([vertList[0], vertList[1], vertList[2]])
        elif line.startswith("f") and line[1] == " ":
            indexList = []
            # to filter out the /
            for index in line[1:-1].strip().split(" "):
                indexList.append(index.split("/")[0])
            statFace = statFace + 1
            if len(indexList) > 2:
                # index - 1
                indexList = [int(i) - 1 for i in indexList]
                add_face(Class_face((indexList[0], indexList[1], indexList[2]), ClassFace.FIX))
    # check the content
    if len(ModelData.dictFaces) == 0 or len(ModelData.dictVertices) == 0:
        print "Invalid Obj file!\n"
        return False
    else:
        print ("Remove " + str(statFace - len(ModelData.dictFaces)) + " invalid ModelData.dictFaces")
        print (
            "Read "
            + str(len(ModelData.dictFaces))
            + " ModelData.dictFaces and "
            + str(len(ModelData.dictVertices))
            + " ModelData.dictVertices"
        )

    f_obj.close()

    # optimise the coordinates by translate and scale
    for key in ModelData.dictVertices:
        ModelData.centerVertex = SimpleMath.tuple_plus(ModelData.centerVertex, ModelData.dictVertices[key])
    ModelData.centerVertex = SimpleMath.tuple_numproduct(1.0 / len(ModelData.dictVertices), ModelData.centerVertex)
    # maxpt = [-9999999999.0, -9999999999.0, -9999999999.0]
    # minpt = [9999999999.0, 9999999999.0, 9999999999.0]
    for key in ModelData.dictVertices:
        ModelData.dictVertices[key] = SimpleMath.tuple_minus(ModelData.dictVertices[key], ModelData.centerVertex)
        # if ModelData.dictVertices[key][0] > maxpt[0]:
        #    maxpt[0] = ModelData.dictVertices[key][0]
        # if ModelData.dictVertices[key][1] > maxpt[1]:
        #    maxpt[1] = ModelData.dictVertices[key][1]
        # if ModelData.dictVertices[key][2] > maxpt[2]:
        #    maxpt[2] = ModelData.dictVertices[key][2]

        # if ModelData.dictVertices[key][0] < minpt[0]:
        #    minpt[0] = ModelData.dictVertices[key][0]
        # if ModelData.dictVertices[key][1] < minpt[1]:
        #    minpt[1] = ModelData.dictVertices[key][1]
        # if ModelData.dictVertices[key][2] < minpt[2]:
        #    minpt[2] = ModelData.dictVertices[key][2]
    # ModelData.scaleVertex = ModelData.scaleVertex / SimpleMath.vector_length_3(SimpleMath.tuple_minus(maxpt, minpt))
    # for key in ModelData.dictVertices:
    #    ModelData.dictVertices[key] = SimpleMath.tuple_numproduct(ModelData.scaleVertex, ModelData.dictVertices[key])
    if ModelData.global_DO_TRUNCATE:
        truncate_verts(ModelData.global_TOL_TRUNCATE)
    print (">>>>>>Eliminate degeneracies...")
    clean_duplicated_vertices()
    print ("{} illshaped ModelData.dictFaces are removed").format(discard_illshaped_faces())
    print (
        "After cleaning redundant ModelData.dictVertices there are "
        + str(len(ModelData.dictFaces))
        + " ModelData.dictFaces and "
        + str(len(ModelData.dictVertices))
        + " ModelData.dictVertices"
    )
    return True
Beispiel #20
0
def get_bbox_vertices(vList):
    ptList = []
    for v in vList:
        ptList.append(ModelData.dictVertices[v])
    return SimpleMath.get_bbox_of_points(ptList)
Beispiel #21
0
def get_dihedral_cos_angle(vids1, vids2):
    fNormal1 =  SimpleMath.get_face_normal((ModelData.dictVertices[vids1[0]], ModelData.dictVertices[vids1[1]], ModelData.dictVertices[vids1[2]]))
    fNormal2 =  SimpleMath.get_face_normal((ModelData.dictVertices[vids2[0]], ModelData.dictVertices[vids2[1]], ModelData.dictVertices[vids2[2]]))
    return SimpleMath.dot_product_3(fNormal1, fNormal2)
Beispiel #22
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