Skip to content

Commit

Permalink
Merge pull request #100 from akaszynski/readers
Browse files Browse the repository at this point in the history
Support all VTK readers
  • Loading branch information
banesullivan committed Feb 25, 2019
2 parents 41e384b + aa3ad09 commit db9ddb2
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 77 deletions.
2 changes: 1 addition & 1 deletion tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def test_plot_texture_associated():
plotter.plot()

@pytest.mark.skipif(not running_xserver(), reason="Requires X11")
def test_load_texture_from_numpy():
def test_read_texture_from_numpy():
""""Test adding a texture to a plot"""
globe = examples.load_globe()
texture = vtki.numpy_to_texture(imageio.imread(examples.mapfile))
Expand Down
8 changes: 7 additions & 1 deletion tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import vtki
from vtki import examples as ex
from vtki import utilities
from vtki import readers

# Only set this here just the once.
utilities.set_error_output_file(os.path.join(os.path.dirname(__file__), 'ERROR_OUTPUT.txt'))
Expand Down Expand Up @@ -41,7 +42,12 @@ def test_read(tmpdir):
types = (vtki.PolyData, vtki.PolyData, vtki.UnstructuredGrid,
vtki.PolyData, vtki.UniformGrid, vtki.RectilinearGrid)
for i, filename in enumerate(fnames):
obj = utilities.read(filename)
obj = readers.read(filename)
assert isinstance(obj, types[i])
# Now test the standard_reader_routine
for i, filename in enumerate(fnames):
# Pass attrs to for the standard_reader_routine to be used
obj = readers.read(filename, attrs={'DebugOn': None})
assert isinstance(obj, types[i])
# this is also tested for each mesh types init from file tests
filename = str(tmpdir.mkdir("tmpdir").join('tmp.%s' % 'npy'))
Expand Down
1 change: 1 addition & 0 deletions vtki/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from vtki._version import __version__
from vtki.plotting import *
from vtki.utilities import *
from vtki.readers import *
from vtki.colors import *
from vtki.filters import DataSetFilters
from vtki.common import Common
Expand Down
5 changes: 3 additions & 2 deletions vtki/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import vtk
from vtk import vtkMultiBlockDataSet

import vtki
from vtki import plot
from vtki.utilities import get_scalar, is_vtki_obj, wrap

Expand Down Expand Up @@ -89,7 +90,7 @@ def _load_file(self, filename):
raise Exception('File %s does not exist' % filename)

# Get extension
ext = os.path.splitext(filename)[1].lower()
ext = vtki.get_ext(filename)
# Extensions: .vtm and .vtmb

# Select reader
Expand Down Expand Up @@ -126,7 +127,7 @@ def save(self, filename, binary=True):
file size.
"""
filename = os.path.abspath(os.path.expanduser(filename))
ext = os.path.splitext(filename)[1].lower()
ext = vtki.get_ext(filename)
if ext in ['.vtm', '.vtmb']:
writer = vtk.vtkXMLMultiBlockDataWriter()
else:
Expand Down
2 changes: 1 addition & 1 deletion vtki/examples/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def load_globe():

def load_globe_texture():
""" Loads a vtk.vtkTexture that can be applied to the globe source """
return vtki.load_texture(mapfile)
return vtki.read_texture(mapfile)

def plot_ants_plane(off_screen=False, notebook=None):
"""
Expand Down
2 changes: 1 addition & 1 deletion vtki/pointset.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def _load_file(self, filename):
raise Exception('File %s does not exist' % filename)

# Get extension
ext = os.path.splitext(filename)[1].lower()
ext = vtki.get_ext(filename)

# Select reader
if ext == '.ply':
Expand Down
196 changes: 196 additions & 0 deletions vtki/readers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
"""
Contains a dictionary that maps file extensions to VTK readers
"""
import os

import vtk
import vtki


READERS = {
# Standard dataset readers:
'.vtk': vtk.vtkDataSetReader,
'.vti': vtk.vtkXMLImageDataReader,
'.vtr': vtk.vtkXMLRectilinearGridReader,
'.vtu': vtk.vtkXMLUnstructuredGridReader,
'.ply': vtk.vtkPLYReader,
'.obj': vtk.vtkOBJReader,
'.stl': vtk.vtkSTLReader,
'.vts': vtk.vtkXMLStructuredGridReader,
'.vtm': vtk.vtkXMLMultiBlockDataReader,
'.vtmb': vtk.vtkXMLMultiBlockDataReader,
# Image formats:
'.bmp': vtk.vtkBMPReader,
'.dem': vtk.vtkDEMReader,
'.dcm': vtk.vtkDICOMImageReader,
'.jpeg': vtk.vtkJPEGReader,
'.jpg': vtk.vtkJPEGReader,
'.png': vtk.vtkPNGReader,
'.pnm': vtk.vtkPNMReader,
'.slc': vtk.vtkSLCReader,
'.tiff': vtk.vtkTIFFReader,
'.tif': vtk.vtkTIFFReader,
# ExodusII files:
#.g, .e, .ex2, .ex2v2, .exo, .gen, .exoII, .exii, .0, .00, .000
'.g': vtk.vtkExodusIIReader,
'.e': vtk.vtkExodusIIReader,
'.ex2': vtk.vtkExodusIIReader,
'.ex2v2': vtk.vtkExodusIIReader,
'.exo': vtk.vtkExodusIIReader,
'.gen': vtk.vtkExodusIIReader,
'.exoii': vtk.vtkExodusIIReader,
'.exii': vtk.vtkExodusIIReader,
'.0': vtk.vtkExodusIIReader,
'.00': vtk.vtkExodusIIReader,
'.000': vtk.vtkExodusIIReader,
# Other formats:
'.byu': vtk.vtkBYUReader,
'.chemml': vtk.vtkCMLMoleculeReader,
'.cml': vtk.vtkCMLMoleculeReader,
# TODO: '.csv': vtk.vtkCSVReader, # vtkTables are currently not supported
'.facet': vtk.vtkFacetReader,
'.cas': vtk.vtkFLUENTReader,
'.dat': vtk.vtkFLUENTReader,
'.cube': vtk.vtkGaussianCubeReader,
'.res': vtk.vtkMFIXReader,
'.foam': vtk.vtkOpenFOAMReader,
'.pdb': vtk.vtkPDBReader,
'.p3d': vtk.vtkPlot3DMetaReader,
'.pts': vtk.vtkPTSReader,
'.particles': vtk.vtkParticleReader,
#TODO: '.pht': vtk.vtkPhasta??????,
#TODO: '.vpc': vtk.vtkVPIC?????,
'.xyz': vtk.vtkXYZMolReader,
}


if (vtk.vtkVersion().GetVTKMajorVersion() >= 8 and
vtk.vtkVersion().GetVTKMinorVersion() >= 2):
READERS['.sgy'] = vtk.vtkSegYReader
READERS['.segy'] = vtk.vtkSegYReader


def get_ext(filename):
"""Extract the extension of the filename"""
ext = os.path.splitext(filename)[1].lower()
return ext


def get_reader(filename):
"""Gets the corresponding reader based on file extension and instantiates it
"""
ext = get_ext(filename)
return READERS[ext]() # Get and instantiate the reader


def standard_reader_routine(reader, filename, attrs=None):
"""Use a given reader from the ``READERS`` mapping in the common VTK reading
pipeline routine.
Parameters
----------
reader : vtkReader
Any instantiated VTK reader class
filename : str
The string filename to the data file to read.
attrs : dict, optional
A dictionary of attributes to call on the reader. Keys of dictionary are
the attribute/method names and values are the arguments passed to those
calls. If you do not have any attributes to call, pass ``None`` as the
value.
"""
if attrs is None:
attrs = {}
if not isinstance(attrs, dict):
raise TypeError('Attributes must be a dictionary of name and arguments.')
reader.SetFileName(filename)
# Apply any attributes listed
for name, args in attrs.items():
attr = getattr(reader, name)
if args is not None:
if not isinstance(args, (list, tuple)):
args = [args]
attr(*args)
else:
attr()
# Perform the read
reader.Update()
return vtki.wrap(reader.GetOutputDataObject(0))


def read_legacy(filename):
"""Use VTK's legacy reader to read a file"""
reader = vtk.vtkDataSetReader()
reader.SetFileName(filename)
# Ensure all data is fetched with poorly formated legacy files
reader.ReadAllScalarsOn()
reader.ReadAllColorScalarsOn()
reader.ReadAllNormalsOn()
reader.ReadAllTCoordsOn()
reader.ReadAllVectorsOn()
# Perform the read
reader.Update()
output = reader.GetOutputDataObject(0)
if output is None:
raise AssertionError('No output when using VTKs legacy reader')
return vtki.wrap(output)


def read(filename, attrs=None):
"""This will read any VTK file! It will figure out what reader to use
then wrap the VTK object for use in ``vtki``.
Parameters
----------
attrs : dict, optional
A dictionary of attributes to call on the reader. Keys of dictionary are
the attribute/method names and values are the arguments passed to those
calls. If you do not have any attributes to call, pass ``None`` as the
value.
"""
filename = os.path.abspath(os.path.expanduser(filename))
ext = get_ext(filename)

# From the extension, decide which reader to use
if attrs is not None:
reader = get_reader(filename)
return standard_reader_routine(reader, filename, attrs=attrs)
elif ext in '.vti': # ImageData
return vtki.UniformGrid(filename)
elif ext in '.vtr': # RectilinearGrid
return vtki.RectilinearGrid(filename)
elif ext in '.vtu': # UnstructuredGrid
return vtki.UnstructuredGrid(filename)
elif ext in ['.ply', '.obj', '.stl']: # PolyData
return vtki.PolyData(filename)
elif ext in '.vts': # StructuredGrid
return vtki.StructuredGrid(filename)
elif ext in ['.vtm', '.vtmb']:
return vtki.MultiBlock(filename)
elif ext in ['.vtk']:
# Attempt to use the legacy reader...
return read_legacy(filename)
else:
# Attempt find a reader in the readers mapping
try:
reader = get_reader(filename)
return standard_reader_routine(reader, filename)
except KeyError:
pass
raise IOError("This file was not able to be automatically read by vtki.")


def read_texture(filename, attrs=None):
"""Loads a ``vtkTexture`` from an image file."""
filename = os.path.abspath(os.path.expanduser(filename))
try:
# intitialize the reader using the extnesion to find it
reader = get_reader(filename)
image = standard_reader_routine(reader, filename, attrs=attrs)
return vtki.image_to_texture(image)
except KeyError:
# Otherwise, use the imageio reader
pass
return vtki.numpy_to_texture(imageio.imread(filename))
79 changes: 8 additions & 71 deletions vtki/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
vtk_to_numpy)

import vtki
from vtki.readers import standard_reader_routine, get_ext, get_reader

POINT_DATA_FIELD = 0
CELL_DATA_FIELD = 1
Expand Down Expand Up @@ -237,50 +238,6 @@ def wrap(vtkdataset):
return vtkdataset # if not supported just passes the VTK data object
return wrapped

def read(filename):
"""This will read any VTK file! It will figure out what reader to use
then wrap the VTK object for use in ``vtki``
"""
filename = os.path.abspath(os.path.expanduser(filename))
ext = os.path.splitext(filename)[1].lower()

def legacy(filename):
"""Use VTK's legacy reader to read a file"""
reader = vtk.vtkDataSetReader()
reader.SetFileName(filename)
# Ensure all data is fetched with poorly formated legacy files
reader.ReadAllScalarsOn()
reader.ReadAllColorScalarsOn()
reader.ReadAllNormalsOn()
reader.ReadAllTCoordsOn()
reader.ReadAllVectorsOn()
# Perform the read
reader.Update()
return reader.GetOutputDataObject(0)

# From the extension, decide which reader to use
if ext in '.vti': # ImageData
return vtki.UniformGrid(filename)
elif ext in '.vtr': # RectilinearGrid
return vtki.RectilinearGrid(filename)
elif ext in '.vtu': # UnstructuredGrid
return vtki.UnstructuredGrid(filename)
elif ext in ['.ply', '.obj', '.stl']: # PolyData
return vtki.PolyData(filename)
elif ext in '.vts': # StructuredGrid
return vtki.StructuredGrid(filename)
elif ext in ['.vtm', '.vtmb']:
return vtki.MultiBlock(filename)
else:
# Attempt to use the legacy reader...
try:
output = wrap(legacy(filename))
if output is None:
raise AssertionError()
return output
except:
pass
raise IOError("This file was not able to be automatically read by vtki.")


def set_error_output_file(filename):
Expand All @@ -293,29 +250,12 @@ def set_error_output_file(filename):
return fileOutputWindow, outputWindow


def load_texture(filename):
"""Loads a ``vtkTexture`` from an image file."""
filename = os.path.abspath(os.path.expanduser(filename))
ext = os.path.splitext(filename)[1].lower()
readers = {
'.jpg': vtk.vtkJPEGReader,
'.jpeg': vtk.vtkJPEGReader,
'.tif': vtk.vtkTIFFReader,
'.tiff': vtk.vtkTIFFReader,
'.png': vtk.vtkPNGReader,
}
try:
# intitialize the reader using the extnesion to find it
reader = readers[ext]()
except KeyError:
# Otherwise, use the imageio reader
return numpy_to_texture(imageio.imread(filename))
reader.SetFileName(filename)
reader.Update()
texture = vtk.vtkTexture()
texture.SetInputDataObject(reader.GetOutputDataObject(0))
texture.Update()
return texture
def image_to_texture(image):
"""Converts ``vtkImageData`` to a ``vtkTexture``"""
vtex = vtk.vtkTexture()
vtex.SetInputDataObject(image)
vtex.Update()
return vtex


def numpy_to_texture(image):
Expand All @@ -327,10 +267,7 @@ def numpy_to_texture(image):
grid = vtki.UniformGrid((image.shape[1], image.shape[0], 1))
grid.point_arrays['Image'] = np.flip(image.swapaxes(0,1), axis=1).reshape((-1, 3), order='F')
grid.set_active_scalar('Image')
vtex = vtk.vtkTexture()
vtex.SetInputDataObject(grid)
vtex.Update()
return vtex
return image_to_texture(grid)


def is_inside_bounds(point, bounds):
Expand Down

0 comments on commit db9ddb2

Please sign in to comment.