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 regions2step(splinegons, filename, application_protocol='AP203'): """Writes splinegon regions to a STEP file. Parameters ---------- splinegons : list Each member of the list is a `TopoDS_Face` object, the surface of a region. filename : str Name of the file the regions are saved into. application_protocol : {'AP203', 'AP214IS', 'AP242DIS'}, optional Version of schema used for the output STEP file. The default is 'AP203'. Returns ------- None See Also -------- splinegonize write_step_file """ # Initialize a container that we will populate with the splinegons builder = BRep_Builder() compound = TopoDS_Compound() builder.MakeCompound(compound) # Combine multiple faces for splinegon in splinegons: builder.Add(compound, splinegon) # Write to STEP file write_step_file(compound, filename, application_protocol)
def writeBRep(filename, shapeList): aRes = TopoDS_Compound() aBuilder = BRep_Builder() aBuilder.MakeCompound(aRes) for shape in shapeList: aBuilder.Add(aRes, shape) breptools_Write(aRes, filename)
def export(self, event): """ Export the current model to stl """ from OCC.StlAPI import StlAPI_Writer from OCC.BRepMesh import BRepMesh_IncrementalMesh #: TODO: All parts options = event.parameters.get('options') if not isinstance(options, ExportOptions): return False exporter = StlAPI_Writer() exporter.SetASCIIMode(not options.binary) #: Make a compound of compounds (if needed) compound = TopoDS_Compound() builder = BRep_Builder() builder.MakeCompound(compound) for part in self.parts: #: Must mesh the shape first if isinstance(part, Part): builder.Add(compound, part.proxy.shape) else: builder.Add(compound, part.proxy.shape.Shape()) #: Build the mesh mesh = BRepMesh_IncrementalMesh(compound, options.linear_deflection, options.relative, options.angular_deflection) mesh.Perform() if not mesh.IsDone(): raise ExportError("Failed to create the mesh") exporter.Write(compound, options.path)
def mkCompaund(f1,f2): u"""Об'єднує форми для експорту в формат BRep""" from OCC.BRep import BRep_Builder f=TopoDS_Compound() bb=BRep_Builder() bb.MakeCompound(f) bb.Add(f,f1) bb.Add(f,f2) return f
def get_compound(self): """ Create and returns a compound from the _shapes list """ # Create a compound compound = TopoDS_Compound() B = BRep_Builder() B.MakeCompound(compound) # Populate the compound for shape in self._shapes: B.Add(compound, shape) return compound
def update_shape(self, change): """ Create the toolkit shape for the proxy object. """ builder = BRep_Builder() shape = self.shape builder.MakeCompound(shape) for s in self.shapes: if hasattr(s.shape, 'Shape'): builder.Add(shape, s.shape.Shape()) elif s.shape is not None: builder.Add(shape, s.shape) self.builder = builder
def read_step_file(filename, as_compound=True, verbosity=True): """ read the STEP file and returns a compound filename: the file path verbosity: optional, False by default. as_compound: True by default. If there are more than one shape at root, gather all shapes into one compound. Otherwise returns a list of shapes. """ if not os.path.isfile(filename): raise FileNotFoundError("%s not found." % filename) step_reader = STEPControl_Reader() status = step_reader.ReadFile(filename) if status == IFSelect_RetDone: # check status if verbosity: failsonly = False step_reader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity) step_reader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity) transfer_result = step_reader.TransferRoots() if not transfer_result: raise AssertionError("Transfer failed.") _nbs = step_reader.NbShapes() if _nbs == 0: raise AssertionError("No shape to transfer.") elif _nbs == 1: # most cases return step_reader.Shape(1) elif _nbs > 1: print("Number of shapes:", _nbs) shps = [] # loop over root shapes for k in range(1, _nbs + 1): new_shp = step_reader.Shape(k) if not new_shp.IsNull(): shps.append(new_shp) if as_compound: builder = BRep_Builder() compound = TopoDS_Compound() builder.MakeCompound(compound) for s in shps: builder.Add(compound, s) # shps = compound # compound, result = list_of_shapes_to_compound(shps) # if not result: # print("Warning: all shapes were not added to the compound") return compound else: print("Warning, returns a list of shapes.") return shps else: raise AssertionError("Error: can't read file.") return None
def make_compound(shape_array): """ Creates a TopoDS_Compund from a list of TopoDS_Shapes :param shape_array: list of shapes :return: TopoDS_Compound """ b = BRep_Builder() c = TopoDS_Compound() b.MakeCompound(c) for shape in shape_array: b.Add(c, shape) return c
def read_iges_file(filename, return_as_shapes=False, verbosity=False): """ read the IGES file and returns a compound filename: the file path return_as_shapes: optional, False by default. If True returns a list of shapes, else returns a single compound verbosity: optionl, False by default. """ assert os.path.isfile(filename) iges_reader = IGESControl_Reader() status = iges_reader.ReadFile(filename) _shapes = [] if status == IFSelect_RetDone: # check status if verbosity: failsonly = False iges_reader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity) iges_reader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity) iges_reader.TransferRoots() nbr = iges_reader.NbRootsForTransfer() for n in range(1, nbr + 1): nbs = iges_reader.NbShapes() if nbs == 0: print("At least one shape in IGES cannot be transfered") elif nbr == 1 and nbs == 1: aResShape = iges_reader.Shape(1) if aResShape.IsNull(): print("At least one shape in IGES cannot be transferred") else: _shapes.append(aResShape) else: for i in range(1, nbs + 1): aShape = iges_reader.Shape(i) if aShape.IsNull(): print( "At least one shape in STEP cannot be transferred") else: _shapes.append(aShape) # if not return as shapes # create a compound and store all shapes # TODO if not return_as_shapes: builder = BRep_Builder() Comp = TopoDS_Compound() builder.MakeCompound(Comp) for s in _shapes: builder.Add(Comp, s) _shapes = Comp return _shapes
def export(self): """ Export a DeclaraCAD model from an enaml file to an STL based on the given options. Parameters ---------- options: declaracad.occ.plugin.ExportOptions """ from OCC.BRep import BRep_Builder from OCC.BRepMesh import BRepMesh_IncrementalMesh from OCC.StlAPI import StlAPI_Writer from OCC.TopoDS import TopoDS_Compound # Make a compound of compounds (if needed) compound = TopoDS_Compound() builder = BRep_Builder() builder.MakeCompound(compound) # Load the enaml model file parts = load_model(self.filename) for part in parts: # Render the part from the declaration shape = part.render() # Must mesh the shape firsts if hasattr(shape, 'Shape'): builder.Add(compound, shape.Shape()) else: builder.Add(compound, shape) #: Build the mesh exporter = StlAPI_Writer() exporter.SetASCIIMode(not self.binary) mesh = BRepMesh_IncrementalMesh( compound, self.linear_deflection, self.relative, self.angular_deflection ) mesh.Perform() if not mesh.IsDone(): raise RuntimeError("Failed to create the mesh") exporter.Write(compound, self.path) if not os.path.exists(self.path): raise RuntimeError("Failed to write shape")
def create_shape(self): d = self.declaration if not d.source: return if os.path.exists(d.source): svg = etree.parse(d.source).getroot() else: svg = etree.fromstring(d.source) node = OccSvgDoc(element=svg) builder = BRep_Builder() shape = TopoDS_Compound() builder.MakeCompound(shape) shapes = node.create_shape() for s in shapes: builder.Add(shape, s) self.wires = shapes self.shape = shape
def occ_load_file(filename): """ load in pythonocc a igs or step file :param filename: a filename with extension :return: a topods_shape """ from OCC.STEPControl import STEPControl_Reader from OCC.IGESControl import IGESControl_Reader from OCC.BRep import BRep_Builder from OCC.TopoDS import TopoDS_Compound from OCC.IFSelect import IFSelect_RetDone,\ IFSelect_ItemsByEntity reader_switch = { 'stp': STEPControl_Reader, 'step': STEPControl_Reader, 'igs': IGESControl_Reader, 'iges': IGESControl_Reader } builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) reader = reader_switch[os.path.splitext(filename)[1][1:].lower()]() status = reader.ReadFile(filename) if status == IFSelect_RetDone: # check status failsonly = False reader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity) reader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity) ok = reader.TransferRoots() nbs = reader.NbShapes() for i in range(1, nbs + 1): shape = reader.Shape(i) builder.Add(comp, shape) return comp
def step_reader(step_string): from OCC.StlAPI import StlAPI_Writer from OCC.STEPControl import STEPControl_Reader from OCC.BRep import BRep_Builder from OCC.TopoDS import TopoDS_Compound from OCC.IFSelect import IFSelect_RetDone, IFSelect_ItemsByEntity builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) stl_writer = StlAPI_Writer() stl_writer.SetASCIIMode(True) with io.tmpfile(contents=io.shapes()[shape_name][:][0]) as tmpfile: step_reader = STEPControl_Reader() status = step_reader.ReadFile(tmpfile[1]) if status == IFSelect_RetDone: # check status failsonly = False step_reader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity) step_reader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity) ok = step_reader.TransferRoot(1) nbs = step_reader.NbShapes() l = [] for i in range(1, nbs + 1): shape = step_reader.Shape(i) builder.Add(comp, shape) with io.tmpfile(suffix='.stl') as tmpf: stl_writer.Write(comp, tmpf[1]) tmpf[0].flush() reader = vtk.vtkSTLReader() reader.SetFileName(tmpf[1]) reader.Update() return reader
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 vstep(step_str): step = int(step_str) positions = dpos_data[nbobjs * step:nbobjs * step + nbobjs, 2:] builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) for _id in range(positions.shape[0]): q0, q1, q2, q3, q4, q5, q6 = [float(x) for x in positions[_id, :]] obj = obj_by_id[_id + 1] q = Quaternion((q3, q4, q5, q6)) for shape_name, avatar in zip(io.instances()[obj], avatars(obj)): offset = get_offset(obj, shape_name) p = q.rotate(offset[0]) r = q * Quaternion(offset[1]) tr = gp_Trsf() qocc = gp_Quaternion(r[1], r[2], r[3], r[0]) tr.SetRotation(qocc) xyz = gp_XYZ(q0 + p[0], q1 + p[1], q2 + p[2]) vec = gp_Vec(xyz) tr.SetTranslationPart(vec) loc = TopLoc_Location(tr) display.Context.SetLocation(avatar, loc) moved_shape = BRepBuilderAPI_Transform( avatar.GetObject().Shape(), tr, True).Shape() builder.Add(comp, moved_shape) display.Context.UpdateCurrentViewer() write_step((step_str, comp))
def draw_lineandvertices(event=None): Line_1 = TopoDS_Shape() Vertex_1 = TopoDS_Shape() Vertex_2 = TopoDS_Shape() builder = BRep_Builder() builder1 = BRep_Builder() compound = TopoDS_Compound() builder1.MakeCompound(compound) breptools_Read(Line_1, 'Line_1.brep', builder) breptools_Read(Vertex_1, 'Vertex_1.brep', builder) breptools_Read(Vertex_2, 'Vertex_2.brep', builder) builder1.Add(compound,Line_1) builder1.Add(compound,Vertex_1) builder1.Add(compound,Vertex_2) #display.DisplayShape({Line_1, Vertex_1, Vertex_2}, update=True) #display.DisplayShape(Group_1, update=True) display.DisplayShape(compound, update=True) breptools_Write(compound, 'compound.brep') display.FitAll()
def discretize(shape, tol): """This method discretizes the OpenCascade shape. :param shape: Shape to discretize :type shape: :return: discretized face; profile coordinates; id of the surface the\ coordinates belong to :rtype: OCC.TopoDS.TopoDS_Compound; numpy.ndarray; numpy.ndarray """ BRepMesh_IncrementalMesh(shape, tol, False, 5) builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) bt = BRep_Tool() ex = TopExp_Explorer(shape, TopAbs_EDGE) edge_coords = np.zeros([0, 3]) edge_ids = np.zeros([0], dtype=int) edge_id = 0 while ex.More(): edge = topods_Edge(ex.Current()) location = TopLoc_Location() edging = (bt.Polygon3D(edge, location)).GetObject() tab = edging.Nodes() for i in range(1, edging.NbNodes() + 1): p = tab.Value(i) edge_coords = np.append(edge_coords, [[p.X(), p.Y(), p.Z()]], axis=0) edge_ids = np.append(edge_ids, edge_id) mv = BRepBuilderAPI_MakeVertex(p) if mv.IsDone(): builder.Add(comp, mv.Vertex()) edge_id += 1 ex.Next() edge_coords = np.round(edge_coords, 8) return edge_coords, edge_ids
sphere_r1_shape = sphere_r1.Shape() radius = 0.01 sphere_r01 = BRepPrimAPI_MakeSphere(point, radius) sphere_r01_shape = sphere_r01.Shape() radius = 0.001 sphere_r001 = BRepPrimAPI_MakeSphere(point, radius) sphere_r001_shape = sphere_r001.Shape() from OCC.BRep import BRep_Builder from OCC.TopoDS import TopoDS_Compound builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) from OCC.BRep import BRep_Builder from OCC.TopoDS import TopoDS_Compound builder.Add(comp, sphere_r1_shape) radius = 1.0 point = gp_Pnt(4., 0., 0.) sphere_r1_t = BRepPrimAPI_MakeSphere(point, radius) sphere_r1_t_shape = sphere_r1_t.Shape() builder.Add(comp, sphere_r1_t_shape) # this cylinder is defined for the visualisation of the axis edge # it may be used for contact also.
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 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 = OCC.TopoDS.TopoDS_Compound() compound_builder.MakeCompound(compound) while faces_explorer.More(): # similar to the parser method face = OCC.TopoDS.topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() face_aux = OCC.TopoDS.topods_Face(nurbs_face) brep_face = BRep_Tool.Surface(OCC.TopoDS.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 = OCC.TopoDS.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 generate_stl(self, min_length=None, max_length=None, outfile_stl=None): """ Generate and export the .STL surface mesh for the blade as a whole, including the upper face, lower face and tip. The method utilizes modules from OCC SMESH which is standalone mesh framework based on SALOME mesher project. Please refer to https://github.com/tpaviot and http://docs.salome-platform.org/7/gui/SMESH/index.html for further details. This method requires PythonOCC and SMESH to be installed. :param double min_length: smallest distance between two nodes. Default value is None :param double max_length: largest distance between two nodes. Default value is None :param string outfile_stl: if string is passed then the method exports the generated 2D surface mesh into .stl file holding the name <outfile_stl>.stl. Default value is None We note that since the current implementation performs triangulation based on a topological compound that combines the blade 3 generated shapes without "fusion", it may happen that the generated triangulation of the upper and lower blade faces do not share the same exact nodes on the joint edge/wire resulting from the faces intersection. The current implementation can be enough for visualization purpose. However if the generated mesh is intended for computational analysis then a manual mesh healing is recommended by the user (e.g. see "Repair > Sewing" in SALOME GUI) for a proper mesh closure. """ from OCC.SMESH import SMESH_Gen from OCC.StdMeshers import (StdMeshers_Arithmetic1D, StdMeshers_TrianglePreference, StdMeshers_Regular_1D, StdMeshers_MEFISTO_2D) from OCC.BRep import BRep_Builder from OCC.TopoDS import TopoDS_Shape, TopoDS_Compound if min_length <= 0 or max_length <= 0: raise ValueError('min_length and max_length must be positive.') if min_length >= max_length: raise ValueError('min_length can not be greater than max_length') # First we check that blade shapes are generated, otherwise we generate # them. After that we combine the generated_upper_face, # generated_lower_face, and generated_tip into a topological compound # that we use to compute the surface mesh if (self.generated_upper_face is None) or not isinstance( self.generated_upper_face, TopoDS_Shape): # Upper face is generated with a maximal U degree = 1 self._generate_upper_face(maxDeg=1) if (self.generated_lower_face is None) or not isinstance( self.generated_lower_face, TopoDS_Shape): # Upper face is generated with a maximal U degree = 1 self._generate_lower_face(maxDeg=1) if (self.generated_tip is None) or not isinstance( self.generated_tip, TopoDS_Shape): # Upper face is generated with a maximal U degree = 1 self._generate_tip(maxDeg=1) # Now we regroup all the shapes into a TopoDS_Compound aCompound = TopoDS_Compound() aBuilder = BRep_Builder() aBuilder.MakeCompound(aCompound) # Add shapes aBuilder.Add(aCompound, self.generated_upper_face) aBuilder.Add(aCompound, self.generated_lower_face) aBuilder.Add(aCompound, self.generated_tip) # In the following we build the surface mesh according to the given # hypotheses aMeshGen = SMESH_Gen() aMesh = aMeshGen.CreateMesh(0, True) # Adding 1D hypothesis and algorithms # Wire discretization. Nodes are distributed based on Arithmetic1D # hypothesis which allows to split edges into segments with a length # that changes in arithmetic progression (Lk = Lk-1 + d) beginning # from a given min length and up to a given max length. More about # 1D hypotheses can be viewed through: # http://docs.salome-platform.org/7/gui/SMESH/a1d_meshing_hypo_page.html an1DHypothesis = StdMeshers_Arithmetic1D(0, 0, aMeshGen) # Smallest distance between 2 points an1DHypothesis.SetLength(min_length, False) # Longest distance between 2 points an1DHypothesis.SetLength(max_length, True) # Regular Interpolation an1DAlgo = StdMeshers_Regular_1D(1, 0, aMeshGen) # Adding 2D hypothesis and algorithms # 2D surface mesh -- Triangulations a2dHypothseis = StdMeshers_TrianglePreference(2, 0, aMeshGen) a2dAlgo = StdMeshers_MEFISTO_2D(3, 0, aMeshGen) #Calculate mesh for the topological compound containing the 3 shapes aMesh.ShapeToMesh(aCompound) #Assign hyptothesis to mesh aMesh.AddHypothesis(aCompound, 0) aMesh.AddHypothesis(aCompound, 1) aMesh.AddHypothesis(aCompound, 2) aMesh.AddHypothesis(aCompound, 3) if outfile_stl is not None: if not isinstance(outfile_stl, str): raise ValueError('outfile_stl must be a valid string.') #Compute the data aMeshGen.Compute(aMesh, aMesh.GetShapeToMesh()) # Export STL aMesh.ExportSTL(outfile_stl + '.stl', False)
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 get_current_loft(self): wires = [] curves = [] propeller_number_, xz_mirror_, xy_mirror_, yz_mirror_ \ , rot_x_, hub_length, pitch_angle, root_le_pos_x_, \ root_le_pos_y_, root_le_pos_z_, section_1_length_, section_2_length_, \ section_3_length_, section_4_length_, section_5_length_, section_1_profile_, \ section_2_profile_, section_3_profile_, section_4_profile_, section_5_profile_, \ section_1_z_, section_2_z_, section_3_z_, section_4_z_, section_5_z_ \ , section_1_chord_, section_2_chord_, section_3_chord_, section_4_chord_, \ section_5_chord_, section_1_pitch_angle_, section_2_pitch_angle_, \ section_3_pitch_angle_, section_4_pitch_angle_, section_5_pitch_angle_ = read_propeller_parameters( name=self.name) interval = 5 chords = [ section_1_chord_, section_1_chord_, section_2_chord_, section_3_chord_, section_4_chord_, section_5_chord_, 0.001 ] profile = [ section_1_profile_, section_1_profile_, section_2_profile_, section_3_profile_, section_4_profile_, section_5_profile_, section_5_profile_ ] length = [ 0, section_1_length_, section_2_length_, section_3_length_, section_4_length_, section_5_length_ / 2, section_5_length_ / 2 ] z = [ section_1_z_, section_1_z_, section_2_z_, section_3_z_, section_4_z_, section_5_z_, section_5_z_ ] pitch = [ 0, section_1_pitch_angle_, section_2_pitch_angle_, section_3_pitch_angle_, section_4_pitch_angle_, section_5_pitch_angle_, section_5_pitch_angle_ ] n = random.random() lifting_surface = self.config.get_wings().create_wing( f"{n}", len(chords), f"naca4412") sections = [-hub_length / 2, 0.1 * hub_length, hub_length / 2] radius = [ 0.00, rot_x_ / 2, rot_x_ / 2, ] x_ = [] x_.extend(np.linspace(sections[0], sections[1], num=interval)) x_.append(0.9 * hub_length) radii = [] radii.extend(np.linspace(radius[0], radius[1], num=interval)) radii.append((rot_x_ / 2)) print(x_, radii) n = random.random() hub = self.config.get_fuselages().create_fuselage( f"hub{n}", len(x_), "circularProfile") for (x, rad, index) in zip(x_, radii, range(1, len(x_) + 1)): section = hub.get_section(index) sectionElement = section.get_section_element(1) sectionElementCenter = sectionElement.get_ctigl_section_element() sectionElementCenter.set_center(tigl3.geometry.CTiglPoint(x, 0, 0)) sectionElementCenter.set_area(getArea(rad)) n_sections = lifting_surface.get_section_count() lifting_surface.set_root_leposition( tigl3.geometry.CTiglPoint(-chords[0] / 2, 0, 0)) print(n_sections) y = 0.0 x = hub_length / 2 for (z_, chord, length_, pitch_, profile_, idx) in zip(z, chords, length, pitch, profile, range(1, n_sections + 1)): profile__ = "naca" + profile_ constant = 0.0 nacanumber = profile__.split("naca")[1] if nacanumber.isdigit(): if len(nacanumber) == 4: constant = int(nacanumber[2:]) * 0.01 s = lifting_surface.get_section(idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() ce.set_width(chord) ce.set_height(chord * constant) center = ce.get_center() y += length_ center.x = x center.y = y center.z = 0.0 ce.set_center(center) ce.set_profile_uid(f"{profile_}") e.set_rotation(tigl3.geometry.CTiglPoint(0, pitch_, 0)) lifting_surface.set_rotation( tigl3.geometry.CTiglPoint(0, pitch_angle, 0)) for idx in range(1, n_sections + 1): s = lifting_surface.get_section(idx) e = s.get_section_element(1) ce = e.get_ctigl_section_element() wires.append(ce.get_wire()) for l in wires: adapt = BRepAdaptor_CompCurve(l) curve = Handle_BRepAdaptor_HCompCurve( BRepAdaptor_HCompCurve(adapt)) approx = Approx_Curve3d(curve, 0.001, GeomAbs_C2, 200, 12) if (approx.IsDone() and approx.HasResult()): curves.append(approx.Curve()) surface1 = tigl3.surface_factories.interpolate_curves(curves) face1 = BRepBuilderAPI_MakeFace(surface1, 1e-6).Face() face2 = BRepBuilderAPI_MakeFace(surface1, 1e-6).Face() sew = BRepBuilderAPI_Sewing() sew.Add(face1) sew.Add(face2) sew.Perform() shape = sew.SewedShape() print(shape) tds = topods() model = BRepBuilderAPI_MakeSolid() model.Add(tds.Shell(shape)) solid = model.Solid() print(solid) rot_trafo = tigl3.geometry.CTiglTransformation() rot_trafo.add_rotation_x(90) loft = [] loft.append(hub.get_loft().shape()) loft.append( tigl3.geometry.CNamedShape(rot_trafo.transform(solid), "cut").shape()) if propeller_number_ == 2: trafo = tigl3.geometry.CTiglTransformation() trafo.add_mirroring_at_xzplane() loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft[1]), "cut").shape()) elif propeller_number_ >= 3: delta = 360 / propeller_number_ for i in range(1, propeller_number_ + 1): loft_copy = deepcopy(loft[1]) trafo = tigl3.geometry.CTiglTransformation() trafo.add_rotation_x(delta * i) print(delta * i) loft.append( tigl3.geometry.CNamedShape(trafo.transform(loft_copy), "cut").shape()) builder = BRep_Builder() assembly = TopoDS_Compound() builder.MakeCompound(assembly) for l in loft: builder.Add(assembly, l) trafo = tigl3.geometry.CTiglTransformation() trafo.add_translation(root_le_pos_x_, root_le_pos_y_, root_le_pos_z_) assembly = trafo.transform(assembly) return [assembly]
anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment.Value(), Handle_Geom_Surface(aCyl2)) threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1.Edge(), anEdge2OnSurf1.Edge()) threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2.Edge(), anEdge2OnSurf2.Edge()) # Compute the 3D representations of the edges/wires breplib.BuildCurves3d(threadingWire1.Shape()) breplib.BuildCurves3d(threadingWire2.Shape()) # Create the surfaces of the threading aTool = BRepOffsetAPI_ThruSections(True) aTool.AddWire(threadingWire1.Wire()) aTool.AddWire(threadingWire2.Wire()) aTool.CheckCompatibility(False) myThreading = aTool.Shape() # Build the resulting compound aRes = TopoDS_Compound() aBuilder = BRep_Builder() aBuilder.MakeCompound(aRes) aBuilder.Add(aRes, myBody.Shape()) aBuilder.Add(aRes, myThreading) display, start_display, add_menu, add_function_to_menu = init_display('wx') display.DisplayColoredShape(aRes) start_display()
anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(Handle_Geom2d_Curve(anArc2), Handle_Geom_Surface(aCyl2)) anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment.Value(), Handle_Geom_Surface(aCyl2)) threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1.Edge(), anEdge2OnSurf1.Edge()) threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2.Edge(), anEdge2OnSurf2.Edge()) # Compute the 3D representations of the edges/wires breplib.BuildCurves3d(threadingWire1.Shape()) breplib.BuildCurves3d(threadingWire2.Shape()) # Create the surfaces of the threading aTool = BRepOffsetAPI_ThruSections(True) aTool.AddWire(threadingWire1.Wire()) aTool.AddWire(threadingWire2.Wire()) aTool.CheckCompatibility(False) myThreading = aTool.Shape() # Build the resulting compound bottle = TopoDS_Compound() aBuilder = BRep_Builder() aBuilder.MakeCompound(bottle) aBuilder.Add(bottle, myBody.Shape()) aBuilder.Add(bottle, myThreading) print("bottle finished") if __name__ == "__main__": from OCC.Display.SimpleGui import init_display display, start_display, add_menu, add_function_to_menu = init_display() display.DisplayColoredShape(bottle, update=True) start_display()