def simple_mesh(occshape, mesh_incremental_float=0.8): #TODO: figure out why is it that some surfaces do not work occshape = TopoDS_Shape(occshape) bt = BRep_Tool() BRepMesh_IncrementalMesh(occshape, mesh_incremental_float) occshape_face_list = fetch.geom_explorer(occshape, "face") occface_list = [] for occshape_face in occshape_face_list: location = TopLoc_Location() #occshape_face = modify.fix_face(occshape_face) facing = bt.Triangulation(occshape_face, location).GetObject() if facing: tab = facing.Nodes() tri = facing.Triangles() for i in range(1, facing.NbTriangles() + 1): trian = tri.Value(i) index1, index2, index3 = trian.Get() #print index1, index2, index3 pypt1 = fetch.occpt2pypt(tab.Value(index1)) pypt2 = fetch.occpt2pypt(tab.Value(index2)) pypt3 = fetch.occpt2pypt(tab.Value(index3)) #print pypt1, pypt2, pypt3 occface = make_polygon([pypt1, pypt2, pypt3]) occface_list.append(occface) return occface_list
def extrude_edge(occedge, pydirection, height): edge_midpt = calculate.edge_midpt(occedge) location_pt = modify.move_pt(edge_midpt, pydirection, height) edge2 = fetch.shape2shapetype(modify.move(edge_midpt, location_pt, occedge)) edge_wire = make_wire_frm_edges([occedge]) edge_wire2 = make_wire_frm_edges([edge2]) edgeface = make_loft_with_wires([edge_wire, edge_wire2]) facelist = fetch.geom_explorer(edgeface, "face") return facelist[0]
def fix_close_solid(occsolid): shape_fix = ShapeFix_Solid(occsolid) shape_fix.Perform() fix_solid = shape_fix.Solid() fix_solid_list = fetch.geom_explorer(fix_solid, "solid") if not fix_solid_list: return None else: fix_solid = fix_solid_list[0] breplib.OrientClosedSolid(fix_solid) return fix_solid
def extrude(occface, pydir, height): orig_pt = calculate.face_midpt(occface) dest_pt = modify.move_pt(orig_pt, pydir, height) moved_face = modify.move(orig_pt, dest_pt, occface) loft = make_loft([occface, moved_face]) face_list = fetch.geom_explorer(loft, "face") face_list.append(occface) face_list.append(moved_face) shell = make_shell_frm_faces(face_list)[0] solid = make_solid(shell) solid = modify.fix_close_solid(solid) return solid
def make_shell_frm_faces(occ_face_list, tolerance=1e-06): #make shell sewing = BRepBuilderAPI_Sewing() sewing.SetTolerance(tolerance) for f in occ_face_list: sewing.Add(f) sewing.Perform() sewing_shape = fetch.shape2shapetype(sewing.SewedShape()) #topo_dict = fetch.topos_frm_compound(sewing_shape) #shell_list = topo_dict["shell"] shell_list = fetch.geom_explorer(sewing_shape, "shell") return shell_list
def simplify_shell(occshell, tolerance=1e-06): #this will merge any coincidental faces into a single surfaces to simplify the geometry fshell = fix_shell_orientation(occshell) #get all the faces from the shell and arrange them according to their normals sfaces = fetch.geom_explorer(fshell, "face") nf_dict = calculate.grp_faces_acc2normals(sfaces) merged_fullfacelist = [] #merge all the faces thats share edges into 1 face for snfaces in nf_dict.values(): connected_face_shell_list = construct.make_shell_frm_faces( snfaces, tolerance=tolerance) if connected_face_shell_list: for shell in connected_face_shell_list: shell_faces = fetch.geom_explorer(shell, "face") merged_facelist = construct.merge_faces(shell_faces, tolerance=tolerance) if merged_facelist: merged_fullfacelist.extend(merged_facelist) else: merged_fullfacelist.extend(shell_faces) else: merged_fullfacelist.extend(snfaces) nmerged_face = len(merged_fullfacelist) if len(merged_fullfacelist) > 1: fshell2 = construct.make_shell_frm_faces(merged_fullfacelist, tolerance=tolerance) fshell2 = fix_shell_orientation(fshell2[0]) nfshell2_face = len(fetch.geom_explorer(fshell2, "face")) if nfshell2_face != nmerged_face: return occshell else: #if there is only one face it means its an open shell fshell2 = construct.make_shell(merged_fullfacelist) return fshell2
def flatten_shell_z_value(occshell, z=0): #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.shape2shapetype( uniform_scale(occshell, 1, 1, 0, b_mid_pt)) face_list = construct.simple_mesh(flatten_shell) #face_list = fetch.geom_explorer(flatten_shell,"face") 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: flatten_face = fetch.shape2shapetype( 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.geom_explorer(fused_shape, "face") merged_faces = construct.merge_faces(fused_face_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: flatten_vertex = fetch.geom_explorer( flatten_shell, "vertex") flatten_pts = fetch.vertex_list_2_point_list( flatten_vertex) flatten_pypts = fetch.occptlist2pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None except RuntimeError: flatten_vertex = fetch.geom_explorer(flatten_shell, "vertex") flatten_pts = fetch.vertex_list_2_point_list(flatten_vertex) flatten_pypts = fetch.occptlist2pyptlist(flatten_pts) dface_list = construct.delaunay3d(flatten_pypts) merged_faces = construct.merge_faces(dface_list) if len(merged_faces) == 1: flatten_face = fetch.shape2shapetype( 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.geom_explorer(flatten_shell, "vertex") flatten_pts = fetch.vertex_list_2_point_list(flatten_vertex) flatten_pypts = fetch.occptlist2pyptlist(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.shape2shapetype( move(b_mid_pt, dest_pt, merged_faces[0])) return flatten_face else: #construct.visualise([[occshell]],["WHITE"]) return None