diff --git a/pygem/filehandler.py b/pygem/filehandler.py index d0bdf65..3b6c6ce 100644 --- a/pygem/filehandler.py +++ b/pygem/filehandler.py @@ -10,8 +10,8 @@ class FileHandler(object): :cvar string infile: name of the input file to be processed. :cvar string outfile: name of the output file where to write in. - :cvar list extensions: extensions of the input/output files. It is specific for each - subclass. + :cvar list extensions: extensions of the input/output files. It is specific + for each subclass. """ def __init__(self): @@ -41,8 +41,8 @@ def write(self, *args): def _check_extension(self, filename): """ - This private class method checks if the given `filename` has the proper `extension` set - in the child class. If not it raises a ValueError. + This private class method checks if the given `filename` has the proper + `extension` set in the child class. If not it raises a ValueError. :param string filename: file to check. """ @@ -50,13 +50,14 @@ def _check_extension(self, filename): if file_ext not in self.extensions: raise ValueError( 'The input file does not have the proper extension. \ - It is {0!s}, instead of {1!s}.'.format(file_ext, - self.extensions)) + It is {0!s}, instead of {1!s}.' + .format(file_ext, self.extensions)) @staticmethod def _check_filename_type(filename): """ - This private static method checks if `filename` is a string. If not it raises a TypeError. + This private static method checks if `filename` is a string. If not it + raises a TypeError. :param string filename: file to check. """ @@ -66,9 +67,9 @@ def _check_filename_type(filename): def _check_infile_instantiation(self): """ - This private method checks if `self.infile` is instantiated. If not it means - that nobody called the parse method and `self.infile` is None. If the check fails - it raises a RuntimeError. + This private method checks if `self.infile` is instantiated. If not + it means that nobody called the parse method and `self.infile` is None. + If the check fails it raises a RuntimeError. """ if not self.infile: diff --git a/pygem/freeform.py b/pygem/freeform.py index 4321b03..55686b7 100644 --- a/pygem/freeform.py +++ b/pygem/freeform.py @@ -98,13 +98,13 @@ def perform(self): self.original_mesh_points - translation, transformation) # select mesh points inside bounding box - mesh_points = reference_frame_mesh_points[ - (reference_frame_mesh_points[:, 0] >= 0.) - & (reference_frame_mesh_points[:, 0] <= 1.) & - (reference_frame_mesh_points[:, 1] >= 0.) & - (reference_frame_mesh_points[:, 1] <= 1.) & - (reference_frame_mesh_points[:, 2] >= 0.) & - (reference_frame_mesh_points[:, 2] <= 1.)] + mesh_points = reference_frame_mesh_points[( + reference_frame_mesh_points[:, 0] >= 0.) & ( + reference_frame_mesh_points[:, 0] <= 1.) & ( + reference_frame_mesh_points[:, 1] >= 0.) & ( + reference_frame_mesh_points[:, 1] <= 1.) & ( + reference_frame_mesh_points[:, 2] >= 0.) & ( + reference_frame_mesh_points[:, 2] <= 1.)] (n_rows_mesh, n_cols_mesh) = mesh_points.shape # Initialization. In order to exploit the contiguity in memory the @@ -156,13 +156,12 @@ def perform(self): # merge non-shifted mesh points with shifted ones self.modified_mesh_points = np.copy(self.original_mesh_points) - self.modified_mesh_points[(reference_frame_mesh_points[:, 0] >= 0.) - & (reference_frame_mesh_points[:, 0] <= 1.) & - (reference_frame_mesh_points[:, 1] >= 0.) & - (reference_frame_mesh_points[:, 1] <= 1.) & - (reference_frame_mesh_points[:, 2] >= 0.) & - (reference_frame_mesh_points[:, 2] <= - 1.)] = new_mesh_points + self.modified_mesh_points[(reference_frame_mesh_points[:, 0] >= 0.) & ( + reference_frame_mesh_points[:, 0] <= 1. + ) & (reference_frame_mesh_points[:, 1] >= 0.) & ( + reference_frame_mesh_points[:, 1] <= 1.) & ( + reference_frame_mesh_points[:, 2] >= 0.) & ( + reference_frame_mesh_points[:, 2] <= 1.)] = new_mesh_points @staticmethod def _transform_points(original_points, transformation): diff --git a/pygem/nurbshandler.py b/pygem/nurbshandler.py index d9c8c5e..24909b7 100644 --- a/pygem/nurbshandler.py +++ b/pygem/nurbshandler.py @@ -1,27 +1,33 @@ """ Derived module from filehandler.py to handle iges/igs and step/stp files. Implements all methods for parsing an object and applying FFD. -File handling operations (reading/writing) must be implemented in derived classes. +File handling operations (reading/writing) must be implemented +in derived classes. """ import os import numpy as np -import OCC.TopoDS -from OCC.BRep import (BRep_Tool, BRep_Builder, BRep_Tool_Curve) -from OCC.BRepBuilderAPI import (BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeFace, \ - BRepBuilderAPI_NurbsConvert, BRepBuilderAPI_MakeWire, BRepBuilderAPI_Sewing) +from OCC.BRep import BRep_Tool, BRep_Builder, BRep_Tool_Curve +from OCC.BRepAlgo import brepalgo_IsValid +from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeEdge +from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeFace +from OCC.BRepBuilderAPI import BRepBuilderAPI_NurbsConvert +from OCC.BRepBuilderAPI import BRepBuilderAPI_MakeWire +from OCC.BRepBuilderAPI import BRepBuilderAPI_Sewing +from OCC.BRepOffsetAPI import BRepOffsetAPI_FindContigousEdges from OCC.Display.SimpleGui import init_display -from OCC.GeomConvert import (geomconvert_SurfaceToBSplineSurface, - geomconvert_CurveToBSplineCurve) -from OCC.ShapeFix import (ShapeFix_ShapeTolerance, ShapeFix_Shell) +from OCC.GeomConvert import geomconvert_SurfaceToBSplineSurface +from OCC.GeomConvert import geomconvert_CurveToBSplineCurve +from OCC.gp import gp_Pnt, gp_XYZ +from OCC.Precision import precision_Confusion from OCC.ShapeAnalysis import ShapeAnalysis_WireOrder -import OCC.Precision +from OCC.ShapeFix import ShapeFix_ShapeTolerance, ShapeFix_Shell from OCC.StlAPI import StlAPI_Writer -from OCC.TopAbs import (TopAbs_FACE, TopAbs_EDGE, TopAbs_WIRE, TopAbs_FORWARD, - TopAbs_SHELL) -from OCC.TopExp import (TopExp_Explorer, topexp) -from OCC.gp import (gp_Pnt, gp_XYZ) -from OCC.TColgp import (TColgp_Array1OfPnt, TColgp_Array2OfPnt) -from OCC.BRepOffsetAPI import BRepOffsetAPI_FindContigousEdges +from OCC.TColgp import TColgp_Array1OfPnt, TColgp_Array2OfPnt +from OCC.TopAbs import TopAbs_FACE, TopAbs_EDGE, TopAbs_WIRE +from OCC.TopAbs import TopAbs_FORWARD, TopAbs_SHELL +from OCC.TopExp import TopExp_Explorer, topexp +from OCC.TopoDS import topods_Face, TopoDS_Compound, topods_Shell +from OCC.TopoDS import topods_Edge, topods_Wire, topods, TopoDS_Shape from matplotlib import pyplot from mpl_toolkits import mplot3d from stl import mesh @@ -34,18 +40,19 @@ class NurbsHandler(fh.FileHandler): :cvar string infile: name of the input file to be processed. :cvar string outfile: name of the output file where to write in. - :cvar list control_point_position: index of the first NURBS control point (or pole) - of each face of the files. + :cvar list control_point_position: index of the first NURBS + control point (or pole) of each face of the files. :cvar TopoDS_Shape shape: shape meant for modification. - :cvar float tolerance: tolerance for the construction of the faces and wires - in the write function. Default value is 1e-6. + :cvar float tolerance: tolerance for the construction of the faces + and wires in the write function. Default value is 1e-6. .. warning:: - - For non trivial geometries it could be necessary to increase the tolerance. - Linking edges into a single wire and then trimming the surface with the wire - can be hard for the software, especially when the starting CAD has not been - made for analysis but for design purposes. + - For non trivial geometries it could be necessary to increase + the tolerance. Linking edges into a single wire and then + trimming the surface with the wire can be hard for the + software, especially when the starting CAD has not been made + for analysis but for design purposes. """ def __init__(self): @@ -57,14 +64,14 @@ def __init__(self): def _check_infile_instantiation(self): """ - This private method checks if `self.infile` and `self.shape' are instantiated. If not it means - that nobody called the parse method and at least one of them is None` If the check fails - it raises a RuntimeError. - + This private method checks if `self.infile` and `self.shape` are + instantiated. If not it means that nobody called the parse method + and at least one of them is None` If the check fails it raises a + RuntimeError. """ if not self.shape or not self.infile: raise RuntimeError( - "You can not write a file without having parsed one.") + 'You can not write a file without having parsed one.') def load_shape_from_file(self, filename): """ @@ -72,22 +79,23 @@ def load_shape_from_file(self, filename): Not implemented, it has to be implemented in subclasses. """ - raise NotImplementedError("Subclass must implement abstract method " +\ - self.__class__.__name__ + ".load_shape_from_file") + raise NotImplementedError('Subclass must implement abstract method ' + + self.__class__.__name__ + + '.load_shape_from_file') def parse(self, filename): """ - Method to parse the file `filename`. It returns a matrix with all the coordinates. + Method to parse the file `filename`. It returns a matrix with all + the coordinates. :param string filename: name of the input file. - :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of - the points of the mesh + :return: mesh_points: it is a `n_points`-by-3 matrix containing + the coordinates of the points of the mesh :rtype: numpy.ndarray """ self.infile = filename - self.shape = self.load_shape_from_file(filename) # cycle on the faces to get the control points @@ -99,11 +107,11 @@ def parse(self, filename): while faces_explorer.More(): # performing some conversions to get the right format (BSplineSurface) - face = OCC.TopoDS.topods_Face(faces_explorer.Current()) + face = topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() - brep_face = BRep_Tool.Surface(OCC.TopoDS.topods_Face(nurbs_face)) + brep_face = BRep_Tool.Surface(topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) # openCascade object @@ -112,24 +120,26 @@ def parse(self, filename): # extract the Control Points of each face n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() - control_polygon_coordinates = np.zeros(\ + 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 range(n_poles_u): for pole_v_direction in range(n_poles_v): - control_point_coordinates = occ_face.Pole(\ + control_point_coordinates = occ_face.Pole( pole_u_direction + 1, pole_v_direction + 1) - control_polygon_coordinates[i, :] = [control_point_coordinates.X(),\ - control_point_coordinates.Y(),\ - control_point_coordinates.Z()] + 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) + control_point_position.append(control_point_position[-1] + n_poles_u + * n_poles_v) n_faces += 1 faces_explorer.Next() @@ -138,15 +148,16 @@ def parse(self, 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. + 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 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`. + :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) @@ -164,17 +175,17 @@ def write(self, mesh_points, filename, tolerance=None): control_point_position = self._control_point_position compound_builder = BRep_Builder() - compound = OCC.TopoDS.TopoDS_Compound() + compound = TopoDS_Compound() compound_builder.MakeCompound(compound) while faces_explorer.More(): # similar to the parser method - face = OCC.TopoDS.topods_Face(faces_explorer.Current()) + face = 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)) + 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() @@ -203,11 +214,11 @@ def write(self, mesh_points, filename, tolerance=None): # 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 = 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_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) @@ -280,16 +291,16 @@ def parse_face(topo_face): face_exp_wire = TopExp_Explorer(topo_face, TopAbs_WIRE) # loop on wires per face while face_exp_wire.More(): - twire = OCC.TopoDS.topods_Wire(face_exp_wire.Current()) + twire = topods_Wire(face_exp_wire.Current()) wire_exp_edge = TopExp_Explorer(twire, TopAbs_EDGE) # loop on edges per wire while wire_exp_edge.More(): - edge = OCC.TopoDS.topods_Edge(wire_exp_edge.Current()) + edge = topods_Edge(wire_exp_edge.Current()) bspline_converter = BRepBuilderAPI_NurbsConvert(edge) bspline_converter.Perform(edge) bspline_tshape_edge = bspline_converter.Shape() - h_geom_edge, a, b = BRep_Tool_Curve( - OCC.TopoDS.topods_Edge(bspline_tshape_edge)) + h_geom_edge = BRep_Tool_Curve(topods_Edge(bspline_tshape_edge))[ + 0] h_bspline_edge = geomconvert_CurveToBSplineCurve(h_geom_edge) bspline_geom_edge = h_bspline_edge.GetObject() @@ -303,9 +314,7 @@ def parse_face(topo_face): for i in range(1, nb_poles + 1): ctrlpt = edge_ctrlpts.Value(i) ctrlpt_position = np.array( - [[ctrlpt.Coord(1), - ctrlpt.Coord(2), - ctrlpt.Coord(3)]]) + [[ctrlpt.Coord(1), ctrlpt.Coord(2), ctrlpt.Coord(3)]]) points_single_edge = np.append( points_single_edge, ctrlpt_position, axis=0) @@ -320,7 +329,7 @@ def parse_face(topo_face): nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_face) nurbs_converter.Perform(topo_face) nurbs_face = nurbs_converter.Shape() - h_geomsurface = BRep_Tool.Surface(OCC.TopoDS.topods.Face(nurbs_face)) + h_geomsurface = BRep_Tool.Surface(topods.Face(nurbs_face)) h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface) bsurface = h_bsurface.GetObject() @@ -333,10 +342,8 @@ def parse_face(topo_face): for indice_u_direction in range(1, nb_u + 1): for indice_v_direction in range(1, nb_v + 1): ctrlpt = ctrlpts.Value(indice_u_direction, indice_v_direction) - ctrlpt_position = np.array( - [[ctrlpt.Coord(1), - ctrlpt.Coord(2), - ctrlpt.Coord(3)]]) + ctrlpt_position = np.array([[ctrlpt.Coord(1), ctrlpt.Coord(2), + ctrlpt.Coord(3)]]) mesh_points_face = np.append( mesh_points_face, ctrlpt_position, axis=0) @@ -373,14 +380,13 @@ def parse_shape(self, filename): # cycle on shells while shells_explorer.More(): - topo_shell = OCC.TopoDS.topods.Shell(shells_explorer.Current()) + topo_shell = topods.Shell(shells_explorer.Current()) shell_faces_explorer = TopExp_Explorer(topo_shell, TopAbs_FACE) l_faces = [] # an empty list of faces per shell # cycle on faces while shell_faces_explorer.More(): - topo_face = OCC.TopoDS.topods.Face( - shell_faces_explorer.Current()) + topo_face = topods.Face(shell_faces_explorer.Current()) mesh_point, edge_point = self.parse_face(topo_face) l_faces.append((mesh_point, edge_point)) shell_faces_explorer.Next() @@ -395,8 +401,7 @@ def parse_shape(self, filename): l_faces = [] # an empty list of faces per shell while shell_faces_explorer.More(): - topo_face = OCC.TopoDS.topods.Face( - shell_faces_explorer.Current()) + topo_face = topods.Face(shell_faces_explorer.Current()) mesh_point, edge_point = self.parse_face(topo_face) l_faces.append((mesh_point, edge_point)) shell_faces_explorer.Next() @@ -422,8 +427,8 @@ def write_edge(points_edge, topo_edge): nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_edge) nurbs_converter.Perform(topo_edge) nurbs_curve = nurbs_converter.Shape() - topo_curve = OCC.TopoDS.topods_Edge(nurbs_curve) - h_geomcurve, param_min, param_max = BRep_Tool.Curve(topo_curve) + topo_curve = topods_Edge(nurbs_curve) + h_geomcurve = BRep_Tool.Curve(topo_curve)[0] h_bcurve = geomconvert_CurveToBSplineCurve(h_geomcurve) bspline_edge_curve = h_bcurve.GetObject() @@ -462,7 +467,7 @@ def write_face(self, points_face, list_points_edge, topo_face, toledge): nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_face) nurbs_converter.Perform(topo_face) nurbs_face = nurbs_converter.Shape() - topo_nurbsface = OCC.TopoDS.topods.Face(nurbs_face) + topo_nurbsface = topods.Face(nurbs_face) h_geomsurface = BRep_Tool.Surface(topo_nurbsface) h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface) bsurface = h_bsurface.GetObject() @@ -484,7 +489,7 @@ def write_face(self, points_face, list_points_edge, topo_face, toledge): # create modified new face new_bspline_tface = BRepBuilderAPI_MakeFace() - toler = OCC.Precision.precision_Confusion() + toler = precision_Confusion() new_bspline_tface.Init(bsurface.GetHandle(), False, toler) # cycle on the wires @@ -494,7 +499,7 @@ def write_face(self, points_face, list_points_edge, topo_face, toledge): while face_wires_explorer.More(): # get old wire - twire = OCC.TopoDS.topods_Wire(face_wires_explorer.Current()) + twire = topods_Wire(face_wires_explorer.Current()) # cycle on the edges ind_edge = 0 @@ -509,7 +514,7 @@ def write_face(self, points_face, list_points_edge, topo_face, toledge): deformed_edges = [] # cycle on the edges while wire_explorer_edge.More(): - tedge = OCC.TopoDS.topods_Edge(wire_explorer_edge.Current()) + tedge = topods_Edge(wire_explorer_edge.Current()) new_bspline_tedge = self.write_edge( list_points_edge[ind_edge_total], tedge) @@ -543,8 +548,8 @@ def write_face(self, points_face, list_points_edge, topo_face, toledge): stol.SetTolerance(new_edge_toadd, toledge * 10.0) new_bspline_twire.Add(new_edge_toadd) else: - deformed_edge_revers = deformed_edges[ - np.abs(deformed_edge_i) - 1] + deformed_edge_revers = deformed_edges[np.abs( + deformed_edge_i) - 1] stol.SetTolerance(deformed_edge_revers, toledge) new_bspline_twire.Add(deformed_edge_revers) if new_bspline_twire.Error() != 0: @@ -554,7 +559,7 @@ def write_face(self, points_face, list_points_edge, topo_face, toledge): new_bspline_tface.Add(new_bspline_twire.Wire()) face_wires_explorer.Next() - return OCC.TopoDS.topods.Face(new_bspline_tface.Face()) + return topods.Face(new_bspline_tface.Face()) @staticmethod def combine_faces(compshape, sew_tolerance): @@ -572,7 +577,7 @@ def combine_faces(compshape, sew_tolerance): n_faces = 0 # cycle on Faces while face_explorers.More(): - tface = OCC.TopoDS.topods.Face(face_explorers.Current()) + tface = topods.Face(face_explorers.Current()) sew.Add(tface) offsew.Add(tface) n_faces += 1 @@ -584,7 +589,7 @@ def combine_faces(compshape, sew_tolerance): shell = sew.SewedShape() sew.Dump() - shell = OCC.TopoDS.topods.Shell(shell) + shell = topods.Shell(shell) shell_fixer = ShapeFix_Shell() shell_fixer.FixFaceOrientation(shell) @@ -595,7 +600,7 @@ def combine_faces(compshape, sew_tolerance): new_shell = shell_fixer.Shell() - if OCC.BRepAlgo.brepalgo_IsValid(new_shell): + if brepalgo_IsValid(new_shell): print "Shell valid! " else: print "Shell failed! " @@ -617,7 +622,7 @@ def write_shape(self, l_shells, filename, tol): self.outfile = filename # global compound containing multiple shells global_compound_builder = BRep_Builder() - global_comp = OCC.TopoDS.TopoDS_Compound() + global_comp = TopoDS_Compound() global_compound_builder.MakeCompound(global_comp) if self.check_topo == 0: @@ -627,11 +632,10 @@ def write_shape(self, l_shells, filename, tol): ishell = 0 while shape_shells_explorer.More(): - per_shell = OCC.TopoDS.topods_Shell( - shape_shells_explorer.Current()) + per_shell = topods_Shell(shape_shells_explorer.Current()) # a local compound containing a shell compound_builder = BRep_Builder() - comp = OCC.TopoDS.TopoDS_Compound() + comp = TopoDS_Compound() compound_builder.MakeCompound(comp) # cycle on faces @@ -639,7 +643,7 @@ def write_shape(self, l_shells, filename, tol): per_shell.Oriented(TopAbs_FORWARD), TopAbs_FACE) iface = 0 while faces_explorer.More(): - topoface = OCC.TopoDS.topods.Face(faces_explorer.Current()) + topoface = topods.Face(faces_explorer.Current()) newface = self.write_face(l_shells[ishell][iface][0], l_shells[ishell][iface][1], topoface, tol) @@ -650,7 +654,7 @@ def write_shape(self, l_shells, filename, tol): faces_explorer.Next() new_shell = self.combine_faces(comp, 0.01) - itype = OCC.TopoDS.TopoDS_Shape.ShapeType(new_shell) + itype = TopoDS_Shape.ShapeType(new_shell) # add the new shell to the global compound global_compound_builder.Add(global_comp, new_shell) @@ -664,7 +668,7 @@ def write_shape(self, l_shells, filename, tol): # cycle on faces # a local compound containing a shell compound_builder = BRep_Builder() - comp = OCC.TopoDS.TopoDS_Compound() + comp = TopoDS_Compound() compound_builder.MakeCompound(comp) # cycle on faces @@ -672,7 +676,7 @@ def write_shape(self, l_shells, filename, tol): self.shape.Oriented(TopAbs_FORWARD), TopAbs_FACE) iface = 0 while faces_explorer.More(): - topoface = OCC.TopoDS.topods.Face(faces_explorer.Current()) + topoface = topods.Face(faces_explorer.Current()) newface = self.write_face(l_shells[0][iface][0], l_shells[0][iface][1], topoface, tol) @@ -682,7 +686,7 @@ def write_shape(self, l_shells, filename, tol): faces_explorer.Next() new_shell = self.combine_faces(comp, 0.01) - itype = OCC.TopoDS.TopoDS_Shape.ShapeType(new_shell) + itype = TopoDS_Shape.ShapeType(new_shell) # add the new shell to the global compound global_compound_builder.Add(global_comp, new_shell) @@ -703,13 +707,15 @@ def write_shape_to_file(self, shape, filename): def plot(self, plot_file=None, save_fig=False): """ - Method to plot a file. If `plot_file` is not given it plots `self.shape`. + Method to plot a file. If `plot_file` is not given it plots + `self.shape`. :param string plot_file: the 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. + :param bool save_fig: a flag to save the figure in png or not. + If True the plot is not shown. - :return: figure: matlplotlib structure for the figure of the chosen geometry + :return: figure: matlplotlib structure for the figure of the + chosen geometry :rtype: matplotlib.pyplot.figure """ if plot_file is None: @@ -764,7 +770,8 @@ def plot(self, plot_file=None, save_fig=False): def show(self, show_file=None): """ - Method to show a file. If `show_file` is not given it plots `self.shape`. + Method to show a file. If `show_file` is not given it plots + `self.shape`. :param string show_file: the filename you want to show. """ diff --git a/pygem/params/ffdparams.py b/pygem/params/ffdparams.py index 03094f4..0c43b18 100644 --- a/pygem/params/ffdparams.py +++ b/pygem/params/ffdparams.py @@ -123,8 +123,8 @@ def position_vertices(self): :rtype: numpy.ndarray """ return self.origin_box + np.vstack([ - np.zeros((1, 3)), - self.rotation_matrix.dot(np.diag(self.lenght_box)).T + np.zeros( + (1, 3)), self.rotation_matrix.dot(np.diag(self.lenght_box)).T ]) def read_parameters(self, filename='parameters.prm'): @@ -203,15 +203,16 @@ def write_parameters(self, filename='parameters.prm'): output_string += ' points in each direction (x, y, z).\n' output_string += '# For example, to create a 2 x 3 x 2 grid, use the' output_string += ' following: n control points: 2, 3, 2\n' - output_string += 'n control points x: ' + str( - self.n_control_points[0]) + '\n' - output_string += 'n control points y: ' + str( - self.n_control_points[1]) + '\n' - output_string += 'n control points z: ' + str( - self.n_control_points[2]) + '\n' + output_string += 'n control points x: ' + str(self.n_control_points[ + 0]) + '\n' + output_string += 'n control points y: ' + str(self.n_control_points[ + 1]) + '\n' + output_string += 'n control points z: ' + str(self.n_control_points[ + 2]) + '\n' output_string += '\n# box lenght indicates the length of the FFD ' - output_string += 'bounding box along the three canonical directions (x, y, z).\n' + output_string += 'bounding box along the three canonical directions ' + output_string += '(x, y, z).\n' output_string += '# It uses the local coordinate system.\n' output_string += '# For example to create a 2 x 1.5 x 3 meters box ' @@ -221,26 +222,32 @@ def write_parameters(self, filename='parameters.prm'): output_string += 'box lenght y: ' + str(self.lenght_box[1]) + '\n' output_string += 'box lenght z: ' + str(self.lenght_box[2]) + '\n' - output_string += '\n# box origin indicates the x, y, and z coordinates of ' - output_string += 'the origin of the FFD bounding box. That is center of\n' + output_string += '\n# box origin indicates the x, y, and z coordinates ' + output_string += 'of the origin of the FFD bounding box. That is ' + output_string += 'center of\n' output_string += '# rotation of the bounding box. It corresponds to ' output_string += 'the point coordinates with position [0][0][0].\n' - output_string += '# See section "Parameters weights" for more details.\n' - output_string += '# For example, if the origin is equal to 0., 0., 0., use ' - output_string += 'the following: origin box: 0., 0., 0.\n' + output_string += '# See section "Parameters weights" for more ' + output_string += 'details.\n' + output_string += '# For example, if the origin is equal to 0., 0., 0., ' + output_string += 'use the following: origin box: 0., 0., 0.\n' output_string += 'box origin x: ' + str(self.origin_box[0]) + '\n' output_string += 'box origin y: ' + str(self.origin_box[1]) + '\n' output_string += 'box origin z: ' + str(self.origin_box[2]) + '\n' output_string += '\n# rotation angle indicates the rotation angle ' - output_string += 'around the x, y, and z axis of the FFD bounding box in degrees.\n' + output_string += 'around the x, y, and z axis of the FFD bounding box ' + output_string += 'in degrees.\n' - output_string += '# The rotation is done with respect to the box origin.\n' - output_string += '# For example, to rotate the box by 2 deg along the z ' - output_string += 'direction, use the following: rotation angle: 0., 0., 2.\n' + output_string += '# The rotation is done with respect to the box ' + output_string += 'origin.\n' + output_string += '# For example, to rotate the box by 2 deg along ' + output_string += 'the z ' + output_string += 'direction, use the following: rotation angle: ' + output_string += '0., 0., 2.\n' output_string += 'rotation angle x: ' + str(self.rot_angle[0]) + '\n' output_string += 'rotation angle y: ' + str(self.rot_angle[1]) + '\n' @@ -254,8 +261,8 @@ def write_parameters(self, filename='parameters.prm'): output_string += '# For example with a 2x2x2 grid of control points we ' output_string += 'have to fill a 2x2x2 matrix of weights.\n' - output_string += '# If a weight is equal to zero you can discard the line ' - output_string += 'since the default is zero.\n' + output_string += '# If a weight is equal to zero you can discard the ' + output_string += 'line since the default is zero.\n' output_string += '#\n' output_string += '# | x index | y index | z index | weight |\n' @@ -275,8 +282,8 @@ def write_parameters(self, filename='parameters.prm'): for j in range(0, self.n_control_points[1]): for k in range(0, self.n_control_points[2]): output_string += offset * ' ' + str(i) + ' ' + str( - j) + ' ' + str(k) + ' ' + str( - self.array_mu_x[i][j][k]) + '\n' + j) + ' ' + str(k) + ' ' + str(self.array_mu_x[i][j][ + k]) + '\n' offset = 13 output_string += '\n# parameter y collects the displacements along y, ' @@ -288,8 +295,8 @@ def write_parameters(self, filename='parameters.prm'): for j in range(0, self.n_control_points[1]): for k in range(0, self.n_control_points[2]): output_string += offset * ' ' + str(i) + ' ' + str( - j) + ' ' + str(k) + ' ' + str( - self.array_mu_y[i][j][k]) + '\n' + j) + ' ' + str(k) + ' ' + str(self.array_mu_y[i][j][ + k]) + '\n' offset = 13 output_string += '\n# parameter z collects the displacements along z, ' @@ -301,8 +308,8 @@ def write_parameters(self, filename='parameters.prm'): for j in range(0, self.n_control_points[1]): for k in range(0, self.n_control_points[2]): output_string += offset * ' ' + str(i) + ' ' + str( - j) + ' ' + str(k) + ' ' + str( - self.array_mu_z[i][j][k]) + '\n' + j) + ' ' + str(k) + ' ' + str(self.array_mu_z[i][j][ + k]) + '\n' offset = 13 with open(filename, 'w') as f: @@ -352,29 +359,28 @@ def save(self, filename, write_deformed=True): y = np.linspace(0, self.lenght_box[1], self.n_control_points[1]) z = np.linspace(0, self.lenght_box[2], self.n_control_points[2]) - lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid( - y, x, z) + lattice_y_coords, lattice_x_coords, lattice_z_coords = np.meshgrid(y, x, + z) if write_deformed: box_points = np.array([ - lattice_x_coords.ravel() + - self.array_mu_x.ravel() * self.lenght_box[0], - lattice_y_coords.ravel() + + lattice_x_coords.ravel() + self.array_mu_x.ravel() * + self.lenght_box[0], lattice_y_coords.ravel() + self.array_mu_y.ravel() * self.lenght_box[1], - lattice_z_coords.ravel() + - self.array_mu_z.ravel() * self.lenght_box[2] + lattice_z_coords.ravel() + self.array_mu_z.ravel() * + self.lenght_box[2] ]) else: box_points = np.array([ - lattice_x_coords.ravel(), - lattice_y_coords.ravel(), + lattice_x_coords.ravel(), lattice_y_coords.ravel(), lattice_z_coords.ravel() ]) n_rows = box_points.shape[1] - box_points = np.dot(self.rotation_matrix, box_points) + np.transpose( - np.tile(self.origin_box, (n_rows, 1))) + box_points = np.dot( + self.rotation_matrix, + box_points) + np.transpose(np.tile(self.origin_box, (n_rows, 1))) points = vtk.vtkPoints() @@ -386,10 +392,7 @@ def save(self, filename, write_deformed=True): writer = vtk.vtkPolyDataWriter() writer.SetFileName(filename) - if vtk.VTK_MAJOR_VERSION <= 5: - writer.SetInput(data) - else: - writer.SetInputData(data) + writer.SetInputData(data) writer.Write() def build_bounding_box(self, diff --git a/pygem/params/rbfparams.py b/pygem/params/rbfparams.py index 385985e..7267e70 100644 --- a/pygem/params/rbfparams.py +++ b/pygem/params/rbfparams.py @@ -88,9 +88,7 @@ def read_parameters(self, filename='parameters_rbf.prm'): for line, i in zip(lines, list(range(0, self.n_control_points))): values = line.split() self.original_control_points[i] = np.array( - [float(values[0]), - float(values[1]), - float(values[2])]) + [float(values[0]), float(values[1]), float(values[2])]) mod_points = config.get('Control points', 'deformed control points') lines = mod_points.split('\n') @@ -105,9 +103,7 @@ def read_parameters(self, filename='parameters_rbf.prm'): for line, i in zip(lines, list(range(0, self.n_control_points))): values = line.split() self.deformed_control_points[i] = np.array( - [float(values[0]), - float(values[1]), - float(values[2])]) + [float(values[0]), float(values[1]), float(values[2])]) def write_parameters(self, filename='parameters_rbf.prm'): """ @@ -126,21 +122,17 @@ def write_parameters(self, filename='parameters_rbf.prm'): '# This section describes the radial basis functions shape.\n') output_file.write( - '\n# basis funtion is the name of the basis functions to use in the transformation. The functions\n' - ) + '\n# basis funtion is the name of the basis functions to use in the transformation. The functions\n') output_file.write( - '# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,\n' - ) + '# implemented so far are: gaussian_spline, multi_quadratic_biharmonic_spline,\n') output_file.write( - '# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis, polyharmonic_spline.\n' - ) + '# inv_multi_quadratic_biharmonic_spline, thin_plate_spline, beckert_wendland_c2_basis, polyharmonic_spline.\n') output_file.write( '# For a comprehensive list with details see the class RBF.\n') output_file.write('basis function: ' + str(self.basis) + '\n') output_file.write( - '\n# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation\n' - ) + '\n# radius is the scaling parameter r that affects the shape of the basis functions. See the documentation\n') output_file.write('# of the class RBF for details.\n') output_file.write('radius: ' + str(self.radius) + '\n') output_file.write( @@ -153,27 +145,25 @@ def write_parameters(self, filename='parameters_rbf.prm'): '# This section describes the RBF control points.\n') output_file.write( - '\n# original control points collects the coordinates of the interpolation control points before the deformation.\n' - ) + '\n# original control points collects the coordinates of the interpolation control points before the deformation.\n') output_file.write('original control points:') offset = 1 for i in range(0, self.n_control_points): - output_file.write( - offset * ' ' + str(self.original_control_points[i][0]) + - ' ' + str(self.original_control_points[i][1]) + ' ' + - str(self.original_control_points[i][2]) + '\n') + output_file.write(offset * ' ' + str( + self.original_control_points[i][0]) + ' ' + str( + self.original_control_points[i][1]) + ' ' + str( + self.original_control_points[i][2]) + '\n') offset = 25 output_file.write( - '\n# deformed control points collects the coordinates of the interpolation control points after the deformation.\n' - ) + '\n# deformed control points collects the coordinates of the interpolation control points after the deformation.\n') output_file.write('deformed control points:') offset = 1 for i in range(0, self.n_control_points): - output_file.write( - offset * ' ' + str(self.deformed_control_points[i][0]) + - ' ' + str(self.deformed_control_points[i][1]) + ' ' + - str(self.deformed_control_points[i][2]) + '\n') + output_file.write(offset * ' ' + str( + self.deformed_control_points[i][0]) + ' ' + str( + self.deformed_control_points[i][1]) + ' ' + str( + self.deformed_control_points[i][2]) + '\n') offset = 25 def __str__(self): diff --git a/pygem/radial.py b/pygem/radial.py index f3d1075..94b0e33 100644 --- a/pygem/radial.py +++ b/pygem/radial.py @@ -16,7 +16,7 @@ Rozza, Efficient geometrical parametrization techniques of interfaces for reduced order modelling: application to fluid-structure interaction coupling problems, International Journal of Computational Fluid Dynamics. - + RBF shape parametrization technique is based on the definition of a map, :math:`\\mathcal{M}(\\boldsymbol{x}) : \\mathbb{R}^n \\rightarrow \\mathbb{R}^n`, that allows the possibility of transferring data across @@ -87,7 +87,8 @@ class RBF(object): >>> import pygem.params as rbfp >>> import numpy as np >>> rbf_parameters = rbfp.RBFParameters() - >>> rbf_parameters.read_parameters('tests/test_datasets/parameters_rbf_cube.prm') + >>> fname = 'tests/test_datasets/parameters_rbf_cube.prm' + >>> rbf_parameters.read_parameters(fname) >>> nx, ny, nz = (20, 20, 20) >>> mesh = np.zeros((nx * ny * nz, 3)) >>> xv = np.linspace(0, 1, nx) @@ -107,18 +108,14 @@ def __init__(self, rbf_parameters, original_mesh_points): self.modified_mesh_points = None self.bases = { - 'gaussian_spline': - self.gaussian_spline, + 'gaussian_spline': self.gaussian_spline, 'multi_quadratic_biharmonic_spline': self.multi_quadratic_biharmonic_spline, 'inv_multi_quadratic_biharmonic_spline': self.inv_multi_quadratic_biharmonic_spline, - 'thin_plate_spline': - self.thin_plate_spline, - 'beckert_wendland_c2_basis': - self.beckert_wendland_c2_basis, - 'polyharmonic_spline': - self.polyharmonic_spline + 'thin_plate_spline': self.thin_plate_spline, + 'beckert_wendland_c2_basis': self.beckert_wendland_c2_basis, + 'polyharmonic_spline': self.polyharmonic_spline } # to make the str callable we have to use a dictionary with all the @@ -141,7 +138,7 @@ def gaussian_spline(X, r): It implements the following formula: .. math:: - \\varphi(\\| \\boldsymbol{x} \\|) = + \\varphi(\\| \\boldsymbol{x} \\|) = e^{-\\frac{\\| \\boldsymbol{x} \\|^2}{r^2}} :param numpy.ndarray X: the vector x in the formula above. @@ -270,15 +267,16 @@ def polyharmonic_spline(self, X, r): k = self.parameters.power r_sc = np.linalg.norm(X) / r - power = np.power - if k & 1: return power(r_sc, k) # k odd + # k odd + if k & 1: + return np.power(r_sc, k) - # Here, k is even + # k even if r_sc < 1: - return power(r_sc, k - 1) * np.log(power(r_sc, r_sc)) + return np.power(r_sc, k - 1) * np.log(np.power(r_sc, r_sc)) else: - return power(r_sc, k) * np.log(r_sc) + return np.power(r_sc, k) * np.log(r_sc) def _distance_matrix(self, X1, X2): """ @@ -317,12 +315,9 @@ def _get_weights(self, X, Y): dim = X.shape[1] identity = np.ones((n_points, 1)) dist = self._distance_matrix(X, X) - H = np.bmat([[dist, identity, - X], [identity.T, - np.zeros((1, 1)), - np.zeros((1, dim))], - [X.T, np.zeros((dim, 1)), - np.zeros((dim, dim))]]) + H = np.bmat([[dist, identity, X], [identity.T, np.zeros( + (1, 1)), np.zeros((1, dim))], [X.T, np.zeros((dim, 1)), np.zeros( + (dim, dim))]]) rhs = np.bmat([[Y], [np.zeros((1, dim))], [np.zeros((dim, dim))]]) weights = np.linalg.solve(H, rhs) return weights diff --git a/pygem/stephandler.py b/pygem/stephandler.py index 2424eda..2f9f89e 100644 --- a/pygem/stephandler.py +++ b/pygem/stephandler.py @@ -1,9 +1,10 @@ """ Derived module from nurbshandler.py to handle step and stp files. """ -from OCC.Interface import Interface_Static_SetCVal -from OCC.STEPControl import STEPControl_Writer, STEPControl_Reader, STEPControl_AsIs from OCC.IFSelect import IFSelect_RetDone +from OCC.Interface import Interface_Static_SetCVal +from OCC.STEPControl import STEPControl_Writer, STEPControl_Reader +from OCC.STEPControl import STEPControl_AsIs from pygem.nurbshandler import NurbsHandler @@ -15,18 +16,19 @@ class StepHandler(NurbsHandler): :cvar string outfile: name of the output file where to write in. :cvar list extensions: list of extensions of the input/output files. It is equal to ['.step', '.stp']. - :cvar list control_point_position: index of the first NURBS control point (or pole) - of each face of the iges file. + :cvar list control_point_position: index of the first NURBS control + point (or pole) of each face of the iges file. :cvar float tolerance: tolerance for the construction of the faces and wires in the write function. Default value is 1e-6. :cvar TopoDS_Shape shape: shape meant for modification. .. warning:: - - For non trivial geometries it could be necessary to increase the tolerance. - Linking edges into a single wire and then trimming the surface with the wire - can be hard for the software, especially when the starting CAD has not been - made for analysis but for design purposes. + - For non trivial geometries it could be necessary to increase the + tolerance. Linking edges into a single wire and then trimming the + surface with the wire can be hard for the software, especially when + the starting CAD has not been made for analysis but for design + purposes. """ def __init__(self): diff --git a/pygem/stlhandler.py b/pygem/stlhandler.py index 8d1ca97..f574300 100644 --- a/pygem/stlhandler.py +++ b/pygem/stlhandler.py @@ -137,14 +137,10 @@ def plot(self, plot_file=None, save_fig=False): axes.add_collection3d(tri) ## Get the limits of the axis and center the geometry - max_dim = np.array( - [np.max(vtx[:, :, 0]), - np.max(vtx[:, :, 1]), - np.max(vtx[:, :, 2])]) - min_dim = np.array( - [np.min(vtx[:, :, 0]), - np.min(vtx[:, :, 1]), - np.min(vtx[:, :, 2])]) + max_dim = np.array([np.max(vtx[:, :, 0]), np.max(vtx[:, :, 1]), + np.max(vtx[:, :, 2])]) + min_dim = np.array([np.min(vtx[:, :, 0]), np.min(vtx[:, :, 1]), + np.min(vtx[:, :, 2])]) max_lenght = np.max(max_dim - min_dim) axes.set_xlim(-.6 * max_lenght + (max_dim[0] + min_dim[0]) / 2, diff --git a/pygem/utils.py b/pygem/utils.py index 46bea79..ec55781 100644 --- a/pygem/utils.py +++ b/pygem/utils.py @@ -26,7 +26,8 @@ def write_bounding_box(parameters, outfile, write_deformed=True): >>> import numpy as np >>> >>> params = pars.FFDParameters() - >>> params.read_parameters(filename='tests/test_datasets/parameters_test_ffd_sphere.prm') + >>> fname = 'tests/test_datasets/parameters_test_ffd_sphere.prm' + >>> params.read_parameters(filename=fname) >>> ut.write_bounding_box(params, 'tests/test_datasets/box_test_sphere.vtk') """ aux_x = np.linspace(0, parameters.lenght_box[0], @@ -40,27 +41,27 @@ def write_bounding_box(parameters, outfile, write_deformed=True): if write_deformed: box_points = np.array([ - lattice_x_coords.ravel() + - parameters.array_mu_x.ravel() * parameters.lenght_box[0], - lattice_y_coords.ravel() + + lattice_x_coords.ravel() + parameters.array_mu_x.ravel() * + parameters.lenght_box[0], lattice_y_coords.ravel() + parameters.array_mu_y.ravel() * parameters.lenght_box[1], - lattice_z_coords.ravel() + - parameters.array_mu_z.ravel() * parameters.lenght_box[2] + lattice_z_coords.ravel() + parameters.array_mu_z.ravel() * + parameters.lenght_box[2] ]) else: box_points = np.array([ - lattice_x_coords.ravel(), - lattice_y_coords.ravel(), + lattice_x_coords.ravel(), lattice_y_coords.ravel(), lattice_z_coords.ravel() ]) n_rows = box_points.shape[1] - box_points = np.dot(parameters.rotation_matrix, box_points) + np.transpose( - np.tile(parameters.origin_box, (n_rows, 1))) + box_points = np.dot( + parameters.rotation_matrix, + box_points) + np.transpose(np.tile(parameters.origin_box, (n_rows, 1))) - # step necessary to set the correct order to the box points for vtkStructuredGrid: - # Data in vtkStructuredGrid are ordered with x increasing fastest, then y, then z + # step necessary to set the correct order to the box points for + # vtkStructuredGrid. Data in vtkStructuredGrid are ordered with + # x increasing fastest, then y, then z dims = lattice_y_coords.shape aux_xx = box_points[0, :].reshape(dims).ravel(order='f') aux_yy = box_points[1, :].reshape(dims).ravel(order='f') @@ -73,15 +74,16 @@ def write_bounding_box(parameters, outfile, write_deformed=True): def _write_vtk_box(box_points, filename, dimensions): """ Private method that writes a vtk file containing FFD control points. - + :param numpy.ndarray box_points: coordinates of the FFD control points. :param string filename: name of the output file. :param list dimensions: dimension of the lattice in (x, y, z) directions. - + .. warning:: - If you want to visualize in paraview the inner points, - you have to slice the lattice because paraview does not visualize them automatically - even in the wireframe visualization. + + If you want to visualize in paraview the inner points, + you have to slice the lattice because paraview does not visualize them + automatically even in the wireframe visualization. """ # setup points and vertices points = vtk.vtkPoints() @@ -110,13 +112,14 @@ def _write_vtk_box(box_points, filename, dimensions): def plot_rbf_control_points(parameters, save_fig=False): """ - Method to plot the control points of a RBFParameters class. It is possible to save the - resulting figure. + Method to plot the control points of a RBFParameters class. It is possible + to save the resulting figure. - :param RBFParameters parameters: parameters of the Radial Basis Functions interpolation. + :param RBFParameters parameters: parameters of the Radial Basis Functions + interpolation. :param bool save_fig: a flag to save the figure in png or not. If True the - plot is not shown and the figure is saved with the name 'RBF_control_points.png'. - The default value is False. + plot is not shown and the figure is saved with the name + 'RBF_control_points.png'. The default value is False. """ fig = plt.figure(1) axes = fig.add_subplot(111, projection='3d') @@ -153,13 +156,16 @@ def plot_rbf_control_points(parameters, save_fig=False): def write_points_in_vtp(points, outfile='points.vtp', color=None): """ - Method that writes a vtp file containing the given points. It can be used for any set of - 3D points. Useful to visualize control points together with mesh points in the same window. + Method that writes a vtp file containing the given points. It can be + used for any set of 3D points. Useful to visualize control points together + with mesh points in the same window. - :param numpy.ndarray points: coordinates of the points. The shape has to be (n_points, 3). - :param string outfile: name of the output file. The extension has to be .vtp. Default is 'points.vtp'. - :param tuple color: tuple defining the RGB color to assign to all the points. Default is - blue: (0, 0, 255). + :param numpy.ndarray points: coordinates of the points. The shape has to + be (n_points, 3). + :param string outfile: name of the output file. The extension has to be + .vtp. Default is 'points.vtp'. + :param tuple color: tuple defining the RGB color to assign to all the + points. Default is blue: (0, 0, 255). :Example: @@ -167,7 +173,8 @@ def write_points_in_vtp(points, outfile='points.vtp', color=None): >>> import numpy as np >>> >>> ctrl_points = np.arange(9).reshape(3, 3) - >>> ut.write_points_in_vtp(ctrl_points, 'example_points.vtp', color=(255, 0, 0)) + >>> outfile = 'example_points.vtp' + >>> ut.write_points_in_vtp(ctrl_points, outfile, color=(255, 0, 0)) """ if color is None: color = (0, 0, 255) diff --git a/pygem/vtkhandler.py b/pygem/vtkhandler.py index fa27fa7..e048eea 100644 --- a/pygem/vtkhandler.py +++ b/pygem/vtkhandler.py @@ -14,7 +14,8 @@ class VtkHandler(fh.FileHandler): :cvar string infile: name of the input file to be processed. :cvar string outfile: name of the output file where to write in. - :cvar list extensions: extensions of the input/output files. It is equal to ['.vtk']. + :cvar list extensions: extensions of the input/output files. It + is equal to ['.vtk']. """ def __init__(self): @@ -23,12 +24,13 @@ def __init__(self): def parse(self, filename): """ - Method to parse the file `filename`. It returns a matrix with all the coordinates. + Method to parse the file `filename`. It returns a matrix + with all the coordinates. :param string filename: name of the input file. - :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of - the points of the mesh + :return: mesh_points: it is a `n_points`-by-3 matrix + containing the coordinates of the points of the mesh :rtype: numpy.ndarray .. todo:: @@ -58,12 +60,14 @@ def parse(self, filename): def write(self, mesh_points, filename): """ - Writes a vtk 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 vtk file. - - :param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix containing - the coordinates of the points of the mesh + Writes a vtk 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 vtk 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) @@ -80,7 +84,6 @@ def write(self, mesh_points, filename): data = reader.GetOutput() points = vtk.vtkPoints() - for i in range(data.GetNumberOfPoints()): points.InsertNextPoint(mesh_points[i, :]) @@ -88,23 +91,20 @@ def write(self, mesh_points, filename): writer = vtk.vtkDataSetWriter() writer.SetFileName(self.outfile) - - if vtk.VTK_MAJOR_VERSION <= 5: - writer.SetInput(data) - else: - writer.SetInputData(data) - + writer.SetInputData(data) writer.Write() def plot(self, plot_file=None, save_fig=False): """ - Method to plot a vtk file. If `plot_file` is not given it plots `self.infile`. + Method to plot a vtk file. If `plot_file` is not given it + plots `self.infile`. :param string plot_file: the vtk 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. + :param bool save_fig: a flag to save the figure in png or + not. If True the plot is not shown. - :return: figure: matlplotlib structure for the figure of the chosen geometry + :return: figure: matlplotlib structure for the figure of + the chosen geometry :rtype: matplotlib.pyplot.figure """ if plot_file is None: @@ -136,12 +136,10 @@ def plot(self, plot_file=None, save_fig=False): axes.add_collection3d(tri) ## Get the limits of the axis and center the geometry - max_dim = np.array([np.max(vtx[:,:,0]), \ - np.max(vtx[:,:,1]), \ - np.max(vtx[:,:,2])]) - min_dim = np.array([np.min(vtx[:,:,0]), \ - np.min(vtx[:,:,1]), \ - np.min(vtx[:,:,2])]) + max_dim = np.array([np.max(vtx[:, :, 0]), np.max(vtx[:, :, 1]), + np.max(vtx[:, :, 2])]) + min_dim = np.array([np.min(vtx[:, :, 0]), np.min(vtx[:, :, 1]), + np.min(vtx[:, :, 2])]) max_lenght = np.max(max_dim - min_dim) axes.set_xlim(-.6 * max_lenght + (max_dim[0] + min_dim[0]) / 2, @@ -161,7 +159,8 @@ def plot(self, plot_file=None, save_fig=False): def show(self, show_file=None): """ - Method to show a vtk file. If `show_file` is not given it shows `self.infile`. + Method to show a vtk file. If `show_file` is not given + it shows `self.infile`. :param string show_file: the vtk filename you want to show. """ diff --git a/tests/test_ffdparams.py b/tests/test_ffdparams.py index ee2e1f9..e69af53 100644 --- a/tests/test_ffdparams.py +++ b/tests/test_ffdparams.py @@ -33,18 +33,18 @@ def test_class_members_default_rot_angle(self): def test_class_members_default_array_mu_x(self): params = FFDParameters() - np.testing.assert_array_almost_equal(params.array_mu_x, - np.zeros((2, 2, 2))) + np.testing.assert_array_almost_equal(params.array_mu_x, np.zeros( + (2, 2, 2))) def test_class_members_default_array_mu_y(self): params = FFDParameters() - np.testing.assert_array_almost_equal(params.array_mu_y, - np.zeros((2, 2, 2))) + np.testing.assert_array_almost_equal(params.array_mu_y, np.zeros( + (2, 2, 2))) def test_class_members_default_array_mu_z(self): params = FFDParameters() - np.testing.assert_array_almost_equal(params.array_mu_z, - np.zeros((2, 2, 2))) + np.testing.assert_array_almost_equal(params.array_mu_z, np.zeros( + (2, 2, 2))) def test_class_members_default_psi_mapping(self): params = FFDParameters() @@ -73,18 +73,18 @@ def test_class_members_generic_n_control_points(self): def test_class_members_generic_array_mu_x(self): params = FFDParameters([2, 3, 5]) - np.testing.assert_array_almost_equal(params.array_mu_x, - np.zeros((2, 3, 5))) + np.testing.assert_array_almost_equal(params.array_mu_x, np.zeros( + (2, 3, 5))) def test_class_members_generic_array_mu_y(self): params = FFDParameters([2, 3, 5]) - np.testing.assert_array_almost_equal(params.array_mu_y, - np.zeros((2, 3, 5))) + np.testing.assert_array_almost_equal(params.array_mu_y, np.zeros( + (2, 3, 5))) def test_class_members_generic_array_mu_z(self): params = FFDParameters([2, 3, 5]) - np.testing.assert_array_almost_equal(params.array_mu_z, - np.zeros((2, 3, 5))) + np.testing.assert_array_almost_equal(params.array_mu_z, np.zeros( + (2, 3, 5))) def test_read_parameters_conversion_unit(self): params = FFDParameters(n_control_points=[3, 2, 2]) @@ -126,18 +126,16 @@ def test_read_parameters_array_mu_x(self): def test_read_parameters_array_mu_y(self): params = FFDParameters(n_control_points=[3, 2, 2]) params.read_parameters('tests/test_datasets/parameters_sphere.prm') - array_mu_y_exact = np.array( - [0., 0., 0.5555555555, 0., 0., 0., 0., 0., -1., 0., 0., - 0.]).reshape((3, 2, 2)) + array_mu_y_exact = np.array([0., 0., 0.5555555555, 0., 0., 0., 0., 0., + -1., 0., 0., 0.]).reshape((3, 2, 2)) np.testing.assert_array_almost_equal(params.array_mu_y, array_mu_y_exact) def test_read_parameters_array_mu_z(self): params = FFDParameters(n_control_points=[3, 2, 2]) params.read_parameters('tests/test_datasets/parameters_sphere.prm') - array_mu_z_exact = np.array( - [0., -0.2, 0., -0.45622985, 0., 0., 0., 0., -1.22, 0., -1., - 0.]).reshape((3, 2, 2)) + array_mu_z_exact = np.array([0., -0.2, 0., -0.45622985, 0., 0., 0., 0., + -1.22, 0., -1., 0.]).reshape((3, 2, 2)) np.testing.assert_array_almost_equal(params.array_mu_z, array_mu_z_exact)