diff --git a/.travis.yml b/.travis.yml index 4503deef..ea7721ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ install: - conda create --yes -n test python=$TRAVIS_PYTHON_VERSION - source activate test - conda install --yes numpy scipy matplotlib pip nose vtk + - conda install --yes -c https://conda.anaconda.org/dlr-sc pythonocc-core - pip install setuptools - pip install enum34 - pip install numpy-stl diff --git a/docs/source/code.rst b/docs/source/code.rst index db581a71..a81bf36c 100644 --- a/docs/source/code.rst +++ b/docs/source/code.rst @@ -14,4 +14,5 @@ Code Documentation stlhandler vtkhandler unvhandler + igeshandler diff --git a/docs/source/igeshandler.rst b/docs/source/igeshandler.rst new file mode 100644 index 00000000..d12dc03f --- /dev/null +++ b/docs/source/igeshandler.rst @@ -0,0 +1,9 @@ +Igeshandler +================= + +.. automodule:: pygem.igeshandler + +.. autoclass:: IgesHandler + :members: + :private-members: + :special-members: diff --git a/pygem/__init__.py b/pygem/__init__.py index f5f39105..5d940317 100644 --- a/pygem/__init__.py +++ b/pygem/__init__.py @@ -1,5 +1,5 @@ -__all__ = ['affine', 'filehandler', 'freeform', 'openfhandler', 'params', 'stlhandler', 'unvhandler', 'vtkhandler'] +__all__ = ['affine', 'filehandler', 'freeform', 'openfhandler', 'params', 'stlhandler', 'unvhandler', 'vtkhandler', 'igeshandler'] from . import affine from . import freeform @@ -9,3 +9,4 @@ from . import stlhandler from . import unvhandler from . import vtkhandler +from . import igeshandler diff --git a/pygem/igeshandler.py b/pygem/igeshandler.py new file mode 100644 index 00000000..3b5fffc3 --- /dev/null +++ b/pygem/igeshandler.py @@ -0,0 +1,226 @@ +""" +Utilities for reading and writing different CAD files. +""" +import numpy as np +import pygem.filehandler as fh +from OCC.IGESControl import (IGESControl_Reader, IGESControl_Writer) +from OCC.BRep import BRep_Tool +from OCC.BRepBuilderAPI import (BRepBuilderAPI_NurbsConvert, BRepBuilderAPI_MakeWire, BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeFace) +from OCC.GeomConvert import geomconvert_SurfaceToBSplineSurface +import OCC.TopoDS +from OCC.TopAbs import (TopAbs_FACE, TopAbs_EDGE) +from OCC.TopExp import TopExp_Explorer +from OCC.Geom import Geom_BSplineSurface +from OCC.gp import (gp_Pnt, gp_XYZ) +from OCC.Display.SimpleGui import init_display +from OCC.ShapeFix import ShapeFix_ShapeTolerance + + +class IgesHandler(fh.FileHandler): + """ + Iges file handler class + + :cvar string infile: name of the input file to be processed. + :cvar string outfile: name of the output file where to write in. + :cvar string extension: extension of the input/output files. It is equal to '.iges'. + :cvar list control_point_position: index of the first NURBS control point (or pole) of each face of the iges file. + """ + def __init__(self): + super(IgesHandler, self).__init__() + self.extension = '.iges' # TODO: also igs could be accepted + self._control_point_position = None + + + def parse(self, filename): + """ + Method to parse the file `filename`. It returns a matrix with all the coordinates. + + :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of + the points of the mesh + :rtype: numpy.ndarray + + .. todo:: + + - specify when it works + """ + self._check_filename_type(filename) + self._check_extension(filename) + + self.infile = filename + + ## read in the IGES file + reader = IGESControl_Reader() + reader.ReadFile(self.infile) + reader.TransferRoots() + shape = reader.Shape() + + ## cycle on the faces to get the control points + # init some quantities + 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) + iges_face = OCC.TopoDS.topods_Face(faces_explorer.Current()) + iges_nurbs_converter = BRepBuilderAPI_NurbsConvert(iges_face) + iges_nurbs_converter.Perform(iges_face) + nurbs_face = iges_nurbs_converter.Shape() + brep_face = BRep_Tool.Surface(OCC.TopoDS.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 xrange(n_poles_u): + for pole_v_direction in xrange(n_poles_v): + control_point_coordinates = occ_face.Pole(pole_u_direction+1,pole_v_direction+1) + weight = occ_face.Weight(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() + + print control_point_position + + self._control_point_position = control_point_position + + return mesh_points + + + def write(self, mesh_points, filename): + """ + Writes a iges 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 iges 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. + """ + self._check_filename_type(filename) + self._check_extension(filename) + self._check_infile_instantiation(self.infile) + + self.outfile = filename + + ## init the ouput file writer + writer = IGESControl_Writer() + + ## read in the IGES file + reader = IGESControl_Reader() + reader.ReadFile(self.infile) + reader.TransferRoots() + shape_read = reader.Shape() + + ## cycle on the faces to update the control points position + # init some quantities + faces_explorer = TopExp_Explorer(shape_read, TopAbs_FACE) + n_faces = 0 + control_point_position = self._control_point_position + + while faces_explorer.More(): + + # similar to the parser method + iges_face = OCC.TopoDS.topods_Face(faces_explorer.Current()) + iges_nurbs_converter = BRepBuilderAPI_NurbsConvert(iges_face) + iges_nurbs_converter.Perform(iges_face) + nurbs_face = iges_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 xrange(n_poles_u): + for pole_v_direction in xrange(n_poles_v): + control_point_coordinates = mesh_points[i+control_point_position[n_faces],:] + point_xyz = gp_XYZ(control_point_coordinates[0], control_point_coordinates[1], control_point_coordinates[2]) + 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 + wireMaker = BRepBuilderAPI_MakeWire() + tol = ShapeFix_ShapeTolerance() + brep = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), 1e-4).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 = OCC.BRep.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, 1e-4) + wireMaker.Add(edge_phis_coordinates) + edge_explorer.Next() + + #grouping the edges in a wire + wire = wireMaker.Wire() + + ## trimming the surfaces + brep_surf = BRepBuilderAPI_MakeFace(occ_face.GetHandle(), wire).Face() + writer.AddShape(brep_surf) + + #print writer + + n_faces += 1 + faces_explorer.Next() + + ## write out the iges file + writer.Write(self.outfile) + + + def plot(self, plot_file=None, save_fig=False): + """ + Method to plot an iges file. If `plot_file` is not given it plots `self.infile`. + + :param string plot_file: the iges filename you want to plot. + :param bool save_fig: a flag to save the figure in png or not. If True the + plot is not shown. + + .. warning:: + It does not work well up to now + """ + if plot_file is None: + plot_file = self.infile + else: + self._check_filename_type(plot_file) + + ## read in the IGES file + reader = IGESControl_Reader() + reader.ReadFile(plot_file) + reader.TransferRoots() + shape = reader.Shape() + + display, start_display, add_menu, add_function_to_menu = init_display() + display.FitAll() + display.DisplayShape(shape, update=True) + + # Show the plot to the screen + if not save_fig: + start_display() + else: + display.View.Dump(plot_file.split('.')[0] + '.ppm') + diff --git a/tests/test_datasets/parameters_test_ffd_iges.prm b/tests/test_datasets/parameters_test_ffd_iges.prm new file mode 100644 index 00000000..1b06e9f4 --- /dev/null +++ b/tests/test_datasets/parameters_test_ffd_iges.prm @@ -0,0 +1,75 @@ + +[Box info] +# This section collects all the properties of the FFD bounding box. + +# n control points indicates the number of control points in each direction (x, y, z). +# For example, to create a 2 x 3 x 2 grid, use the following: n control points: 2, 3, 2 +n control points x: 2 +n control points y: 2 +n control points z: 2 + +# box lenght indicates the length of the FFD bounding box along the three canonical directions (x, y, z). +# It uses the local coordinate system. +# For example to create a 2 x 1.5 x 3 meters box use the following: lenght box: 2.0, 1.5, 3.0 +box lenght x: 2200.0 +box lenght y: 2200.0 +box lenght z: 5100.0 + +# box origin indicates the x, y, and z coordinates of the origin of the FFD bounding box. That is center of +# rotation of the bounding box. It corresponds to the point coordinates with position [0][0][0]. +# See section "Parameters weights" for more details. +# For example, if the origin is equal to 0., 0., 0., use the following: origin box: 0., 0., 0. +box origin x: -1100.0 +box origin y: -1100.0 +box origin z: 5000.0 + +# rotation angle indicates the rotation angle around the x, y, and z axis of the FFD bounding box in degrees. +# The rotation is done with respect to the box origin. +# For example, to rotate the box by 2 deg along the z direction, use the following: rotation angle: 0., 0., 2. +rotation angle x: 0 +rotation angle y: 0 +rotation angle z: 0 + + +[Parameters weights] +# This section describes the weights of the FFD control points. +# We adopt the following convention: +# For example with a 2x2x2 grid of control points we have to fill a 2x2x2 matrix of weights. +# If a weight is equal to zero you can discard the line since the default is zero. +# +# | x index | y index | z index | weight | +# -------------------------------------- +# | 0 | 0 | 0 | 1.0 | +# | 0 | 1 | 1 | 0.0 | --> you can erase this line without effects +# | 0 | 1 | 0 | -2.1 | +# | 0 | 0 | 1 | 3.4 | + +# parameter x collects the displacements along x, normalized with the box lenght x. +parameter x: 0 0 0 0.0 + 0 0 1 0.0 + 0 1 0 0.0 + 0 1 1 0.0 + 1 0 0 0.0 + 1 0 1 0.0 + 1 1 0 0.0 + 1 1 1 0.3 + +# parameter y collects the displacements along y, normalized with the box lenght y. +parameter y: 0 0 0 0.0 + 0 0 1 0.0 + 0 1 0 0.0 + 0 1 1 0.0 + 1 0 0 0.0 + 1 0 1 0.0 + 1 1 0 0.0 + 1 1 1 0.4 + +# parameter z collects the displacements along z, normalized with the box lenght z. +parameter z: 0 0 0 0.0 + 0 0 1 0.5 + 0 1 0 0.0 + 0 1 1 0.5 + 1 0 0 0.0 + 1 0 1 0.2 + 1 1 0 0.0 + 1 1 1 0.2 diff --git a/tests/test_datasets/test_pipe.iges b/tests/test_datasets/test_pipe.iges new file mode 100644 index 00000000..361d3a32 --- /dev/null +++ b/tests/test_datasets/test_pipe.iges @@ -0,0 +1,288 @@ + S0000001 +,,31HOpen CASCADE IGES processor 6.9,13HFilename.iges, G0000001 +16HOpen CASCADE 6.9,31HOpen CASCADE IGES processor 6.9,32,308,15,308,15,G0000002 +,1.,6,1HM,1,0.01,15H20151117.094824,1E-07,10.,7Hfilippo,,11,0, G0000003 +15H20151117.094824,; G0000004 + 402 1 0 0 0 0 0 000000000D0000001 + 402 0 0 1 1 0D0000002 + 144 2 0 0 0 0 0 000020000D0000003 + 144 0 0 1 0 0D0000004 + 120 3 0 0 0 0 7 000010000D0000005 + 120 0 0 1 0 0D0000006 + 124 4 0 0 0 0 0 000000000D0000007 + 124 0 0 1 0 0D0000008 + 110 5 0 0 0 0 0 000010000D0000009 + 110 0 0 1 0 0D0000010 + 110 6 0 0 0 0 0 000010000D0000011 + 110 0 0 1 0 0D0000012 + 142 7 0 0 0 0 0 000010500D0000013 + 142 0 0 1 0 0D0000014 + 102 8 0 0 0 0 0 000010000D0000015 + 102 0 0 1 0 0D0000016 + 110 9 0 0 0 0 0 000010000D0000017 + 110 0 0 1 0 0D0000018 + 110 10 0 0 0 0 0 000010000D0000019 + 110 0 0 1 0 0D0000020 + 110 11 0 0 0 0 0 000010000D0000021 + 110 0 0 1 0 0D0000022 + 110 12 0 0 0 0 0 000010000D0000023 + 110 0 0 1 0 0D0000024 + 102 13 0 0 0 0 0 000010000D0000025 + 102 0 0 1 0 0D0000026 + 100 14 0 0 0 0 29 000010000D0000027 + 100 0 0 1 0 0D0000028 + 124 15 0 0 0 0 0 000000000D0000029 + 124 0 0 1 0 0D0000030 + 110 16 0 0 0 0 0 000010000D0000031 + 110 0 0 1 0 0D0000032 + 100 17 0 0 0 0 0 000010000D0000033 + 100 0 0 1 0 0D0000034 + 110 18 0 0 0 0 0 000010000D0000035 + 110 0 0 1 0 0D0000036 + 144 19 0 0 0 0 0 000020000D0000037 + 144 0 0 1 0 0D0000038 + 120 20 0 0 0 0 41 000010000D0000039 + 120 0 0 1 0 0D0000040 + 124 21 0 0 0 0 0 000000000D0000041 + 124 0 0 1 0 0D0000042 + 110 22 0 0 0 0 0 000010000D0000043 + 110 0 0 1 0 0D0000044 + 110 23 0 0 0 0 0 000010000D0000045 + 110 0 0 1 0 0D0000046 + 142 24 0 0 0 0 0 000010500D0000047 + 142 0 0 1 0 0D0000048 + 102 25 0 0 0 0 0 000010000D0000049 + 102 0 0 1 0 0D0000050 + 110 26 0 0 0 0 0 000010000D0000051 + 110 0 0 2 0 0D0000052 + 110 28 0 0 0 0 0 000010000D0000053 + 110 0 0 1 0 0D0000054 + 110 29 0 0 0 0 0 000010000D0000055 + 110 0 0 1 0 0D0000056 + 110 30 0 0 0 0 0 000010000D0000057 + 110 0 0 1 0 0D0000058 + 102 31 0 0 0 0 0 000010000D0000059 + 102 0 0 1 0 0D0000060 + 100 32 0 0 0 0 63 000010000D0000061 + 100 0 0 1 0 0D0000062 + 124 33 0 0 0 0 0 000000000D0000063 + 124 0 0 1 0 0D0000064 + 110 34 0 0 0 0 0 000010000D0000065 + 110 0 0 1 0 0D0000066 + 100 35 0 0 0 0 0 000010000D0000067 + 100 0 0 1 0 0D0000068 + 110 36 0 0 0 0 0 000010000D0000069 + 110 0 0 1 0 0D0000070 + 144 37 0 0 0 0 0 000020000D0000071 + 144 0 0 1 0 0D0000072 + 120 38 0 0 0 0 75 000010000D0000073 + 120 0 0 1 0 0D0000074 + 124 39 0 0 0 0 0 000000000D0000075 + 124 0 0 1 0 0D0000076 + 110 40 0 0 0 0 0 000010000D0000077 + 110 0 0 1 0 0D0000078 + 110 41 0 0 0 0 0 000010000D0000079 + 110 0 0 1 0 0D0000080 + 142 42 0 0 0 0 0 000010500D0000081 + 142 0 0 1 0 0D0000082 + 102 43 0 0 0 0 0 000010000D0000083 + 102 0 0 1 0 0D0000084 + 110 44 0 0 0 0 0 000010000D0000085 + 110 0 0 2 0 0D0000086 + 110 46 0 0 0 0 0 000010000D0000087 + 110 0 0 1 0 0D0000088 + 110 47 0 0 0 0 0 000010000D0000089 + 110 0 0 1 0 0D0000090 + 110 48 0 0 0 0 0 000010000D0000091 + 110 0 0 1 0 0D0000092 + 102 49 0 0 0 0 0 000010000D0000093 + 102 0 0 1 0 0D0000094 + 100 50 0 0 0 0 97 000010000D0000095 + 100 0 0 1 0 0D0000096 + 124 51 0 0 0 0 0 000000000D0000097 + 124 0 0 1 0 0D0000098 + 110 52 0 0 0 0 0 000010000D0000099 + 110 0 0 1 0 0D0000100 + 100 53 0 0 0 0 0 000010000D0000101 + 100 0 0 1 0 0D0000102 + 110 54 0 0 0 0 0 000010000D0000103 + 110 0 0 1 0 0D0000104 + 144 55 0 0 0 0 0 000020000D0000105 + 144 0 0 1 0 0D0000106 + 120 56 0 0 0 0 109 000010000D0000107 + 120 0 0 1 0 0D0000108 + 124 57 0 0 0 0 0 000000000D0000109 + 124 0 0 1 0 0D0000110 + 110 58 0 0 0 0 0 000010000D0000111 + 110 0 0 1 0 0D0000112 + 110 59 0 0 0 0 0 000010000D0000113 + 110 0 0 1 0 0D0000114 + 142 60 0 0 0 0 0 000010500D0000115 + 142 0 0 1 0 0D0000116 + 102 61 0 0 0 0 0 000010000D0000117 + 102 0 0 1 0 0D0000118 + 110 62 0 0 0 0 0 000010000D0000119 + 110 0 0 2 0 0D0000120 + 110 64 0 0 0 0 0 000010000D0000121 + 110 0 0 1 0 0D0000122 + 110 65 0 0 0 0 0 000010000D0000123 + 110 0 0 1 0 0D0000124 + 110 66 0 0 0 0 0 000010000D0000125 + 110 0 0 1 0 0D0000126 + 102 67 0 0 0 0 0 000010000D0000127 + 102 0 0 1 0 0D0000128 + 100 68 0 0 0 0 131 000010000D0000129 + 100 0 0 1 0 0D0000130 + 124 69 0 0 0 0 0 000000000D0000131 + 124 0 0 1 0 0D0000132 + 110 70 0 0 0 0 0 000010000D0000133 + 110 0 0 1 0 0D0000134 + 100 71 0 0 0 0 0 000010000D0000135 + 100 0 0 1 0 0D0000136 + 110 72 0 0 0 0 0 000010000D0000137 + 110 0 0 1 0 0D0000138 + 144 73 0 0 0 0 0 000020000D0000139 + 144 0 0 1 0 0D0000140 + 108 74 0 0 0 0 0 000010000D0000141 + 108 0 0 1 0 0D0000142 + 142 75 0 0 0 0 0 000010500D0000143 + 142 0 0 1 0 0D0000144 + 102 76 0 0 0 0 0 000010000D0000145 + 102 0 0 1 0 0D0000146 + 100 77 0 0 0 0 149 000010000D0000147 + 100 0 0 1 0 0D0000148 + 124 78 0 0 0 0 0 000000000D0000149 + 124 0 0 1 0 0D0000150 + 100 79 0 0 0 0 153 000010000D0000151 + 100 0 0 1 0 0D0000152 + 124 80 0 0 0 0 0 000000000D0000153 + 124 0 0 1 0 0D0000154 + 100 81 0 0 0 0 157 000010000D0000155 + 100 0 0 1 0 0D0000156 + 124 82 0 0 0 0 0 000000000D0000157 + 124 0 0 1 0 0D0000158 + 100 83 0 0 0 0 161 000010000D0000159 + 100 0 0 1 0 0D0000160 + 124 84 0 0 0 0 0 000000000D0000161 + 124 0 0 1 0 0D0000162 + 144 85 0 0 0 0 0 000020000D0000163 + 144 0 0 1 0 0D0000164 + 108 86 0 0 0 0 0 000010000D0000165 + 108 0 0 1 0 0D0000166 + 142 87 0 0 0 0 0 000010500D0000167 + 142 0 0 1 0 0D0000168 + 102 88 0 0 0 0 0 000010000D0000169 + 102 0 0 1 0 0D0000170 + 100 89 0 0 0 0 173 000010000D0000171 + 100 0 0 1 0 0D0000172 + 124 90 0 0 0 0 0 000000000D0000173 + 124 0 0 1 0 0D0000174 + 100 91 0 0 0 0 177 000010000D0000175 + 100 0 0 1 0 0D0000176 + 124 92 0 0 0 0 0 000000000D0000177 + 124 0 0 1 0 0D0000178 + 100 93 0 0 0 0 181 000010000D0000179 + 100 0 0 1 0 0D0000180 + 124 94 0 0 0 0 0 000000000D0000181 + 124 0 0 1 0 0D0000182 + 100 95 0 0 0 0 185 000010000D0000183 + 100 0 0 1 0 0D0000184 + 124 96 0 0 0 0 0 000000000D0000185 + 124 0 0 1 0 0D0000186 +402,6,3,37,71,105,139,163; 0000001P0000001 +144,5,1,0,13; 0000003P0000002 +120,9,11,6.283185307,7.853981634; 0000005P0000003 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,0.; 0000007P0000004 +110,0.,0.,1.,0.,0.,0.; 0000009P0000005 +110,1.,0.,-10.,1.,0.,0.; 0000011P0000006 +142,0,5,15,25,3; 0000013P0000007 +102,4,17,19,21,23; 0000015P0000008 +110,3.487868498E-17,7.853981634,0.,0.,6.283185307,0.; 0000017P0000009 +110,-1.110223025E-16,6.283185307,0.,1.,6.283185307,0.; 0000019P0000010 +110,1.,6.283185307,0.,1.,7.853981634,0.; 0000021P0000011 +110,1.,7.853981634,0.,-1.110223025E-16,7.853981634,0.; 0000023P0000012 +102,4,27,31,33,35; 0000025P0000013 +100,0.,0.,0.,-1.836970199E-16,-1.,1.,-2.449293598E-16; 0000027P0000014 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,10.; 0000029P0000015 +110,1.,-1.224646746E-16,10.,1.,-1.224646746E-16,0.; 0000031P0000016 +100,0.,0.,0.,1.,0.,6.123233996E-17,1.; 0000033P0000017 +110,6.123233996E-17,1.,0.,6.123233996E-17,1.,10.; 0000035P0000018 +144,39,1,0,47; 0000037P0000019 +120,43,45,7.853981634,9.424777961; 0000039P0000020 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,0.; 0000041P0000021 +110,0.,0.,1.,0.,0.,0.; 0000043P0000022 +110,1.,0.,-10.,1.,0.,0.; 0000045P0000023 +142,0,39,49,59,3; 0000047P0000024 +102,4,51,53,55,57; 0000049P0000025 +110,6.975736996E-17,9.424777961,0.,3.487868498E-17,7.853981634, 0000051P0000026 +0.; 0000051P0000027 +110,-1.110223025E-16,7.853981634,0.,1.,7.853981634,0.; 0000053P0000028 +110,1.,7.853981634,0.,1.,9.424777961,0.; 0000055P0000029 +110,1.,9.424777961,0.,-1.110223025E-16,9.424777961,0.; 0000057P0000030 +102,4,61,65,67,69; 0000059P0000031 +100,0.,0.,0.,-1.,1.224646799E-16,-1.836970199E-16,-1.; 0000061P0000032 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,10.; 0000063P0000033 +110,6.123233996E-17,1.,10.,6.123233996E-17,1.,0.; 0000065P0000034 +100,0.,0.,0.,6.123233996E-17,1.,-1.,1.224646799E-16; 0000067P0000035 +110,-1.,1.224646799E-16,0.,-1.,1.224646799E-16,10.; 0000069P0000036 +144,73,1,0,81; 0000071P0000037 +120,77,79,9.424777961,10.995574288; 0000073P0000038 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,0.; 0000075P0000039 +110,0.,0.,1.,0.,0.,0.; 0000077P0000040 +110,1.,0.,-10.,1.,0.,0.; 0000079P0000041 +142,0,73,83,93,3; 0000081P0000042 +102,4,85,87,89,91; 0000083P0000043 +110,1.046360549E-16,10.995574288,0.,6.975736996E-17,9.424777961, 0000085P0000044 +0.; 0000085P0000045 +110,-1.110223025E-16,9.424777961,0.,1.,9.424777961,0.; 0000087P0000046 +110,1.,9.424777961,0.,1.,10.995574288,0.; 0000089P0000047 +110,1.,10.995574288,0.,0.,10.995574288,0.; 0000091P0000048 +102,4,95,99,101,103; 0000093P0000049 +100,0.,0.,0.,6.123233996E-17,1.,-1.,1.224646799E-16; 0000095P0000050 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,10.; 0000097P0000051 +110,-1.,1.224646799E-16,10.,-1.,1.224646799E-16,0.; 0000099P0000052 +100,0.,0.,0.,-1.,1.224646799E-16,-1.836970199E-16,-1.; 0000101P0000053 +110,-1.836970199E-16,-1.,0.,-1.836970199E-16,-1.,10.; 0000103P0000054 +144,107,1,0,115; 0000105P0000055 +120,111,113,10.995574288,12.566370614; 0000107P0000056 +124,1.,-0.,0.,0.,0.,-1.,-0.,0.,0.,0.,-1.,0.; 0000109P0000057 +110,0.,0.,1.,0.,0.,0.; 0000111P0000058 +110,1.,0.,-10.,1.,0.,0.; 0000113P0000059 +142,0,107,117,127,3; 0000115P0000060 +102,4,119,121,123,125; 0000117P0000061 +110,1.395147399E-16,12.566370614,0.,1.046360549E-16, 0000119P0000062 +10.995574288,0.; 0000119P0000063 +110,0.,10.995574288,0.,1.,10.995574288,0.; 0000121P0000064 +110,1.,10.995574288,0.,1.,12.566370614,0.; 0000123P0000065 +110,1.,12.566370614,0.,0.,12.566370614,0.; 0000125P0000066 +102,4,129,133,135,137; 0000127P0000067 +100,0.,0.,0.,1.,0.,6.123233996E-17,1.; 0000129P0000068 +124,1.,0.,0.,0.,0.,-1.,-0.,0.,0.,0.,-1.,10.; 0000131P0000069 +110,-1.836970199E-16,-1.,10.,-1.836970199E-16,-1.,0.; 0000133P0000070 +100,0.,0.,0.,-1.836970199E-16,-1.,1.,-2.449293598E-16; 0000135P0000071 +110,1.,-1.224646746E-16,0.,1.,-1.224646746E-16,10.; 0000137P0000072 +144,141,1,0,143; 0000139P0000073 +108,0.,0.,-1.,0.,0,1.,0.,0.,0.; 0000141P0000074 +142,0,141,0,145,2; 0000143P0000075 +102,4,147,151,155,159; 0000145P0000076 +100,0.,0.,0.,1.,0.,6.123233996E-17,1.; 0000147P0000077 +124,1.,0.,0.,0.,0.,-1.,-0.,0.,0.,0.,-1.,0.; 0000149P0000078 +100,0.,0.,0.,6.123233996E-17,1.,-1.,1.224646799E-16; 0000151P0000079 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,0.; 0000153P0000080 +100,0.,0.,0.,-1.,1.224646799E-16,-1.836970199E-16,-1.; 0000155P0000081 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,0.; 0000157P0000082 +100,0.,0.,0.,-1.836970199E-16,-1.,1.,-2.449293598E-16; 0000159P0000083 +124,1.,0.,0.,0.,0.,-1.,0.,0.,0.,0.,-1.,0.; 0000161P0000084 +144,165,1,0,167; 0000163P0000085 +108,-0.,-0.,1.,10.,0,1.,0.,10.,0.; 0000165P0000086 +142,0,165,0,169,2; 0000167P0000087 +102,4,171,175,179,183; 0000169P0000088 +100,0.,0.,0.,1.,0.,6.123233996E-17,1.; 0000171P0000089 +124,1.,0.,0.,0.,0.,1.,0.,0.,0.,0.,1.,10.; 0000173P0000090 +100,0.,0.,0.,6.123233996E-17,1.,-1.,1.224646799E-16; 0000175P0000091 +124,1.,0.,0.,0.,0.,1.,0.,0.,0.,0.,1.,10.; 0000177P0000092 +100,0.,0.,0.,-1.,1.224646799E-16,-1.836970199E-16,-1.; 0000179P0000093 +124,1.,0.,0.,0.,0.,1.,0.,0.,0.,0.,1.,10.; 0000181P0000094 +100,0.,0.,0.,-1.836970199E-16,-1.,1.,-2.449293598E-16; 0000183P0000095 +124,1.,0.,0.,0.,0.,1.,0.,0.,0.,0.,1.,10.; 0000185P0000096 +S 1G 4D 186P 96 T0000001 diff --git a/tests/test_igeshandler.py b/tests/test_igeshandler.py new file mode 100644 index 00000000..4e207c2a --- /dev/null +++ b/tests/test_igeshandler.py @@ -0,0 +1,147 @@ + +from unittest import TestCase +import unittest +import pygem.igeshandler as ih +import numpy as np +import filecmp +import os + + +class TestIgesHandler(TestCase): + + + def test_iges_instantiation(self): + iges_handler = ih.IgesHandler() + + + def test_iges_default_infile_member(self): + iges_handler = ih.IgesHandler() + assert iges_handler.infile == None + + + def test_iges_default_control_point_position_member(self): + iges_handler = ih.IgesHandler() + assert iges_handler._control_point_position == None + + + def test_iges_default_outfile_member(self): + iges_handler = ih.IgesHandler() + assert iges_handler.outfile == None + + + def test_iges_default_extension_member(self): + iges_handler = ih.IgesHandler() + assert iges_handler.extension == '.iges' + + + def test_iges_parse_failing_filename_type(self): + iges_handler = ih.IgesHandler() + with self.assertRaises(TypeError): + mesh_points = iges_handler.parse(5.2) + + + def test_iges_parse_failing_check_extension(self): + iges_handler = ih.IgesHandler() + with self.assertRaises(ValueError): + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.vtk') + + + def test_iges_parse_infile(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + assert iges_handler.infile == 'tests/test_datasets/test_pipe.iges' + + + def test_iges_parse_control_point_position_member(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + assert iges_handler._control_point_position == [0, 6, 12, 18, 24, 28, 32] + + + def test_iges_parse_shape(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + assert mesh_points.shape == (32, 3) + + + def test_iges_parse_coords_1(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + np.testing.assert_almost_equal(mesh_points[6][0], -1000.0) + + + def test_iges_parse_coords_2(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + np.testing.assert_almost_equal(mesh_points[8][1], 999.99999997448208) + + + def test_iges_parse_coords_3(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + np.testing.assert_almost_equal(mesh_points[30][2], 10000.0) + + + def test_iges_parse_coords_4(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + np.testing.assert_almost_equal(mesh_points[0][0], 0.0) + + + def test_iges_parse_coords_5(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + np.testing.assert_almost_equal(mesh_points[-1][2], 10000.0) + + + def test_iges_write_failing_filename_type(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + with self.assertRaises(TypeError): + iges_handler.write(mesh_points, -2) + + + def test_iges_write_failing_check_extension(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + with self.assertRaises(ValueError): + iges_handler.write(mesh_points, 'tests/test_datasets/test_square.stl') + + + def test_iges_write_failing_infile_instantiation(self): + iges_handler = ih.IgesHandler() + mesh_points = np.zeros((20, 3)) + with self.assertRaises(RuntimeError): + iges_handler.write(mesh_points, 'tests/test_datasets/test_pipe_out.iges') + + + def test_iges_write_outfile(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + outfilename = 'tests/test_datasets/test_pipe_out.iges' + iges_handler.write(mesh_points, outfilename) + assert iges_handler.outfile == outfilename + os.remove(outfilename) + + + def test_iges_write_comparison(self): + iges_handler = ih.IgesHandler() + mesh_points = iges_handler.parse('tests/test_datasets/test_pipe.iges') + mesh_points[0][0] = 2.2 + mesh_points[5][1] = 4.3 + mesh_points[9][2] = 0.5 + mesh_points[12][0] = 7.2 + mesh_points[16][1] = -1.2 + mesh_points[31][2] = -3.6 + + outfilename = 'tests/test_datasets/test_pipe_out.iges' + + iges_handler.write(mesh_points, outfilename) + os.remove(outfilename) + + + def test_iges_plot_failing_outfile_type(self): + iges_handler = ih.IgesHandler() + with self.assertRaises(TypeError): + iges_handler.plot(plot_file=3) + diff --git a/tests/test_package.py b/tests/test_package.py index 4d63c695..96ce6415 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -44,6 +44,11 @@ def test_import_pg_7(self): vtkh = pg.vtkhandler.VtkHandler() + def test_import_pg_8(self): + import pygem as pg + igesh = pg.igeshandler.IgesHandler() + + def test_modules_name(self): import pygem package = pygem