def map_face_before_and_after_feat(base, feature_maker): ''' input base: TopoDS_Shape feature_maker: BRepFeat_MakePrism output fmap: {TopoDS_Face:TopoDS_Face} ''' fmap = {} base_faces = occ_utils.list_face(base) for face in base_faces: if feature_maker.IsDeleted(face): continue fmap[face] = [] modified = feature_maker.Modified(face) if modified.IsEmpty(): fmap[face].append(face) continue occ_it = TopTools_ListIteratorOfListOfShape(modified) while occ_it.More(): a_shape = occ_it.Value() assert a_shape.ShapeType() == TopAbs_FACE fmap[face].append(topods.Face(a_shape)) occ_it.Next() return fmap
def __call__(self, plane: gp.gp_Pln, vertex=None, edge_dict=None, **kwargs): splt = BRepFeat_SplitShape() if isinstance(self._base, TopoDS_Shape): base_shape = self._base else: base_shape = self._base.Shape() splt.Init(base_shape) sect = BRepAlgoAPI_Section(base_shape, plane, False) sect.ComputePCurveOn1(True) sect.Approximation(True) sect.Build() self.cutting_edge = sect.Shape() ancestors = set() new_faces = [] edge_iter = TopExp_Explorer(self.cutting_edge, TopAbs_EDGE) while edge_iter.More(): base_iter = TopExp_Explorer(base_shape, TopAbs_FACE) curr_edge = edge_iter.Current() while base_iter.More(): curr_face = base_iter.Current() if sect.HasAncestorFaceOn1(curr_edge, curr_face): k, v = hash(curr_face), hash(curr_edge) if (k, v) not in self.ancestors: ancestors.add((k, v)) e = topods.Edge(curr_edge) f = topods.Face(curr_face) splt.Add(e, f) # todo - only add the closest one !!!! new_faces.append(f) self.added.append(e) break # if sect.HasAncestorFaceOn2(curr_edge, curr_face): # print('has2', curr_edge, curr_face) # pass base_iter.Next() edge_iter.Next() # ------------------------------------- splt.Build() new_shape = splt.Shape() sect.Destroy() return new_shape
def GetFacesSurfaces(BRepShape): FaceExplorer = TopExp_Explorer(BRepShape, TopAbs_FACE) Faces = [] while FaceExplorer.More(): ShapeFace = FaceExplorer.Current() # a TopoDS_Shape # Convert TopoDS_Shape to a TopoDS_Face Face = topods.Face(ShapeFace) Faces.append(Face) FaceExplorer.Next() pass Surfaces = [BRep_Tool().Surface(Face) for Face in Faces] SurfObjs = [Surface.GetObject() for Surface in Surfaces] return (Faces, Surfaces, SurfObjs)
def combine_faces(compshape, sew_tolerance): """ Method to combine faces in a shell by adding connectivity and continuity :param compshape: TopoDS_Shape :param sew_tolerance: tolerance for sewing :return: Topo_Shell """ offsew = BRepOffsetAPI_FindContigousEdges(sew_tolerance) sew = BRepBuilderAPI_Sewing(sew_tolerance) face_explorers = TopExp_Explorer(compshape, TopAbs_FACE) n_faces = 0 # cycle on Faces while face_explorers.More(): tface = topods.Face(face_explorers.Current()) sew.Add(tface) offsew.Add(tface) n_faces += 1 face_explorers.Next() offsew.Perform() offsew.Dump() sew.Perform() shell = sew.SewedShape() sew.Dump() shell = topods.Shell(shell) shell_fixer = ShapeFix_Shell() shell_fixer.FixFaceOrientation(shell) if shell_fixer.Perform(): print("{} shells fixed! ".format(shell_fixer.NbShells())) else: print "Shells not fixed! " new_shell = shell_fixer.Shell() if brepalgo_IsValid(new_shell): print "Shell valid! " else: print "Shell failed! " return new_shell
def split_solid(base, plane): splt = BRepFeat_SplitShape() splt.Init(base) sect = BRepAlgoAPI_Section(base, plane, False) sect.ComputePCurveOn1(True) sect.Approximation(True) sect.Build() edge = sect.Shape() rdict = set() # print(Topo(edge).number_of_edges()) Ex = TopExp_Explorer(edge, TopAbs_EDGE) while Ex.More(): # print('edge', Ex.Current()) base_iter = TopExp_Explorer(base, TopAbs_FACE) curr = Ex.Current() while base_iter.More(): # print('face', base_iter.Current()) bface = base_iter.Current() if sect.HasAncestorFaceOn1(curr, bface): # print('has1', curr, bface) k, v = hash(bface), hash(curr) if (k, v) not in rdict: rdict.add((k, v)) e = topods.Edge(curr) f = topods.Face(bface) splt.Add(e, f) if sect.HasAncestorFaceOn2(curr, bface): # print('has2', curr, bface) pass base_iter.Next() Ex.Next() splt.Build() return splt.Shape()
myNeckRadius = thickness / 4.0 myNeckHeight = height / 10.0 mkCylinder = BRepPrimAPI_MakeCylinder(neckAx2, myNeckRadius, myNeckHeight) myBody = BRepAlgoAPI_Fuse(myBody.Shape(), mkCylinder.Shape()) # Our goal is to find the highest Z face and remove it faceToRemove = None zMax = -1 # We have to work our way through all the faces to find # the highest Z face so we can remove it for the shell aFaceExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_FACE) while aFaceExplorer.More(): aFace = topods.Face(aFaceExplorer.Current()) if face_is_plane(aFace): aPlane = geom_plane_from_face(aFace) # We want the highest Z face, so compare this to the previous faces aPnt = aPlane.Location() aZ = aPnt.Z() if aZ > zMax: zMax = aZ faceToRemove = aFace aFaceExplorer.Next() facesToRemove = TopTools_ListOfShape() facesToRemove.Append(faceToRemove)
def write_shape(self, l_shells, filename, tol): """ Method to recreate a TopoDS_Shape associated to a geometric shape after the modification of points of each Face. It returns a TopoDS_Shape (Shape). :param l_shells: the list of shells after initial parsing :param filename: the output filename :param tol: tolerance on the surface creation after modification :return: None """ self.outfile = filename # global compound containing multiple shells global_compound_builder = BRep_Builder() global_comp = TopoDS_Compound() global_compound_builder.MakeCompound(global_comp) if self.check_topo == 0: # cycle on shells (multiple objects) shape_shells_explorer = TopExp_Explorer( self.shape.Oriented(TopAbs_FORWARD), TopAbs_SHELL) ishell = 0 while shape_shells_explorer.More(): per_shell = topods_Shell(shape_shells_explorer.Current()) # a local compound containing a shell compound_builder = BRep_Builder() comp = TopoDS_Compound() compound_builder.MakeCompound(comp) # cycle on faces faces_explorer = TopExp_Explorer( per_shell.Oriented(TopAbs_FORWARD), TopAbs_FACE) iface = 0 while faces_explorer.More(): topoface = topods.Face(faces_explorer.Current()) newface = self.write_face(l_shells[ishell][iface][0], l_shells[ishell][iface][1], topoface, tol) # add face to compound compound_builder.Add(comp, newface) iface += 1 faces_explorer.Next() new_shell = self.combine_faces(comp, 0.01) itype = TopoDS_Shape.ShapeType(new_shell) # add the new shell to the global compound global_compound_builder.Add(global_comp, new_shell) print("Shell {0} of type {1} Processed ".format(ishell, itype)) print "==============================================" ishell += 1 shape_shells_explorer.Next() else: # cycle on faces # a local compound containing a shell compound_builder = BRep_Builder() comp = TopoDS_Compound() compound_builder.MakeCompound(comp) # cycle on faces faces_explorer = TopExp_Explorer( self.shape.Oriented(TopAbs_FORWARD), TopAbs_FACE) iface = 0 while faces_explorer.More(): topoface = topods.Face(faces_explorer.Current()) newface = self.write_face(l_shells[0][iface][0], l_shells[0][iface][1], topoface, tol) # add face to compound compound_builder.Add(comp, newface) iface += 1 faces_explorer.Next() new_shell = self.combine_faces(comp, 0.01) itype = TopoDS_Shape.ShapeType(new_shell) # add the new shell to the global compound global_compound_builder.Add(global_comp, new_shell) print("Shell {0} of type {1} Processed ".format(0, itype)) print "==============================================" self.write_shape_to_file(global_comp, self.outfile)
def write_face(self, points_face, list_points_edge, topo_face, toledge): """ Method to recreate a Face associated to a geometric surface after the modification of Face points. It returns a TopoDS_Face. :param points_face: the new face points array. :param list_points_edge: new edge points :param topo_face: the face to be modified :param toledge: tolerance on the surface creation after modification :return: TopoDS_Face (Shape) :rtype: TopoDS_Shape """ # convert Face to Geom B-spline Surface nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_face) nurbs_converter.Perform(topo_face) nurbs_face = nurbs_converter.Shape() topo_nurbsface = topods.Face(nurbs_face) h_geomsurface = BRep_Tool.Surface(topo_nurbsface) h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface) bsurface = h_bsurface.GetObject() nb_u = bsurface.NbUPoles() nb_v = bsurface.NbVPoles() # check consistency if points_face.shape[0] != nb_u * nb_v: raise ValueError("Input control points do not have not have the " "same number as the geometric face!") # cycle on the face points indice_cpt = 0 for iu in range(1, nb_u + 1): for iv in range(1, nb_v + 1): cpt = points_face[indice_cpt] bsurface.SetPole(iu, iv, gp_Pnt(cpt[0], cpt[1], cpt[2])) indice_cpt += 1 # create modified new face new_bspline_tface = BRepBuilderAPI_MakeFace() toler = precision_Confusion() new_bspline_tface.Init(bsurface.GetHandle(), False, toler) # cycle on the wires face_wires_explorer = TopExp_Explorer( topo_nurbsface.Oriented(TopAbs_FORWARD), TopAbs_WIRE) ind_edge_total = 0 while face_wires_explorer.More(): # get old wire twire = topods_Wire(face_wires_explorer.Current()) # cycle on the edges ind_edge = 0 wire_explorer_edge = TopExp_Explorer( twire.Oriented(TopAbs_FORWARD), TopAbs_EDGE) # check edges order on the wire mode3d = True tolerance_edges = toledge wire_order = ShapeAnalysis_WireOrder(mode3d, tolerance_edges) # an edge list deformed_edges = [] # cycle on the edges while wire_explorer_edge.More(): tedge = topods_Edge(wire_explorer_edge.Current()) new_bspline_tedge = self.write_edge( list_points_edge[ind_edge_total], tedge) deformed_edges.append(new_bspline_tedge) analyzer = topexp() vfirst = analyzer.FirstVertex(new_bspline_tedge) vlast = analyzer.LastVertex(new_bspline_tedge) pt1 = BRep_Tool.Pnt(vfirst) pt2 = BRep_Tool.Pnt(vlast) wire_order.Add(pt1.XYZ(), pt2.XYZ()) ind_edge += 1 ind_edge_total += 1 wire_explorer_edge.Next() # grouping the edges in a wire, then in the face # check edges order and connectivity within the wire wire_order.Perform() # new wire to be created stol = ShapeFix_ShapeTolerance() new_bspline_twire = BRepBuilderAPI_MakeWire() for order_i in range(1, wire_order.NbEdges() + 1): deformed_edge_i = wire_order.Ordered(order_i) if deformed_edge_i > 0: # insert the deformed edge to the new wire new_edge_toadd = deformed_edges[deformed_edge_i - 1] stol.SetTolerance(new_edge_toadd, toledge) new_bspline_twire.Add(new_edge_toadd) if new_bspline_twire.Error() != 0: stol.SetTolerance(new_edge_toadd, toledge * 10.0) new_bspline_twire.Add(new_edge_toadd) else: deformed_edge_revers = deformed_edges[ np.abs(deformed_edge_i) - 1] stol.SetTolerance(deformed_edge_revers, toledge) new_bspline_twire.Add(deformed_edge_revers) if new_bspline_twire.Error() != 0: stol.SetTolerance(deformed_edge_revers, toledge * 10.0) new_bspline_twire.Add(deformed_edge_revers) # add new wire to the Face new_bspline_tface.Add(new_bspline_twire.Wire()) face_wires_explorer.Next() return topods.Face(new_bspline_tface.Face())
def parse_shape(self, filename): """ Method to parse a Shape with multiple objects (1 compound = multi-shells and 1 shell = multi-faces) It returns a list of matrix with all the coordinates of control points of each Face and a second list with all the control points related to Edges of each Face. :param filename: the input filename. :return: list of (mesh_points: `n_points`-by-3 matrix containing the coordinates of the control points of the Face (surface), edge_points: it is a list of numpy.narray) :rtype: a list of shells """ self.infile = filename self.shape = self.load_shape_from_file(filename) self.check_topology() # parse and get control points l_shells = [] # an empty list of shells n_shells = 0 if self.check_topo == 0: shells_explorer = TopExp_Explorer(self.shape, TopAbs_SHELL) # cycle on shells while shells_explorer.More(): topo_shell = topods.Shell(shells_explorer.Current()) shell_faces_explorer = TopExp_Explorer(topo_shell, TopAbs_FACE) l_faces = [] # an empty list of faces per shell # cycle on faces while shell_faces_explorer.More(): topo_face = topods.Face(shell_faces_explorer.Current()) mesh_point, edge_point = self.parse_face(topo_face) l_faces.append((mesh_point, edge_point)) shell_faces_explorer.Next() l_shells.append(l_faces) n_shells += 1 shells_explorer.Next() else: # cycle only on faces shell_faces_explorer = TopExp_Explorer(self.shape, TopAbs_FACE) l_faces = [] # an empty list of faces per shell while shell_faces_explorer.More(): topo_face = topods.Face(shell_faces_explorer.Current()) mesh_point, edge_point = self.parse_face(topo_face) l_faces.append((mesh_point, edge_point)) shell_faces_explorer.Next() l_shells.append(l_faces) n_shells += 1 return l_shells
def parse_face(topo_face): """ Method to parse a single Face (a single patch nurbs surface). It returns a matrix with all the coordinates of control points of the Face and a second list with all the control points related to the Edges of the Face. :param topo_face: the input Face :return: mesh_points_face: it is a `n_points`-by-3 matrix containing the coordinates of the control points of the Face (a nurbs surface) :return: mesh_points_edge: it is a list of `n_points`-by-3 matrix :rtype: tuple(numpy.ndarray, list) """ # get some Face - Edge - Vertex data map information mesh_points_edge = [] face_exp_wire = TopExp_Explorer(topo_face, TopAbs_WIRE) # loop on wires per face while face_exp_wire.More(): twire = topods_Wire(face_exp_wire.Current()) wire_exp_edge = TopExp_Explorer(twire, TopAbs_EDGE) # loop on edges per wire while wire_exp_edge.More(): edge = topods_Edge(wire_exp_edge.Current()) bspline_converter = BRepBuilderAPI_NurbsConvert(edge) bspline_converter.Perform(edge) bspline_tshape_edge = bspline_converter.Shape() h_geom_edge = BRep_Tool_Curve( topods_Edge(bspline_tshape_edge))[0] h_bspline_edge = geomconvert_CurveToBSplineCurve(h_geom_edge) bspline_geom_edge = h_bspline_edge.GetObject() nb_poles = bspline_geom_edge.NbPoles() # Edge geometric properties edge_ctrlpts = TColgp_Array1OfPnt(1, nb_poles) bspline_geom_edge.Poles(edge_ctrlpts) points_single_edge = np.zeros((0, 3)) for i in range(1, nb_poles + 1): ctrlpt = edge_ctrlpts.Value(i) ctrlpt_position = np.array( [[ctrlpt.Coord(1), ctrlpt.Coord(2), ctrlpt.Coord(3)]]) points_single_edge = np.append(points_single_edge, ctrlpt_position, axis=0) mesh_points_edge.append(points_single_edge) wire_exp_edge.Next() face_exp_wire.Next() # extract mesh points (control points) on Face mesh_points_face = np.zeros((0, 3)) # convert Face to Geom B-spline Face nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_face) nurbs_converter.Perform(topo_face) nurbs_face = nurbs_converter.Shape() h_geomsurface = BRep_Tool.Surface(topods.Face(nurbs_face)) h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface) bsurface = h_bsurface.GetObject() # get access to control points (poles) nb_u = bsurface.NbUPoles() nb_v = bsurface.NbVPoles() ctrlpts = TColgp_Array2OfPnt(1, nb_u, 1, nb_v) bsurface.Poles(ctrlpts) for indice_u_direction in range(1, nb_u + 1): for indice_v_direction in range(1, nb_v + 1): ctrlpt = ctrlpts.Value(indice_u_direction, indice_v_direction) ctrlpt_position = np.array( [[ctrlpt.Coord(1), ctrlpt.Coord(2), ctrlpt.Coord(3)]]) mesh_points_face = np.append(mesh_points_face, ctrlpt_position, axis=0) return mesh_points_face, mesh_points_edge