def points_frm_edge(occedge): """ This function fetches a list of points from the OCCedge. The list of points consist of the starting and ending point of the edge. Parameters ---------- occedge : OCCedge The OCCedge to be examined. Returns ------- list of points : pyptlist The list of points extracted from the OCCedge. """ vertex_list = list(Topology.Topo(occedge).vertices()) point_list = modify.occvertex_list_2_occpt_list(vertex_list) pyptlist = modify.occpt_list_2_pyptlist(point_list) return pyptlist
def points_frm_solid(occsolid): """ This function fetches a list of points from the OCCsolid. Parameters ---------- occsolid : OCCsolid The OCCsolid to be examined. Returns ------- list of points : pyptlist The list of points extracted from the OCCsolid. """ verts = list(Topology.Topo(occsolid).vertices()) ptlist = modify.occvertex_list_2_occpt_list(verts) pyptlist = modify.occpt_list_2_pyptlist(ptlist) return pyptlist
def points_frm_wire(occwire): """ This function fetches a list of points from the OCCwire. The wire is constructed based on the list of points. TODO: WHEN DEALING WITH OPEN WIRE IT WILL NOT RETURN THE LAST VERTEX Parameters ---------- occwire : OCCwire The OCCwire to be examined. Returns ------- list of points : pyptlist The list of points extracted from the OCCwire. """ verts = list(Topology.WireExplorer(occwire).ordered_vertices()) point_list = modify.occvertex_list_2_occpt_list(verts) pyptlist = modify.occpt_list_2_pyptlist(point_list) return pyptlist
def write_2_stl2(occtopology, stl_filepath, is_meshed = True, linear_deflection = 0.8, angle_deflection = 0.5): """ This function writes a 3D model into STL format. This is different from write2stl as it uses the numpy-stl library. Parameters ---------- occtopology : OCCtopology Geometries to be written into STL. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface, OCCwire, OCCedge, OCCvertex stl_filepath : str The file path of the STL file. mesh_incremental_float : float, optional Default = 0.8. Returns ------- None : None The geometries are written to a STL file. """ import numpy as np from stl import mesh if is_meshed == False: tri_faces = construct.simple_mesh(occtopology, linear_deflection = linear_deflection, angle_deflection = angle_deflection) occtopology = construct.make_compound(tri_faces) face_list = fetch.topo_explorer(occtopology, "face") vlist = fetch.topo_explorer(occtopology, "vertex") occptlist = modify.occvertex_list_2_occpt_list(vlist) pyptlist = modify.occpt_list_2_pyptlist(occptlist) pyptlist = modify.rmv_duplicated_pts(pyptlist) vertices = np.array(pyptlist) face_index_2dlsit = [] for face in face_list: f_pyptlist = fetch.points_frm_occface(face) f_pyptlist.reverse() if len(f_pyptlist) == 3: index_list = [] for fp in f_pyptlist: p_index = pyptlist.index(fp) index_list.append(p_index) face_index_2dlsit.append(index_list) elif len(f_pyptlist) > 3: print "THE FACE HAS THE WRONG NUMBER OF VERTICES, IT HAS:", len(f_pyptlist), "VERTICES" tri_faces = construct.simple_mesh(face) for tri_face in tri_faces: tps = fetch.points_frm_occface(tri_face) index_list = [] for tp in tps: p_index = pyptlist.index(tp) index_list.append(p_index) face_index_2dlsit.append(index_list) # else: # print "THE FACE HAS THE WRONG NUMBER OF VERTICES, IT HAS:", len(f_pyptlist), "VERTICES" faces = np.array(face_index_2dlsit) shape_mesh = mesh.Mesh(np.zeros(faces.shape[0], dtype = mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): shape_mesh.vectors[i][j] = vertices[f[j],:] shape_mesh.save(stl_filepath)
def write_2_stl2(occtopology, stl_filepath, is_meshed=True, linear_deflection=0.8, angle_deflection=0.5): """ This function writes a 3D model into STL format. This is different from write2stl as it uses the numpy-stl library. Parameters ---------- occtopology : OCCtopology Geometries to be written into STL. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface, OCCwire, OCCedge, OCCvertex stl_filepath : str The file path of the STL file. mesh_incremental_float : float, optional Default = 0.8. Returns ------- None : None The geometries are written to a STL file. """ import numpy as np from stl import mesh if is_meshed == False: tri_faces = construct.simple_mesh(occtopology, linear_deflection=linear_deflection, angle_deflection=angle_deflection) occtopology = construct.make_compound(tri_faces) face_list = fetch.topo_explorer(occtopology, "face") vlist = fetch.topo_explorer(occtopology, "vertex") occptlist = modify.occvertex_list_2_occpt_list(vlist) pyptlist = modify.occpt_list_2_pyptlist(occptlist) pyptlist = modify.rmv_duplicated_pts(pyptlist) vertices = np.array(pyptlist) face_index_2dlsit = [] for face in face_list: f_pyptlist = fetch.points_frm_occface(face) f_pyptlist.reverse() if len(f_pyptlist) == 3: index_list = [] for fp in f_pyptlist: p_index = pyptlist.index(fp) index_list.append(p_index) face_index_2dlsit.append(index_list) elif len(f_pyptlist) > 3: print "THE FACE HAS THE WRONG NUMBER OF VERTICES, IT HAS:", len( f_pyptlist), "VERTICES" tri_faces = construct.simple_mesh(face) for tri_face in tri_faces: tps = fetch.points_frm_occface(tri_face) index_list = [] for tp in tps: p_index = pyptlist.index(tp) index_list.append(p_index) face_index_2dlsit.append(index_list) # else: # print "THE FACE HAS THE WRONG NUMBER OF VERTICES, IT HAS:", len(f_pyptlist), "VERTICES" faces = np.array(face_index_2dlsit) shape_mesh = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) for i, f in enumerate(faces): for j in range(3): shape_mesh.vectors[i][j] = vertices[f[j], :] shape_mesh.save(stl_filepath)
def flatten_shell_z_value(occshell, z=0): """ This function flatten the OCCshell to the Z-value specified. Parameters ---------- occshell : OCCshell The OCCshell to be flattened. z : float, optional The Z-value to flatten to. Default = 0. Returns ------- flatten shell : OCCshell The flatten OCCshell. """ face_list = fetch.faces_frm_solid(occshell) xmin, ymin, zmin, xmax, ymax, zmax = calculate.get_bounding_box(occshell) boundary_pyptlist = [[xmin, ymin, zmin], [xmax, ymin, zmin], [xmax, ymax, zmin], [xmin, ymax, zmin]] boundary_face = construct.make_polygon(boundary_pyptlist) b_mid_pt = calculate.face_midpt(boundary_face) #flatten_shell = fetch.topo2topotype(uniform_scale(occshell, 1, 1, 0, b_mid_pt)) face_list = construct.simple_mesh(occshell) f_face_list = [] for occface in face_list: f_face = flatten_face_z_value(occface, z=zmin) f_face_list.append(f_face) face_list = f_face_list flatten_shell = construct.make_compound(face_list) nfaces = len(face_list) merged_faces = construct.merge_faces(face_list) dest_pt = [b_mid_pt[0], b_mid_pt[1], z] #depending on how complicated is the shell we decide which is the best way to flatten it #1.) if it is an open shell and when everything is flatten it fits nicely as a flat surface if len(merged_faces) == 1: m_area = calculate.face_area(merged_faces[0]) if m_area > 1e-06: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face #2.) if it is a complex shell with less than 500 faces we fused and create a single surface if nfaces < 50: try: fused_shape = None fcnt = 0 for face in face_list: face_area = calculate.face_area(face) if not face_area < 0.001: if fcnt == 0: fused_shape = face else: #construct.visualise([[fused_shape], [face]], ['WHITE', 'RED']) fused_shape = construct.boolean_fuse(fused_shape, face) fcnt += 1 if fused_shape != None: fused_face_list = fetch.topo_explorer(fused_shape, "face") merged_faces = construct.merge_faces(fused_face_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: flatten_vertex = fetch.topo_explorer( flatten_shell, "vertex") flatten_pts = modify.occvertex_list_2_occpt_list( flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None except RuntimeError: flatten_vertex = fetch.topo_explorer(flatten_shell, "vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None #3.) if it is a complex shell with more than 500 faces we get the vertexes and create a triangulated srf with delaunay #and merge all the faces to make a single surface if nfaces >= 50: flatten_vertex = fetch.topo_explorer(flatten_shell, "vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) #flatten_pypts = rmv_duplicated_pts_by_distance(flatten_pypts, tolerance = 1e-04) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None
def flatten_shell_z_value(occshell, z=0): """ This function flatten the OCCshell to the Z-value specified. Parameters ---------- occshell : OCCshell The OCCshell to be flattened. z : float, optional The Z-value to flatten to. Default = 0. Returns ------- flatten shell : OCCshell The flatten OCCshell. """ face_list = fetch.faces_frm_solid(occshell) xmin,ymin,zmin,xmax,ymax,zmax = calculate.get_bounding_box(occshell) boundary_pyptlist = [[xmin,ymin,zmin], [xmax,ymin,zmin], [xmax,ymax,zmin], [xmin,ymax,zmin]] boundary_face = construct.make_polygon(boundary_pyptlist) b_mid_pt = calculate.face_midpt(boundary_face) #flatten_shell = fetch.topo2topotype(uniform_scale(occshell, 1, 1, 0, b_mid_pt)) face_list = construct.simple_mesh(occshell) f_face_list = [] for occface in face_list: f_face = flatten_face_z_value(occface, z=zmin) f_face_list.append(f_face) face_list = f_face_list flatten_shell = construct.make_compound(face_list) nfaces = len(face_list) merged_faces = construct.merge_faces(face_list) dest_pt = [b_mid_pt[0], b_mid_pt[1], z] #depending on how complicated is the shell we decide which is the best way to flatten it #1.) if it is an open shell and when everything is flatten it fits nicely as a flat surface if len(merged_faces) == 1: m_area = calculate.face_area(merged_faces[0]) if m_area > 1e-06: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face #2.) if it is a complex shell with less than 500 faces we fused and create a single surface if nfaces < 50: try: fused_shape = None fcnt = 0 for face in face_list: face_area = calculate.face_area(face) if not face_area < 0.001: if fcnt == 0: fused_shape = face else: #construct.visualise([[fused_shape], [face]], ['WHITE', 'RED']) fused_shape = construct.boolean_fuse(fused_shape, face) fcnt+=1 if fused_shape!=None: fused_face_list = fetch.topo_explorer(fused_shape, "face") merged_faces = construct.merge_faces(fused_face_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: flatten_vertex = fetch.topo_explorer(flatten_shell,"vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None except RuntimeError: flatten_vertex = fetch.topo_explorer(flatten_shell,"vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None #3.) if it is a complex shell with more than 500 faces we get the vertexes and create a triangulated srf with delaunay #and merge all the faces to make a single surface if nfaces >=50: flatten_vertex = fetch.topo_explorer(flatten_shell,"vertex") flatten_pts = modify.occvertex_list_2_occpt_list(flatten_vertex) flatten_pypts = modify.occpt_list_2_pyptlist(flatten_pts) #flatten_pypts = rmv_duplicated_pts_by_distance(flatten_pypts, tolerance = 1e-04) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.topo2topotype(move(b_mid_pt, dest_pt,merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None