33"""
44import numpy as np
55from mpl_toolkits import mplot3d
6- from matplotlib import pyplot
7- from stl import mesh , Mode
6+ import matplotlib . pyplot as plt
7+ import mpl_toolkits . mplot3d as a3
88import pygem .filehandler as fh
9+ import vtk
910
1011
1112class StlHandler (fh .FileHandler ):
@@ -14,7 +15,8 @@ class StlHandler(fh.FileHandler):
1415
1516 :cvar string infile: name of the input file to be processed.
1617 :cvar string outfile: name of the output file where to write in.
17- :cvar list extensions: extensions of the input/output files. It is equal to ['.stl'].
18+ :cvar list extensions: extensions of the input/output files. It is equal to
19+ ['.stl'].
1820 """
1921
2022 def __init__ (self ):
@@ -24,94 +26,129 @@ def __init__(self):
2426
2527 def parse (self , filename ):
2628 """
27- Method to parse the `filename`. It returns a matrix with all the coordinates.
29+ Method to parse the `filename`. It returns a matrix with all the
30+ coordinates.
2831
2932 :param string filename: name of the input file.
3033
31- :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of
32- the points of the mesh
34+ :return: mesh_points: it is a `n_points`-by-3 matrix containing the
35+ coordinates of the points of the mesh
3336 :rtype: numpy.ndarray
34-
35- .. todo::
36-
37- - specify when it works
3837 """
3938 self ._check_filename_type (filename )
4039 self ._check_extension (filename )
4140
4241 self .infile = filename
4342
44- stl_mesh = mesh .Mesh .from_file (self .infile )
45- mesh_points = np .array (
46- [stl_mesh .x .ravel (), stl_mesh .y .ravel (), stl_mesh .z .ravel ()]
47- )
48- mesh_points = mesh_points .T
43+ reader = vtk .vtkSTLReader ()
44+ reader .SetFileName (self .infile )
45+ reader .Update ()
46+ data = reader .GetOutput ()
47+
48+ n_points = data .GetNumberOfPoints ()
49+ mesh_points = np .zeros ([n_points , 3 ])
50+
51+ for i in range (n_points ):
52+ mesh_points [i ][0 ], mesh_points [i ][1 ], mesh_points [i ][
53+ 2
54+ ] = data .GetPoint (i )
4955
5056 return mesh_points
5157
5258 def write (self , mesh_points , filename , write_bin = False ):
5359 """
54- Writes a stl file, called filename, copying all the lines from self.filename but
55- the coordinates. mesh_points is a matrix that contains the new coordinates to
56- write in the stl file.
60+ Writes a stl file, called filename, copying all the lines from
61+ self.filename but the coordinates. mesh_points is a matrix that contains
62+ the new coordinates to write in the stl file.
5763
58- :param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix containing
59- the coordinates of the points of the mesh.
64+ :param numpy.ndarray mesh_points: it is a `n_points`-by-3 matrix
65+ containing the coordinates of the points of the mesh.
6066 :param string filename: name of the output file.
61- :param boolean write_bin: flag to write in the binary format. Default is False.
67+ :param boolean write_bin: flag to write in the binary format. Default is
68+ False.
6269 """
6370 self ._check_filename_type (filename )
6471 self ._check_extension (filename )
6572 self ._check_infile_instantiation ()
6673
6774 self .outfile = filename
6875
69- n_vertices = mesh_points .shape [0 ]
70- # number of triplets of vertices
71- n_triplets = n_vertices // 3
72- data = np .zeros (n_triplets , dtype = mesh .Mesh .dtype )
73- stl_mesh = mesh .Mesh (data , remove_empty_areas = False )
76+ reader = vtk .vtkSTLReader ()
77+ reader .SetFileName (self .infile )
78+ reader .Update ()
79+ data = reader .GetOutput ()
7480
75- for i in range (0 , n_triplets ):
76- for j in range (0 , 3 ):
77- data ['vectors' ][i ][j ] = mesh_points [3 * i + j ]
81+ points = vtk .vtkPoints ()
82+
83+ for i in range (data .GetNumberOfPoints ()):
84+ points .InsertNextPoint (mesh_points [i , :])
85+
86+ data .SetPoints (points )
7887
79- if not write_bin :
80- stl_mesh .save (self .outfile , mode = Mode .ASCII , update_normals = True )
88+ writer = vtk .vtkSTLWriter ()
89+ writer .SetFileName (self .outfile )
90+
91+ if vtk .VTK_MAJOR_VERSION <= 5 :
92+ writer .SetInput (data )
8193 else :
82- stl_mesh .save (self .outfile , update_normals = True )
94+ writer .SetInputData (data )
95+
96+ if write_bin :
97+ writer .SetFileTypeToBinary ()
98+ else :
99+ writer .SetFileTypeToASCII ()
100+
101+ writer .Write ()
83102
84103 def plot (self , plot_file = None , save_fig = False ):
85104 """
86- Method to plot an stl file. If `plot_file` is not given it plots `self.infile`.
105+ Method to plot an stl file. If `plot_file` is not given it plots
106+ `self.infile`.
87107
88108 :param string plot_file: the stl filename you want to plot.
89- :param bool save_fig: a flag to save the figure in png or not. If True the
90- plot is not shown. The default value is False.
109+ :param bool save_fig: a flag to save the figure in png or not. If True
110+ the plot is not shown. The default value is False.
91111
92- :return: figure: matlplotlib structure for the figure of the chosen geometry
112+ :return: figure: matlplotlib structure for the figure of the chosen
113+ geometry
93114 :rtype: matplotlib.pyplot.figure
94115 """
95116 if plot_file is None :
96117 plot_file = self .infile
97118 else :
98119 self ._check_filename_type (plot_file )
99120
100- # Create a new plot
101- figure = pyplot .figure ()
102- axes = mplot3d .Axes3D (figure )
121+ # Read the source file.
122+ reader = vtk .vtkSTLReader ()
123+ reader .SetFileName (plot_file )
124+ reader .Update ()
103125
104- # Load the STL files and add the vectors to the plot
105- stl_mesh = mesh . Mesh . from_file ( plot_file )
106- axes . add_collection3d ( mplot3d . art3d . Poly3DCollection ( stl_mesh . vectors ) )
126+ data = reader . GetOutput ()
127+ points = data . GetPoints ( )
128+ ncells = data . GetNumberOfCells ( )
107129
108- # Get the limits of the axis and center the geometry
109- max_dim = np .array ([np .max (stl_mesh .vectors [:,:,0 ]), \
110- np .max (stl_mesh .vectors [:,:,1 ]), \
111- np .max (stl_mesh .vectors [:,:,2 ])])
112- min_dim = np .array ([np .min (stl_mesh .vectors [:,:,0 ]), \
113- np .min (stl_mesh .vectors [:,:,1 ]), \
114- np .min (stl_mesh .vectors [:,:,2 ])])
130+ # for each cell it contains the indeces of the points that define the cell
131+ figure = plt .figure ()
132+ axes = a3 .Axes3D (figure )
133+ vtx = np .zeros ((ncells , 3 , 3 ))
134+ for i in range (0 , ncells ):
135+ for j in range (0 , 3 ):
136+ cell = data .GetCell (i ).GetPointId (j )
137+ vtx [i ][j ][0 ], vtx [i ][j ][1 ], vtx [i ][j ][2 ] = points .GetPoint (
138+ int (cell )
139+ )
140+ tri = a3 .art3d .Poly3DCollection ([vtx [i ]])
141+ tri .set_color ('b' )
142+ tri .set_edgecolor ('k' )
143+ axes .add_collection3d (tri )
144+
145+ ## Get the limits of the axis and center the geometry
146+ max_dim = np .array ([np .max (vtx [:,:,0 ]), \
147+ np .max (vtx [:,:,1 ]), \
148+ np .max (vtx [:,:,2 ])])
149+ min_dim = np .array ([np .min (vtx [:,:,0 ]), \
150+ np .min (vtx [:,:,1 ]), \
151+ np .min (vtx [:,:,2 ])])
115152
116153 max_lenght = np .max (max_dim - min_dim )
117154 axes .set_xlim (
@@ -129,8 +166,56 @@ def plot(self, plot_file=None, save_fig=False):
129166
130167 # Show the plot to the screen
131168 if not save_fig :
132- pyplot .show ()
169+ plt .show ()
133170 else :
134171 figure .savefig (plot_file .split ('.' )[0 ] + '.png' )
135172
136173 return figure
174+
175+ def show (self , show_file = None ):
176+ """
177+ Method to show a vtk file. If `show_file` is not given it shows
178+ `self.infile`.
179+
180+ :param string show_file: the vtk filename you want to show.
181+ """
182+ if show_file is None :
183+ show_file = self .infile
184+ else :
185+ self ._check_filename_type (show_file )
186+
187+ # Read the source file.
188+ reader = vtk .vtkSTLReader ()
189+ reader .SetFileName (show_file )
190+ reader .Update () # Needed because of GetScalarRange
191+ output = reader .GetOutput ()
192+ scalar_range = output .GetScalarRange ()
193+
194+ # Create the mapper that corresponds the objects of the vtk file
195+ # into graphics elements
196+ mapper = vtk .vtkDataSetMapper ()
197+ if vtk .VTK_MAJOR_VERSION <= 5 :
198+ mapper .SetInput (output )
199+ else :
200+ mapper .SetInputData (output )
201+ mapper .SetScalarRange (scalar_range )
202+
203+ # Create the Actor
204+ actor = vtk .vtkActor ()
205+ actor .SetMapper (mapper )
206+
207+ # Create the Renderer
208+ renderer = vtk .vtkRenderer ()
209+ renderer .AddActor (actor )
210+ # Set background color (white is 1, 1, 1)
211+ renderer .SetBackground (20 , 20 , 20 )
212+
213+ # Create the RendererWindow
214+ renderer_window = vtk .vtkRenderWindow ()
215+ renderer_window .AddRenderer (renderer )
216+
217+ # Create the RendererWindowInteractor and display the vtk_file
218+ interactor = vtk .vtkRenderWindowInteractor ()
219+ interactor .SetRenderWindow (renderer_window )
220+ interactor .Initialize ()
221+ interactor .Start ()
0 commit comments