def test_step_exporter_overwrite(box_shape): r"""Happy path with a subclass of TopoDS_Shape""" filename = path_from_file(__file__, "./models_out/box.stp") exporter = StepExporter(filename) solid = shape_to_topology(box_shape) assert isinstance(solid, TopoDS_Solid) exporter.add_shape(solid) exporter.write_file() initial_timestamp = os.path.getmtime(filename) assert os.path.isfile(filename) # read the written box.stp importer = StepImporter(filename) topo_compound = Topo(importer.compound, return_iter=False) assert topo_compound.number_of_faces == 6 assert len(topo_compound.faces) == 6 assert topo_compound.number_of_edges == 12 # add a sphere and write again with same exporter sphere = BRepPrimAPI_MakeSphere(10) exporter.add_shape(sphere.Shape()) exporter.write_file() # this creates a file with a box and a sphere intermediate_timestamp = os.path.getmtime(filename) assert intermediate_timestamp > initial_timestamp # check that the file contains the box and the sphere importer = StepImporter(filename) # 6 from box + 1 from sphere assert len(Topo(importer.compound, return_iter=False).faces) == 7 assert len(Topo(importer.compound, return_iter=False).solids) == 2 # create a new exporter and overwrite with a box only filename = path_from_file(__file__, "./models_out/box.stp") exporter = StepExporter(filename) solid = shape_to_topology(box_shape) exporter.add_shape(solid) exporter.write_file() assert os.path.isfile(filename) last_timestamp = os.path.getmtime(filename) assert last_timestamp > intermediate_timestamp # check the file only contains a box importer = StepImporter(filename) # 6 from box assert len(Topo(importer.compound, return_iter=False).faces) == 6 assert len(Topo(importer.compound, return_iter=False).solids) == 1
def translate(brep_or_iterable, vec, copy=False): r"""Translate a TopoDS_* using a vector Parameters ---------- brep_or_iterable : TopoDS_Shape or iterable[TopoDS_Shape] the Topo_DS to translate vec the vector defining the translation copy copies to brep if True Returns ------- list[OCC.TopoDS.TopoDS_*] """ # st = occutils.types_lut.ShapeToTopology() gp_trsf = OCC.gp.gp_Trsf() gp_trsf.SetTranslation(vec) if issubclass(brep_or_iterable.__class__, OCC.TopoDS.TopoDS_Shape): brep_transform = OCC.BRepBuilderAPI.BRepBuilderAPI_Transform(brep_or_iterable, gp_trsf, copy) brep_transform.Build() return shape_to_topology(brep_transform.Shape()) else: return [translate(brep_or_iterable, vec, copy) for _ in brep_or_iterable]
def shell(*args): r"""Make a OCC.TopoDS.TopoDS_Shell Parameters ---------- args Returns ------- OCC.TopoDS.TopoDS_Shell Notes ----- BRepBuilderAPI_MakeShell (const Handle< Geom_Surface > &S, const Standard_Boolean Segment=Standard_False) BRepBuilderAPI_MakeShell (const Handle< Geom_Surface > &S, const Standard_Real UMin, const Standard_Real UMax, const Standard_Real VMin, const Standard_Real VMax, const Standard_Boolean Segment=Standard_False) """ a_shell = OCC.BRepBuilderAPI.BRepBuilderAPI_MakeShell(*args) with AssertIsDone(a_shell, 'failed to produce shell'): result = a_shell.Shell() a_shell.Delete() return shape_to_topology(result)
def sew_shapes(shapes, tolerance=1e-3): r"""Sew shapes Parameters ---------- shapes : list[OCC.TopoDS.TopoDS_Shape] tolerance : float Returns ------- OCC.TopoDS.TopoDS_* """ sew = OCC.BRepBuilderAPI.BRepBuilderAPI_Sewing(tolerance) for shp in shapes: if isinstance(shp, list): for i in shp: sew.Add(i) else: sew.Add(shp) sew.Perform() logger.info('%i degenerated shapes' % sew.NbDegeneratedShapes()) logger.info('%i deleted faces:' % sew.NbDeletedFaces()) logger.info('%i free edges' % sew.NbFreeEdges()) logger.info('%i multiple edges:' % sew.NbMultipleEdges()) return shape_to_topology(sew.SewedShape())
def test_stl_exporter_happy_path_shape_subclass(box_shape): r"""Happy path with a subclass of TopoDS_Shape""" filename = path_from_file(__file__, "./models_out/box.stl") exporter = StlExporter(filename) solid = shape_to_topology(box_shape) assert isinstance(solid, TopoDS_Solid) exporter.set_shape(solid) exporter.write_file() assert os.path.isfile(filename)
def test_stl_exporter_overwrite(box_shape): r"""Happy path with a subclass of TopoDS_Shape""" filename = path_from_file(__file__, "./models_out/box.stl") exporter = StlExporter(filename) solid = shape_to_topology(box_shape) assert isinstance(solid, TopoDS_Solid) exporter.set_shape(solid) exporter.write_file() assert os.path.isfile(filename) # read the written box.stl importer = StlImporter(filename) topo = Topo(importer.shape) assert topo.number_of_shells == 1 # set a sphere and write again with same exporter sphere = BRepPrimAPI_MakeSphere(10) exporter.set_shape(sphere.Shape()) # this creates a file with a sphere only, this is STL specific exporter.write_file() # check that the file contains the sphere only importer = StlImporter(filename) topo = Topo(importer.shape) assert topo.number_of_shells == 1 # create a new exporter and overwrite with a box only filename = path_from_file(__file__, "./models_out/box.stl") exporter = StlExporter(filename) solid = shape_to_topology(box_shape) exporter.set_shape(solid) exporter.write_file() assert os.path.isfile(filename) # check the file only contains a box importer = StlImporter(filename) topo = Topo(importer.shape) assert topo.number_of_shells == 1
def test_iges_exporter_overwrite(box_shape): r"""Happy path with a subclass of TopoDS_Shape""" filename = path_from_file(__file__, "./models_out/box.igs") exporter = IgesExporter(filename) solid = shape_to_topology(box_shape) assert isinstance(solid, TopoDS_Solid) exporter.add_shape(solid) exporter.write_file() assert os.path.isfile(filename) # read the written box.igs importer = IgesImporter(filename) topo_compound = Topo(importer.compound) assert topo_compound.number_of_faces == 6 assert topo_compound.number_of_edges == 24 # add a sphere and write again with same exporter sphere = BRepPrimAPI_MakeSphere(10) exporter.add_shape(sphere.Shape()) exporter.write_file() # this creates a file with a box and a sphere # check that the file contains the box and the sphere importer = IgesImporter(filename) topo_compound = Topo(importer.compound) assert topo_compound.number_of_faces == 7 # 6 from box + 1 from sphere # create a new exporter and overwrite with a box only filename = path_from_file(__file__, "./models_out/box.igs") exporter = IgesExporter(filename) solid = shape_to_topology(box_shape) exporter.add_shape(solid) exporter.write_file() assert os.path.isfile(filename) # check the file only contains a box importer = IgesImporter(filename) topo_compound = Topo(importer.compound) assert topo_compound.number_of_faces == 6 # 6 from box
def copy(self): r"""Copy Returns ------- A copy of self """ brep_builder_copy = OCC.BRepBuilderAPI.BRepBuilderAPI_Copy( self._wrapped_instance) brep_builder_copy.Perform(self._wrapped_instance) # get the class, construct a new instance # cast the cp.Shape() to its specific TopoDS topology _copy = self.__class__(shape_to_topology(brep_builder_copy.Shape())) return _copy
def offset(wire_or_face, offset_distance, altitude=0, join_type=OCC.GeomAbs.GeomAbs_Arc): r"""Builds a offset wire or face from a wire or face construct an offset version of the shape Parameters ---------- wire_or_face the wire or face to offset offset_distance : float the distance to offset altitude : float move the offset shape to altitude from the normal of the wire or face join_type the geom_type of offset you want can be one of OCC.GeomAbs.GeomAbs_Arc, OCC.GeomAbs.GeomAbs_Tangent, OCC.GeomAbs.GeomAbs_Intersection Returns ------- OCC.TopoDS.TopoDS_Shape Notes ----- A shape that has a negative offsetDistance will return a sharp corner """ _joints = [ OCC.GeomAbs.GeomAbs_Arc, OCC.GeomAbs.GeomAbs_Tangent, OCC.GeomAbs.GeomAbs_Intersection ] assert join_type in _joints, '%s is not one of %s' % (join_type, _joints) try: an_offset = OCC.BRepOffsetAPI.BRepOffsetAPI_MakeOffset( wire_or_face, join_type) an_offset.Perform(offset_distance, altitude) if an_offset.IsDone(): return shape_to_topology(an_offset.Shape()) else: msg = "offset not done" logger.error(msg) raise OffsetShapeException(msg) except RuntimeError: msg = "failed to offset" logger.error(msg) raise OffsetShapeException(msg)
def rotate(brep, axe, degree, copy=False): r"""Rotate around an axis Parameters ---------- brep : OCC.TopoDS.TopoDS_* axe : OCC.gp.gp_Ax1 degree : float Rotation angle in degrees copy : bool Returns ------- OCC.TopoDS.TopoDS_* """ gp_trsf = OCC.gp.gp_Trsf() gp_trsf.SetRotation(axe, math.radians(degree)) brep_transform = OCC.BRepBuilderAPI.BRepBuilderAPI_Transform(brep, gp_trsf, copy) with AssertIsDone(brep_transform, 'could not produce rotation'): brep_transform.Build() return shape_to_topology(brep_transform.Shape())
def loft(elements, ruled=False, tolerance=OCCUTILS_DEFAULT_TOLERANCE, continuity=OCC.GeomAbs.GeomAbs_C2, check_compatibility=True): r"""Loft Parameters ---------- elements ruled : bool tolerance : float continuity : OCC.GeomAbs.GeomAbs_C*, optional (the default is OCC.GeomAbs.GeomAbs_C2) check_compatibility : bool Returns ------- OCC.TopoDS.TopoDS_* """ sections = OCC.BRepOffsetAPI.BRepOffsetAPI_ThruSections( False, ruled, tolerance) for i in elements: if isinstance(i, OCC.TopoDS.TopoDS_Wire): sections.AddWire(i) elif isinstance(i, OCC.TopoDS.TopoDS_Vertex): sections.AddVertex(i) else: msg = "elements is a list of OCC.TopoDS.TopoDS_Wire or OCC.TopoDS.TopoDS_Vertex, found a %s " % i.__class__ logger.error(msg) raise TypeError(msg) sections.CheckCompatibility(check_compatibility) sections.SetContinuity(continuity) sections.Build() with AssertIsDone(sections, 'failed lofting'): # te = occutils.topology.shape_to_topology() return shape_to_topology(sections.Shape())