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
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
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()
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
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
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