Source code for pygem.stlhandler

"""
Derived module from filehandler.py to handle STereoLithography files.

.. warning::
    This module will be deprecated in next releases. Follow updates on
    https://github.com/mathLab for news about file handling. 
"""
import numpy as np
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as a3
import pygem.filehandler as fh
import vtk
import warnings
warnings.warn("This module will be deprecated in next releases", DeprecationWarning)


[docs]class StlHandler(fh.FileHandler): """ STereoLithography 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 list extensions: extensions of the input/output files. It is equal to ['.stl']. """ def __init__(self): super(StlHandler, self).__init__() self.extensions = ['.stl']
[docs] def parse(self, filename): """ Method to parse the `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 :rtype: numpy.ndarray """ self._check_filename_type(filename) self._check_extension(filename) self.infile = filename reader = vtk.vtkSTLReader() reader.SetFileName(self.infile) reader.Update() data = reader.GetOutput() n_points = data.GetNumberOfPoints() mesh_points = np.zeros([n_points, 3]) for i in range(n_points): mesh_points[i][0], mesh_points[i][1], mesh_points[i][ 2] = data.GetPoint(i) return mesh_points
[docs] def write(self, mesh_points, filename, write_bin=False): """ Writes a stl file, called filename, copying all the lines from self.filename but the coordinates. mesh_points is a matrix that contains the new coordinates to write in the stl 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. :param boolean write_bin: flag to write in the binary format. Default is False. """ self._check_filename_type(filename) self._check_extension(filename) self._check_infile_instantiation() self.outfile = filename reader = vtk.vtkSTLReader() reader.SetFileName(self.infile) reader.Update() data = reader.GetOutput() points = vtk.vtkPoints() for i in range(data.GetNumberOfPoints()): points.InsertNextPoint(mesh_points[i, :]) data.SetPoints(points) writer = vtk.vtkSTLWriter() writer.SetFileName(self.outfile) writer.SetInputData(data) if write_bin: writer.SetFileTypeToBinary() else: writer.SetFileTypeToASCII() writer.Write()
[docs] def plot(self, plot_file=None, save_fig=False): """ Method to plot an stl file. If `plot_file` is not given it plots `self.infile`. :param string plot_file: the stl 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. The default value is False. :return: figure: matlplotlib structure for the figure of the chosen geometry :rtype: matplotlib.pyplot.figure """ if plot_file is None: plot_file = self.infile else: self._check_filename_type(plot_file) # Read the source file. reader = vtk.vtkSTLReader() reader.SetFileName(plot_file) reader.Update() data = reader.GetOutput() points = data.GetPoints() ncells = data.GetNumberOfCells() # for each cell it contains the indeces of the points that define the cell figure = plt.figure() axes = a3.Axes3D(figure) vtx = np.zeros((ncells, 3, 3)) for i in range(0, ncells): for j in range(0, 3): cell = data.GetCell(i).GetPointId(j) vtx[i][j][0], vtx[i][j][1], vtx[i][j][2] = points.GetPoint( int(cell)) tri = a3.art3d.Poly3DCollection([vtx[i]]) tri.set_color('b') tri.set_edgecolor('k') 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_lenght = np.max(max_dim - min_dim) axes.set_xlim(-.6 * max_lenght + (max_dim[0] + min_dim[0]) / 2, .6 * max_lenght + (max_dim[0] + min_dim[0]) / 2) axes.set_ylim(-.6 * max_lenght + (max_dim[1] + min_dim[1]) / 2, .6 * max_lenght + (max_dim[1] + min_dim[1]) / 2) axes.set_zlim(-.6 * max_lenght + (max_dim[2] + min_dim[2]) / 2, .6 * max_lenght + (max_dim[2] + min_dim[2]) / 2) # Show the plot to the screen if not save_fig: plt.show() else: figure.savefig(plot_file.split('.')[0] + '.png') return figure
[docs] def show(self, show_file=None): """ 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. """ if show_file is None: show_file = self.infile else: self._check_filename_type(show_file) # Read the source file. reader = vtk.vtkSTLReader() reader.SetFileName(show_file) reader.Update() # Needed because of GetScalarRange output = reader.GetOutput() scalar_range = output.GetScalarRange() # Create the mapper that corresponds the objects of the vtk file # into graphics elements mapper = vtk.vtkDataSetMapper() mapper.SetInputData(output) mapper.SetScalarRange(scalar_range) # Create the Actor actor = vtk.vtkActor() actor.SetMapper(mapper) # Create the Renderer renderer = vtk.vtkRenderer() renderer.AddActor(actor) # Set background color (white is 1, 1, 1) renderer.SetBackground(20, 20, 20) # Create the RendererWindow renderer_window = vtk.vtkRenderWindow() renderer_window.AddRenderer(renderer) # Create the RendererWindowInteractor and display the vtk_file interactor = vtk.vtkRenderWindowInteractor() interactor.SetRenderWindow(renderer_window) interactor.Initialize() interactor.Start()