def replace_splitted_faces(builder, shape, old_face, splitted_faces): """ Try to create new shape that does not include old_face, but it includes instead splitted_faces """ old_points = points_of_face(old_face) sewing = BRepBuilderAPI_Sewing(0.01, True, True, True, False) sewing.SetFloatingEdgesMode(True) # Get list of all faces in shape primitives = brep_explorer.shape_disassembly(shape) obsolete_face_found = False # This loop tries to add original not-splitted faces to sewing for face_shape in primitives[4].values(): new_points = points_of_face(face_shape) # Quick Python trick using sets: all points in new_points # has to be included in old_points. # Note: may be, it is not 100% reliable, but for all uses cases it just works. old_set = set(old_points) new_set = set(new_points) if not old_set <= new_set: old_face = topods_Face(face_shape) sewing.Add(old_face) else: obsolete_face_found = True # When no face for replacement was found, then # return origin unchanged shape if obsolete_face_found is not True: return shape # This loop adds splitted faces to sewing for face_shape in splitted_faces: old_face = topods_Face(face_shape) sewing.Add(old_face) # Sew all faces together sewing.Perform() sewing_shape = sewing.SewedShape() # When there is hole in sewing, then following function will be terminated with Error. # Do not use try-except to solve this problems! Fill hole(s) with face(s). shell = topods_Shell(sewing_shape) # Make solid from shell and return result make_solid = BRepBuilderAPI_MakeSolid() make_solid.Add(shell) solid = make_solid.Solid() builder.MakeSolid(solid) builder.Add(solid, shell) return solid
def topo2topotype(occtopology): """ This function converts the original OCCtopology of the given topology. e.g. an OCCcompound that is originally an OCCface etc. Parameters ---------- occtopology : OCCtopology The OCCtopology to be converted. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface, OCCwire, OCCedge, OCCvertex Returns ------- original topology : OCCtopology The original OCCtopology of the input. """ shapetype = occtopology.ShapeType() if shapetype == TopAbs_COMPOUND:#compound orig_topo = topods_Compound(occtopology) if shapetype == TopAbs_COMPSOLID:#compsolid orig_topo = topods_CompSolid(occtopology) if shapetype == TopAbs_SOLID:#solid orig_topo = topods_Solid(occtopology) if shapetype == TopAbs_SHELL:#shell orig_topo = topods_Shell(occtopology) if shapetype == TopAbs_FACE:#face orig_topo = topods_Face(occtopology) if shapetype == TopAbs_WIRE:#wire orig_topo = topods_Wire(occtopology) if shapetype == TopAbs_EDGE:#edge orig_topo = topods_Edge(occtopology) if shapetype == TopAbs_VERTEX:#vertex orig_topo = topods_Vertex(occtopology) return orig_topo
def recognize_clicked(shp, *kwargs): """ This is the function called every time a face is clicked in the 3d view """ for shape in shp: # this should be a TopoDS_Face TODO check it is print("Face selected: ", shape) recognize_face(topods_Face(shape))
def occ_triangle_mesh(event=None): # # Mesh the shape # BRepMesh_IncrementalMesh(aShape, 0.1) builder = BRep_Builder() Comp = TopoDS_Compound() builder.MakeCompound(Comp) ex = TopExp_Explorer(aShape, TopAbs_FACE) while ex.More(): F = topods_Face(ex.Current()) L = TopLoc_Location() facing = (BRep_Tool().Triangulation(F, L)).GetObject() tab = facing.Nodes() tri = facing.Triangles() for i in range(1, facing.NbTriangles() + 1): trian = tri.Value(i) #print trian index1, index2, index3 = trian.Get() for j in range(1, 4): if j == 1: M = index1 N = index2 elif j == 2: N = index3 elif j == 3: M = index2 ME = BRepBuilderAPI_MakeEdge(tab.Value(M), tab.Value(N)) if ME.IsDone(): builder.Add(Comp, ME.Edge()) ex.Next() display.DisplayShape(Comp, update=True)
def occ_topo_list(shape): """ return the edges & faces from `shape` :param shape: a TopoDS_Shape :return: a list of edges and faces """ from OCC.TopAbs import TopAbs_FACE from OCC.TopAbs import TopAbs_EDGE from OCC.TopExp import TopExp_Explorer from OCC.TopoDS import topods_Face, topods_Edge topExp = TopExp_Explorer() topExp.Init(shape, TopAbs_FACE) faces = [] edges = [] while topExp.More(): face = topods_Face(topExp.Current()) faces.append(face) topExp.Next() topExp.Init(shape, TopAbs_EDGE) while topExp.More(): edge = topods_Edge(topExp.Current()) edges.append(edge) topExp.Next() return faces, edges
def chamfer(self, length, length2, edgeList): """ Chamfers the specified edges of this solid. :param length: length > 0, the length (length) of the chamfer :param length2: length2 > 0, optional parameter for asymmetrical chamfer. Should be `None` if not required. :param edgeList: a list of Edge objects, which must belong to this solid :return: Chamfered solid """ nativeEdges = [e.wrapped for e in edgeList] # make a edge --> faces mapping edge_face_map = TopTools_IndexedDataMapOfShapeListOfShape() topexp_MapShapesAndAncestors(self.wrapped, ta.TopAbs_EDGE, ta.TopAbs_FACE, edge_face_map) # note: we prefer 'length' word to 'radius' as opposed to FreeCAD's API chamfer_builder = BRepFilletAPI_MakeChamfer(self.wrapped) if length2: d1 = length d2 = length2 else: d1 = length d2 = length for e in nativeEdges: face = edge_face_map.FindFromKey(e).First() chamfer_builder.Add(d1, d2, e, topods_Face( face)) # NB: edge_face_map return a generic TopoDS_Shape return self.__class__(chamfer_builder.Shape())
def topo_explorer(occtopo2explore, topotype2find): """ This function explores and fetches the specified topological type from the given OCCtopology. e.g. find a list of OCCfaces in an OCCcompound. Parameters ---------- occtopo2explore : OCCtopology The OCCtopology to be explored. OCCtopology includes: OCCshape, OCCcompound, OCCcompsolid, OCCsolid, OCCshell, OCCface, OCCwire, OCCedge, OCCvertex topotype2find : str The string describing the topology to find. The strings can be e.g. "compound", "compsolid", "solid", "shell", "face", "wire", "edge", "vertex". Returns ------- list of topology : list of OCCtopology The list of OCCtopology found in the specified OCCtopology. """ geom_list = [] if topotype2find == "compound": shapetype2find_topABS = TopAbs_COMPOUND if topotype2find == "compsolid": shapetype2find_topABS = TopAbs_COMPSOLID if topotype2find == "solid": shapetype2find_topABS = TopAbs_SOLID if topotype2find == "shell": shapetype2find_topABS = TopAbs_SHELL if topotype2find == "face": shapetype2find_topABS = TopAbs_FACE if topotype2find == "wire": shapetype2find_topABS = TopAbs_WIRE if topotype2find == "edge": shapetype2find_topABS = TopAbs_EDGE if topotype2find == "vertex": shapetype2find_topABS = TopAbs_VERTEX ex = TopExp_Explorer(occtopo2explore, shapetype2find_topABS) while ex.More(): if shapetype2find_topABS == 0: geom = topods_Compound(ex.Current()) if shapetype2find_topABS == 1: geom = topods_CompSolid(ex.Current()) if shapetype2find_topABS == 2: geom = topods_Solid(ex.Current()) if shapetype2find_topABS == 3: geom = topods_Shell(ex.Current()) if shapetype2find_topABS == 4: geom = topods_Face(ex.Current()) if shapetype2find_topABS == 5: geom = topods_Wire(ex.Current()) if shapetype2find_topABS == 6: geom = topods_Edge(ex.Current()) if shapetype2find_topABS == 7: geom = topods_Vertex(ex.Current()) geom_list.append(geom) ex.Next() return geom_list
def get_faces(_shape): """ return the faces from `_shape` :param _shape: TopoDS_Shape, or a subclass like TopoDS_Solid :return: a list of faces found in `_shape` """ topExp = TopExp_Explorer() topExp.Init(_shape, TopAbs_FACE) _faces = [] while topExp.More(): fc = topods_Face(topExp.Current()) _faces.append(fc) topExp.Next() return _faces
def draft_angle(event=None): S = BRepPrimAPI_MakeBox(200., 300., 150.).Shape() adraft = BRepOffsetAPI_DraftAngle(S) topExp = TopExp_Explorer() topExp.Init(S, TopAbs_FACE) while topExp.More(): face = topods_Face(topExp.Current()) surf = Handle_Geom_Plane_DownCast(BRep_Tool_Surface(face)).GetObject() dirf = surf.Pln().Axis().Direction() ddd = gp_Dir(0, 0, 1) if dirf.IsNormal(ddd, precision_Angular()): adraft.Add(face, ddd, math.radians(15), gp_Pln(gp_Ax3(gp_XOY()))) topExp.Next() adraft.Build() display.DisplayShape(adraft.Shape(), update=True)
def shape2shapetype(occ_shape): shapetype = occ_shape.ShapeType() if shapetype == TopAbs_COMPOUND: #compound orig_topo = topods_Compound(occ_shape) if shapetype == TopAbs_COMPSOLID: #compsolid orig_topo = topods_CompSolid(occ_shape) if shapetype == TopAbs_SOLID: #solid orig_topo = topods_Solid(occ_shape) if shapetype == TopAbs_SHELL: #shell orig_topo = topods_Shell(occ_shape) if shapetype == TopAbs_FACE: #face orig_topo = topods_Face(occ_shape) if shapetype == TopAbs_WIRE: #wire orig_topo = topods_Wire(occ_shape) if shapetype == TopAbs_EDGE: #edge orig_topo = topods_Edge(occ_shape) if shapetype == TopAbs_VERTEX: #vertex orig_topo = topods_Vertex(occ_shape) return orig_topo
def simple_mesh(): # # Create the shape # shape = BRepPrimAPI_MakeBox(200, 200, 200).Shape() theBox = BRepPrimAPI_MakeBox(200, 60, 60).Shape() theSphere = BRepPrimAPI_MakeSphere(gp_Pnt(100, 20, 20), 80).Shape() shape = BRepAlgoAPI_Fuse(theSphere, theBox).Shape() # # Mesh the shape # BRepMesh_IncrementalMesh(shape, 0.8) builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) bt = BRep_Tool() ex = TopExp_Explorer(shape, TopAbs_FACE) while ex.More(): face = topods_Face(ex.Current()) location = TopLoc_Location() facing = (bt.Triangulation(face, location)).GetObject() tab = facing.Nodes() tri = facing.Triangles() for i in range(1, facing.NbTriangles()+1): trian = tri.Value(i) index1, index2, index3 = trian.Get() for j in range(1, 4): if j == 1: m = index1 n = index2 elif j == 2: n = index3 elif j == 3: m = index2 me = BRepBuilderAPI_MakeEdge(tab.Value(m), tab.Value(n)) if me.IsDone(): builder.Add(comp, me.Edge()) ex.Next() display.EraseAll() display.DisplayShape(shape) display.DisplayShape(comp, update=True)
def geom_explorer(geom2explore, shapetype2find): geom_list = [] if shapetype2find == "compound": shapetype2find_topABS = TopAbs_COMPOUND if shapetype2find == "compsolid": shapetype2find_topABS = TopAbs_COMPSOLID if shapetype2find == "solid": shapetype2find_topABS = TopAbs_SOLID if shapetype2find == "shell": shapetype2find_topABS = TopAbs_SHELL if shapetype2find == "face": shapetype2find_topABS = TopAbs_FACE if shapetype2find == "wire": shapetype2find_topABS = TopAbs_WIRE if shapetype2find == "edge": shapetype2find_topABS = TopAbs_EDGE if shapetype2find == "vertex": shapetype2find_topABS = TopAbs_VERTEX ex = TopExp_Explorer(geom2explore, shapetype2find_topABS) while ex.More(): if shapetype2find_topABS == 0: geom = topods_Compound(ex.Current()) if shapetype2find_topABS == 1: geom = topods_CompSolid(ex.Current()) if shapetype2find_topABS == 2: geom = topods_Solid(ex.Current()) if shapetype2find_topABS == 3: geom = topods_Shell(ex.Current()) if shapetype2find_topABS == 4: geom = topods_Face(ex.Current()) if shapetype2find_topABS == 5: geom = topods_Wire(ex.Current()) if shapetype2find_topABS == 6: geom = topods_Edge(ex.Current()) if shapetype2find_topABS == 7: geom = topods_Vertex(ex.Current()) geom_list.append(geom) ex.Next() return geom_list
def __init__(self, shape): from OCC.BRep import BRep_Tool from OCC.BRepMesh import BRepMesh_IncrementalMesh from OCC.TopAbs import TopAbs_FACE, TopAbs_VERTEX from OCC.TopExp import TopExp_Explorer from OCC.TopLoc import TopLoc_Location from OCC.TopoDS import topods_Face, topods_Vertex, TopoDS_Iterator vertices = [] # a (nested) list of vec3 triangles = [] # a (flat) list of integers normals = [] uv = [] # Mesh the shape linDeflection = 0.8 BRepMesh_IncrementalMesh(shape, linDeflection) bt = BRep_Tool() # Explore the faces of the shape # each face is triangulated, we need to collect all the parts expFac = TopExp_Explorer(shape, TopAbs_FACE) while expFac.More(): face = topods_Face(expFac.Current()) location = TopLoc_Location() facing = (bt.Triangulation(face, location)).GetObject() try: tri = facing.Triangles() nTri = facing.NbTriangles() ver = facing.Nodes() except: tri = None nTri = None ver = None # store origin of the face's local coordinates transf = face.Location().Transformation() # iterate over triangles and store indices of vertices defining each triangle # OCC uses one-based indexing for i in range(1, nTri + 1): # each triangle is defined by three points # each point is defined by its index in the list of vertices index1, index2, index3 = tri.Value(i).Get() indices = [index1, index2, index3] # python uses zero-based indexing # for each vertex of a triangle, check whether it is already known # then store it (or not) and update the index for idx in [0, 1, 2]: # read global coordinates of each point vec3 = [ ver.Value(indices[idx]).Transformed(transf).X(), ver.Value(indices[idx]).Transformed(transf).Y(), ver.Value(indices[idx]).Transformed(transf).Z() ] if vec3 not in vertices: vertices.append(vec3) indices[idx] = vertices.index(vec3) triangles.extend(indices) expFac.Next() self.shape = shape self.vertices = vertices self.triangles = triangles self.normals = normals self.uv = uv
def read(cls, filename): controller = IGESControl_Controller() controller.Init() reader = IGESControl_Reader() reader.ReadFile(filename) reader.TransferRoots() shape = reader.OneShape() n_faces = 0 control_point_position = [0] faces_explorer = TopExp_Explorer(shape, TopAbs_FACE) mesh_points = np.zeros(shape=(0, 3)) while faces_explorer.More(): # performing some conversions to get the right format (BSplineSurface) face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) # openCascade object occ_face = bspline_face.GetObject() # extract the Control Points of each face n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() control_polygon_coordinates = np.zeros(shape=(n_poles_u * n_poles_v, 3)) # cycle over the poles to get their coordinates i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): print(pole_u_direction, pole_v_direction) control_point_coordinates = occ_face.Pole( pole_u_direction + 1, pole_v_direction + 1) control_polygon_coordinates[i, :] = [ control_point_coordinates.X(), control_point_coordinates.Y(), control_point_coordinates.Z() ] i += 1 # pushing the control points coordinates to the mesh_points array # (used for FFD) mesh_points = np.append(mesh_points, control_polygon_coordinates, axis=0) control_point_position.append(control_point_position[-1] + n_poles_u * n_poles_v) n_faces += 1 faces_explorer.Next() return { 'shape': shape, 'points': mesh_points, 'control_point_position': control_point_position }
def write(cls, filename, data, tolerance=1e-6): # cycle on the faces to update the control points position # init some quantities shape = data.shape control_point_position = data.control_point_position mesh_points = data.points faces_explorer = TopExp_Explorer(shape, TopAbs_FACE) n_faces = 0 compound_builder = BRep_Builder() compound = TopoDS_Compound() compound_builder.MakeCompound(compound) while faces_explorer.More(): # similar to the parser method face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() face_aux = topods_Face(nurbs_face) brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) occ_face = bspline_face.GetObject() n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): control_point_coordinates = mesh_points[ +control_point_position[n_faces], :] point_xyz = gp_XYZ(*control_point_coordinates) gp_point = gp_Pnt(point_xyz) occ_face.SetPole(pole_u_direction + 1, pole_v_direction + 1, gp_point) i += 1 # construct the deformed wire for the trimmed surfaces wire_maker = BRepBuilderAPI_MakeWire() tol = ShapeFix_ShapeTolerance() brep = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), tolerance).Face() brep_face = BRep_Tool.Surface(brep) # cycle on the edges edge_explorer = TopExp_Explorer(nurbs_face, TopAbs_EDGE) while edge_explorer.More(): edge = topods_Edge(edge_explorer.Current()) # edge in the (u,v) coordinates edge_uv_coordinates = BRep_Tool.CurveOnSurface(edge, face_aux) # evaluating the new edge: same (u,v) coordinates, but # different (x,y,x) ones edge_phis_coordinates_aux = BRepBuilderAPI_MakeEdge( edge_uv_coordinates[0], brep_face) edge_phis_coordinates = edge_phis_coordinates_aux.Edge() tol.SetTolerance(edge_phis_coordinates, tolerance) wire_maker.Add(edge_phis_coordinates) edge_explorer.Next() # grouping the edges in a wire wire = wire_maker.Wire() # trimming the surfaces brep_surf = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), wire).Shape() compound_builder.Add(compound, brep_surf) n_faces += 1 faces_explorer.Next() IGESControl_Controller_Init() writer = IGESControl_Writer() writer.AddShape(compound) writer.Write(filename)
def parse(self, filename): """ Method to parse the file `filename`. It returns a matrix with all the coordinates. :param string filename: name of the input file. :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of the points of the mesh :rtype: numpy.ndarray """ self.infile = filename self.shape = self.load_shape_from_file(filename) # cycle on the faces to get the control points # init some quantities n_faces = 0 control_point_position = [0] faces_explorer = TopExp_Explorer(self.shape, TopAbs_FACE) mesh_points = np.zeros(shape=(0, 3)) while faces_explorer.More(): # performing some conversions to get the right format (BSplineSurface) face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) # openCascade object occ_face = bspline_face.GetObject() # extract the Control Points of each face n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() control_polygon_coordinates = np.zeros( shape=(n_poles_u * n_poles_v, 3)) # cycle over the poles to get their coordinates i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): control_point_coordinates = occ_face.Pole( pole_u_direction + 1, pole_v_direction + 1) control_polygon_coordinates[i, :] = [ control_point_coordinates.X(), control_point_coordinates.Y(), control_point_coordinates.Z() ] i += 1 # pushing the control points coordinates to the mesh_points array # (used for FFD) mesh_points = np.append( mesh_points, control_polygon_coordinates, axis=0) control_point_position.append( control_point_position[-1] + n_poles_u * n_poles_v) n_faces += 1 faces_explorer.Next() self._control_point_position = control_point_position return mesh_points
def write(self, mesh_points, filename, tolerance=None): """ Writes a output file, called `filename`, copying all the structures from self.filename but the coordinates. `mesh_points` is a matrix that contains the new coordinates to write in the output file. :param numpy.ndarray mesh_points: it is a *n_points*-by-3 matrix containing the coordinates of the points of the mesh. :param str filename: name of the output file. :param float tolerance: tolerance for the construction of the faces and wires in the write function. If not given it uses `self.tolerance`. """ self._check_filename_type(filename) self._check_extension(filename) self._check_infile_instantiation() self.outfile = filename if tolerance is not None: self.tolerance = tolerance # cycle on the faces to update the control points position # init some quantities faces_explorer = TopExp_Explorer(self.shape, TopAbs_FACE) n_faces = 0 control_point_position = self._control_point_position compound_builder = BRep_Builder() compound = TopoDS_Compound() compound_builder.MakeCompound(compound) while faces_explorer.More(): # similar to the parser method face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() face_aux = topods_Face(nurbs_face) brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) occ_face = bspline_face.GetObject() n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): control_point_coordinates = mesh_points[ i + control_point_position[n_faces], :] point_xyz = gp_XYZ(*control_point_coordinates) gp_point = gp_Pnt(point_xyz) occ_face.SetPole(pole_u_direction + 1, pole_v_direction + 1, gp_point) i += 1 # construct the deformed wire for the trimmed surfaces wire_maker = BRepBuilderAPI_MakeWire() tol = ShapeFix_ShapeTolerance() brep = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), self.tolerance).Face() brep_face = BRep_Tool.Surface(brep) # cycle on the edges edge_explorer = TopExp_Explorer(nurbs_face, TopAbs_EDGE) while edge_explorer.More(): edge = topods_Edge(edge_explorer.Current()) # edge in the (u,v) coordinates edge_uv_coordinates = BRep_Tool.CurveOnSurface(edge, face_aux) # evaluating the new edge: same (u,v) coordinates, but # different (x,y,x) ones edge_phis_coordinates_aux = BRepBuilderAPI_MakeEdge( edge_uv_coordinates[0], brep_face) edge_phis_coordinates = edge_phis_coordinates_aux.Edge() tol.SetTolerance(edge_phis_coordinates, self.tolerance) wire_maker.Add(edge_phis_coordinates) edge_explorer.Next() # grouping the edges in a wire wire = wire_maker.Wire() # trimming the surfaces brep_surf = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), wire).Shape() compound_builder.Add(compound, brep_surf) n_faces += 1 faces_explorer.Next() self.write_shape_to_file(compound, self.outfile)
def write(self, mesh_points, filename, tolerance=None): """ Writes a output file, called filename, copying all the structures from self.filename but the coordinates. `mesh_points` is a matrix that contains the new coordinates to write in the output file. :param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of the points of the mesh :param string filename: name of the output file. :param float tolerance: tolerance for the construction of the faces and wires in the write function. If not given it uses `self.tolerance`. """ self._check_filename_type(filename) self._check_extension(filename) self._check_infile_instantiation() self.outfile = filename if tolerance is not None: self.tolerance = tolerance # cycle on the faces to update the control points position # init some quantities faces_explorer = TopExp_Explorer(self.shape, TopAbs_FACE) n_faces = 0 control_point_position = self._control_point_position compound_builder = BRep_Builder() compound = TopoDS_Compound() compound_builder.MakeCompound(compound) while faces_explorer.More(): # similar to the parser method face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() face_aux = topods_Face(nurbs_face) brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) occ_face = bspline_face.GetObject() n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): control_point_coordinates = mesh_points[ i + control_point_position[n_faces], :] point_xyz = gp_XYZ(*control_point_coordinates) gp_point = gp_Pnt(point_xyz) occ_face.SetPole(pole_u_direction + 1, pole_v_direction + 1, gp_point) i += 1 # construct the deformed wire for the trimmed surfaces wire_maker = BRepBuilderAPI_MakeWire() tol = ShapeFix_ShapeTolerance() brep = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), self.tolerance).Face() brep_face = BRep_Tool.Surface(brep) # cycle on the edges edge_explorer = TopExp_Explorer(nurbs_face, TopAbs_EDGE) while edge_explorer.More(): edge = topods_Edge(edge_explorer.Current()) # edge in the (u,v) coordinates edge_uv_coordinates = BRep_Tool.CurveOnSurface(edge, face_aux) # evaluating the new edge: same (u,v) coordinates, but different (x,y,x) ones edge_phis_coordinates_aux = BRepBuilderAPI_MakeEdge( edge_uv_coordinates[0], brep_face) edge_phis_coordinates = edge_phis_coordinates_aux.Edge() tol.SetTolerance(edge_phis_coordinates, self.tolerance) wire_maker.Add(edge_phis_coordinates) edge_explorer.Next() # grouping the edges in a wire wire = wire_maker.Wire() # trimming the surfaces brep_surf = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), wire).Shape() compound_builder.Add(compound, brep_surf) n_faces += 1 faces_explorer.Next() self.write_shape_to_file(compound, self.outfile)
def parse(self, filename): """ Method to parse the file `filename`. It returns a matrix with all the coordinates. :param string filename: name of the input file. :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of the points of the mesh :rtype: numpy.ndarray """ self.infile = filename self.shape = self.load_shape_from_file(filename) # cycle on the faces to get the control points # init some quantities n_faces = 0 control_point_position = [0] faces_explorer = TopExp_Explorer(self.shape, TopAbs_FACE) mesh_points = np.zeros(shape=(0, 3)) while faces_explorer.More(): # performing some conversions to get the right format (BSplineSurface) face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) # openCascade object occ_face = bspline_face.GetObject() # extract the Control Points of each face n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() control_polygon_coordinates = np.zeros(shape=(n_poles_u * n_poles_v, 3)) # cycle over the poles to get their coordinates i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): control_point_coordinates = occ_face.Pole( pole_u_direction + 1, pole_v_direction + 1) control_polygon_coordinates[i, :] = [ control_point_coordinates.X(), control_point_coordinates.Y(), control_point_coordinates.Z() ] i += 1 # pushing the control points coordinates to the mesh_points array (used for FFD) mesh_points = np.append(mesh_points, control_polygon_coordinates, axis=0) control_point_position.append(control_point_position[-1] + n_poles_u * n_poles_v) n_faces += 1 faces_explorer.Next() self._control_point_position = control_point_position return mesh_points