Beispiel #1
0
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 ?
Beispiel #2
0
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)
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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)
Beispiel #7
0
def test_iges_importer_wrong_file_content():
    r"""wrong file content"""
    with pytest.raises(IgesFileReadException):
        IgesImporter(path_from_file(__file__, "./models_in/empty.igs"))
Beispiel #8
0
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"))
Beispiel #9
0
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()
Beispiel #11
0
    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