def test_iges_importer_happy_topology(): r"""import iges file containing a box and test topology""" importer = IgesImporter(path_from_file(__file__, "./models_in/box.igs")) topo = Topo(importer.compound, return_iter=False) assert topo.number_of_faces == 6 assert topo.number_of_edges == 24 # 12 edges * 2 possible orientations ?
def test_iges_importer_happy_path(): r"""happy path""" importer = IgesImporter( path_from_file(__file__, "./models_in/aube_pleine.iges")) assert isinstance(importer.compound, TopoDS_Compound) assert isinstance(importer.shapes, list) for shape in importer.shapes: assert isinstance(shape, TopoDS_Shape)
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 test_iges_importer_2_boxes(): r"""Import an iges file containing 2 distinct boxes and test topology Notes ----- This shows the current limitations of the IgesImporter as 2 boxes cannot be distinguished from one another """ importer = IgesImporter(path_from_file(__file__, "./models_in/2_boxes.igs")) topo = Topo(importer.compound, return_iter=False) assert topo.number_of_faces == 6 * 2 assert topo.number_of_edges == 24 * 2
def handle_cad_file_open(): r"""Handle the logic of cad file opening Returns ------- path : str type_ : str iges, step, stl brep shapes: list[OCC.TopoDS.TopoDS_Shape] """ with OpenCadDialog() as open_cad_file_dialog: if open_cad_file_dialog.ShowModal() == wx.ID_OK: # cast the path from the FileDialog to st to avoid # TypeError: in method 'XSControl_Reader_ReadFile', # argument 2 of type 'char const *' path = str(open_cad_file_dialog.GetPath()) extension = extract_file_extension(path) if extension.lower() in step_extensions: type_ = "step" shapes = StepImporter(path).shapes elif extension.lower() in iges_extensions: type_ = "iges" shapes = IgesImporter(path).shapes elif extension.lower() in stl_extensions: type_ = "stl" shapes = list() shapes.append(StlImporter(path).shape) elif extension.lower() in brep_extensions: type_ = "brep" shapes = list() shapes.append(BrepImporter(path).shape) else: raise ValueError("File extension indicates a file type that " "is not supported") # return filepath + type (iges ...) + list of shapes return path, type_, shapes else: # cancel button return None, None, None
def convert_iges_file(iges_filename, target_folder, remove_original=True): r"""Convert an IGES file (.iges, .igs) for web display Parameters ---------- iges_filename : str Full path to IGES file target_folder : str Full path to the target folder for the conversion remove_original : bool Should the input file be deleted after conversion? It should be deleted on a web platform to save disk space, but, for testing, it might be useful not to delete it. Returns ------- Nothing, it is a procedure """ if not isdir(target_folder): mkdir(target_folder) converted_basenames = [] importer = IgesImporter(iges_filename) shapes = importer.shapes max_dim = BoundingBox(importer.compound).max_dimension for i, shape in enumerate(shapes): converted_filename = _conversion_filename(iges_filename, target_folder, i) _convert_shape(shape, converted_filename) converted_basenames.append(basename(converted_filename)) _write_descriptor( max_dim, converted_basenames, _descriptor_filename(target_folder, basename(iges_filename))) if remove_original is True: remove(iges_filename)
def test_iges_importer_wrong_file_content(): r"""wrong file content""" with pytest.raises(IgesFileReadException): IgesImporter(path_from_file(__file__, "./models_in/empty.igs"))
def test_iges_importer_wrong_extension(): r"""wrong file format (i.e. trying to read a step file with iges importer)""" with pytest.raises(IncompatibleFileFormatException): IgesImporter(path_from_file(__file__, "./models_in/aube_pleine.stp"))
def test_iges_importer_wrong_path(): r"""Wrong filename""" with pytest.raises(FileNotFoundError): IgesImporter("C:/stupid-filename.bad_extension")
from OCC.Display.SimpleGui import init_display from aocutils.display.topology import faces from aocutils.display.defaults import backend from aocxchange.iges import IgesImporter from corelib.core.files import path_from_file logging.basicConfig(level=logging.DEBUG, format='%(asctime)s :: %(levelname)6s :: %(module)20s :: ' '%(lineno)3d :: %(message)s') backend = backend display, start_display, add_menu, add_function_to_menu = init_display(backend) filename = path_from_file(__file__, "./models_in/iges/2_boxes.igs") iges_importer = IgesImporter(filename) the_shapes = iges_importer.shapes print(iges_importer.nb_shapes) # 13 print(len(iges_importer.shapes)) # 13 # display.DisplayShape(iges_importer.compound) # there are no shells or solids in the compound (IGES specific) faces(display, iges_importer.compound) display.FitAll() display.View_Iso() start_display()
def on_selected_change(self, change): """Callback function for listener""" # TODO: investigate why importing Part # at top of file causes an app crash from cadracks_core.model import Part logger.debug("Selection changed") sel = self.model.selected logger.debug("sel : %s" % sel) if not isdir(sel): # what extension ? ext = splitext(sel)[1].lower() logger.info("File extension : %s" % ext) if ext == ".py": with open(sel) as f: content = f.read() if is_valid_python(content) is True: busy_info = wx.BusyInfo( "Loading Python defined geometry ...") try: module_ = imp.load_source(sel, sel) has_shape = hasattr(module_, "__shape__") has_shapes = hasattr(module_, "__shapes__") has_anchors = hasattr(module_, "__anchors__") has_properties = hasattr(module_, "__properties__") has_assembly = hasattr(module_, "__assembly__") has_assemblies = hasattr(module_, "__assemblies__") self.erase_all() if has_shapes is True: logger.info("%s has shapeS" % sel) for i, shape in enumerate(module_.__shapes__): self.display_shape(shape, color_=colour_wx_to_occ( color_from_sequence( i, "colors"))) elif has_assembly is True: logger.info("%s has assembly" % sel) try: self.display_assembly(module_.__assembly__) self.viewer_display.FitAll() except KeyError as ke: self.erase_all() logger.exception(ke) elif has_assemblies is True: logger.info("%s has assemblies" % sel) try: self.display_assemblies(module_.__assemblies__) self.viewer_display.FitAll() except KeyError as ke: self.erase_all() logger.exception(ke) # elif has_shape is True and has_anchors is True: elif has_shape is True: if has_anchors is False: logger.info("%s has shape" % sel) self.display_shape(module_.__shape__) else: logger.info("%s has shape and anchors" % sel) p = anchorable_part_from_py_script(sel) self.display_part(p) self.viewer_display.FitAll() else: self.erase_all() logger.warning("Nothing to display") except Exception as e: logger.error(str(e)) finally: del busy_info else: # the file is not a valid Python file logger.warning("Not a valid python file") self.erase_all() elif ext in [".step", ".stp"]: self.erase_all() busy_info = wx.BusyInfo("Loading STEP ...") try: shapes = StepImporter(sel).shapes logger.info("%i shapes in %s" % (len(shapes), sel)) for shape in shapes: color_255 = (255, 255, 255) self.display_shape(shape, color_=colour_wx_to_occ(color_255), transparency=0.1) self.viewer_display.FitAll() except Exception as e: logger.error(str(e)) finally: del busy_info elif ext in [".iges", ".igs"]: self.erase_all() busy_info = wx.BusyInfo("Loading IGES ...") try: shapes = IgesImporter(sel).shapes logger.info("%i shapes in %s" % (len(shapes), sel)) for shape in shapes: color_255 = (51, 255, 255) self.display_shape(shape, color_=colour_wx_to_occ(color_255), transparency=0.1) self.viewer_display.FitAll() except Exception as e: logger.error(str(e)) finally: del busy_info elif ext == ".stl": self.erase_all() busy_info = wx.BusyInfo("Loading STL ...") try: shape = StlImporter(sel).shape color_255 = (0, 255, 0) self.display_shape(shape, color_=colour_wx_to_occ(color_255), transparency=0.1) self.viewer_display.FitAll() except Exception as e: logger.error(str(e)) finally: del busy_info elif ext == ".json": # parts library self.erase_all() is_library_file = False with open(sel) as json_file: if "metadata" in json_file.read(): is_library_file = True if is_library_file is True: busy_info = wx.BusyInfo("Loading parts library ...") try: with open(sel) as json_file: json_file_content = json.load(json_file) # print(json_file_content["data"].keys()) # find the biggest bounding box biggest_bb = [0, 0, 0] # smallest_bb = [0, 0, 0] for i, k in enumerate( json_file_content["data"].keys()): library_part = anchorable_part_from_library( sel, k) bb = BoundingBox(library_part.shape) if bb.x_span > biggest_bb[0]: biggest_bb[0] = bb.x_span # if bb.x_span < smallest_bb[0]: # smallest_bb[0] = bb.x_span if bb.y_span > biggest_bb[1]: biggest_bb[1] = bb.y_span # if bb.y_span < smallest_bb[1]: # smallest_bb[1] = bb.y_span if bb.z_span > biggest_bb[2]: biggest_bb[2] = bb.z_span # if bb.z_span < smallest_bb[2]: # smallest_bb[2] = bb.y_span biggest_dimension = max(biggest_bb) # smallest_dimension = min(smallest_bb) nb_per_row = int( math.sqrt(len( json_file_content["data"].keys()))) for i, k in enumerate( json_file_content["data"].keys()): library_part = anchorable_part_from_library( sel, k) x_pos = biggest_dimension * 2 * (i % nb_per_row) y_pos = biggest_dimension * 2 * (i // nb_per_row) # Translate using an AnchorTransformation library_part.add_matrix_generator( AnchorTransformation( Anchor(p=(0, 0, 0), u=(1, 0, 0), v=(0, 1, 0), name='a'), Anchor(p=(x_pos, y_pos, 0), u=(1, 0, 0), v=(0, 1, 0), name='b'))) self.display_part(library_part, transparency=0.2, anchor_names_height=10) pnt_message = gp_Pnt( x_pos + biggest_dimension / 5, y_pos + biggest_dimension / 5, 0) self.display_message(pnt_message, k, message_color=(1, 1, 1), height=20) self.viewer_display.FitAll() except Exception as e: logger.error(str(e)) finally: del busy_info elif ext == ".stepzip": self.erase_all() busy_info = wx.BusyInfo("Loading STEPZIP ...") try: self.display_part(anchorable_part_from_stepzip(sel), transparency=0.2) self.viewer_display.FitAll() except Exception as e: logger.error(str(e)) finally: del busy_info else: logger.error("File has an extension %s that is not " "handled by the 3D panel" % ext) self.erase_all() else: # a directory is selected self.erase_all() self.Layout() logger.debug("code change detected in 3D panel")
#!/usr/bin/env python # coding: utf-8 r"""Hull FFD example with IGES""" from aocxchange.iges import IgesImporter from aocutils.analyze.bounds import BoundingBox import pygem as pg from pygem.utils import write_bounding_box # Bounding box hull_shape_compound = \ IgesImporter(filename="./example_hull_iges/SYSSER01_Z0WL.igs").compound bb = BoundingBox(hull_shape_compound) print("X min : %f" % bb.x_min) print("X max : %f" % bb.x_max) print("Y min : %f" % bb.y_min) print("Y max : %f" % bb.y_max) print("Z min : %f" % bb.z_min) print("Z max : %f" % bb.z_max) assert abs(abs(bb.y_min) - abs(bb.y_max)) <= 1e-6 # Initial file loading and visualization iges_handler = pg.igeshandler.IgesHandler() mesh_points = iges_handler.parse('./example_hull_iges/SYSSER01_Z0WL.igs') iges_handler.check_topology() # Display the unmodified hull in 2 possible ways