def test_multi_io_erros(tmpdir): fdir = tmpdir.mkdir("tmpdir") multi = vtki.MultiBlock() # Check saving with bad extension bad_ext_name = str(fdir.join('tmp.%s' % 'npy')) with pytest.raises(Exception): multi.save(bad_ext_name) arr = np.random.rand(10, 10) np.save(bad_ext_name, arr) # Load non existing file with pytest.raises(Exception): data = vtki.MultiBlock('foo.vtm') # Load bad extension with pytest.raises(IOError): data = vtki.MultiBlock(bad_ext_name)
def split_bodies(dataset, label=False): """Find, label, and split connected bodies/volumes. This splits different connected bodies into blocks in a MultiBlock dataset. Parameters ---------- label : bool A flag on whether to keep the ID arrays given by the ``connectivity`` filter. """ # Get the connectivity and label different bodies labeled = dataset.connectivity() classifier = labeled.cell_arrays['RegionId'] bodies = vtki.MultiBlock() for vid in np.unique(classifier): # Now extract it: b = labeled.threshold([vid-0.5, vid+0.5], scalars='RegionId') if not label: # strange behavior: # must use this method rather than deleting from the point_arrays # or else object is collected. b._remove_cell_scalar('RegionId') b._remove_point_scalar('RegionId') bodies.append(b) return bodies
def test_multi_block_init_list(): data = [ex.load_rectilinear(), ex.load_airplane()] multi = vtki.MultiBlock(data) assert isinstance(multi, vtki.MultiBlock) assert multi.n_blocks == 2 assert isinstance(multi[0], vtki.RectilinearGrid) assert isinstance(multi[1], vtki.PolyData)
def test_multi_block_io(extension, binary, tmpdir): filename = str(tmpdir.mkdir("tmpdir").join('tmp.%s' % extension)) multi = vtki.MultiBlock() # Add examples multi.append(ex.load_ant()) multi.append(ex.load_sphere()) multi.append(ex.load_uniform()) multi.append(ex.load_airplane()) multi.append(ex.load_globe()) # Now check everything assert multi.n_blocks == 5 # Save it out multi.save(filename, binary) foo = vtki.MultiBlock(filename) assert foo.n_blocks == multi.n_blocks foo = vtki.read(filename) assert foo.n_blocks == multi.n_blocks
def test_multi_block_init_vtk(): multi = vtk.vtkMultiBlockDataSet() multi.SetBlock(0, vtk.vtkRectilinearGrid()) multi.SetBlock(1, vtk.vtkTable()) multi = vtki.MultiBlock(multi) assert isinstance(multi, vtki.MultiBlock) assert multi.n_blocks == 2 assert isinstance(multi[0], vtki.RectilinearGrid) assert isinstance(multi[1], vtk.vtkTable) multi = vtk.vtkMultiBlockDataSet() multi.SetBlock(0, vtk.vtkRectilinearGrid()) multi.SetBlock(1, vtk.vtkTable()) multi = vtki.MultiBlock(multi, deep=True) assert isinstance(multi, vtki.MultiBlock) assert multi.n_blocks == 2 assert isinstance(multi[0], vtki.RectilinearGrid) assert isinstance(multi[1], vtk.vtkTable)
def test_multi_block_plot(): multi = vtki.MultiBlock() multi.append(examples.load_rectilinear()) uni = examples.load_uniform() arr = np.random.rand(uni.n_cells) uni._add_cell_scalar(arr, 'Random Data') multi.append(uni) # And now add a data set without the desired array and a NULL component multi[3] = examples.load_airplane() multi.plot(scalars='Random Data', off_screen=OFF_SCREEN, multi_colors=True)
def project_to_vtk(project): """Converts an OMF project (:class:`omf.base.Project`) to a :class:`vtki.MultiBlock` data boject """ # Iterate over the elements and add converted VTK objects a MultiBlock data = vtki.MultiBlock() for i, e in enumerate(project.elements): d = omfvtk.wrap(e) data[i, e.name] = d return data
def test_multi_block_repr(): multi = vtki.MultiBlock() # Add examples multi.append(ex.load_ant()) multi.append(ex.load_sphere()) multi.append(ex.load_uniform()) multi.append(ex.load_airplane()) multi.append(None) # Now check everything assert multi.n_blocks == 5 assert multi._repr_html_() is not None
def test_multi_block_init_dict(): data = dict() data['grid'] = ex.load_rectilinear() data['poly'] = ex.load_airplane() multi = vtki.MultiBlock(data) assert isinstance(multi, vtki.MultiBlock) assert multi.n_blocks == 2 # Note that disctionaries do not maintain order assert isinstance(multi[0], (vtki.RectilinearGrid, vtki.PolyData)) assert multi.get_block_name(0) in ['grid', 'poly'] assert isinstance(multi[1], (vtki.RectilinearGrid, vtki.PolyData)) assert multi.get_block_name(1) in ['grid', 'poly']
def read_shape_file_to_vtk(filename, topo_points): """Read all the features of a shapefile into vtki objects. Use the topo_points argument to fill the Z component of 2D points """ shp = shapefile.Reader(filename) output = vtki.MultiBlock() for i, feature in enumerate(shp.shapeRecords()): shape = feature.shape try: output[i, feature.record[1]] = VTK_CONVERTERS[shape.shapeType](shape, topo_points) except KeyError: raise RuntimeError('Shape type ({}) unknown'.format(shape.shapeType)) return output
def test_combine_filter(): multi = vtki.MultiBlock() # Add examples multi.append(ex.load_ant()) multi.append(ex.load_sphere()) multi.append(ex.load_uniform()) multi.append(ex.load_airplane()) multi.append(ex.load_globe()) # Now check everything assert multi.n_blocks == 5 # Now apply the geometry filter to combine a plethora of data blocks geom = multi.combine() assert isinstance(geom, vtki.UnstructuredGrid)
def wrap(data): """Wraps the OMF data object/project as a VTK data object. This is the primary function that an end user will harness. Args: data: any OMF data object Example: >>> import omf >>> import omfvtk >>> # Read all elements >>> reader = omf.OMFReader('test_file.omf') >>> project = reader.get_project() >>> # Iterate over the elements and add converted VTK objects to dictionary: >>> data = dict() >>> for e in project.elements: >>> d = omfvtk.wrap(e) >>> data[e.name] = d """ # Allow recursion if isinstance(data, (list, tuple)): multi = vtki.MultiBlock() for i, item in enumerate(data): multi.append(wrap(item)) multi.set_block_name(i, item.name) return multi # Define wrappers wrappers = { 'LineSetElement': omfvtk.line_set_to_vtk, 'PointSetElement': omfvtk.point_set_to_vtk, # Surfaces 'SurfaceGeometry': omfvtk.surface_geom_to_vtk, 'SurfaceGridGeometry': omfvtk.surface_grid_geom_to_vtk, 'SurfaceElement': omfvtk.surface_to_vtk, # Volumes 'VolumeGridGeometry': omfvtk.volume_grid_geom_to_vtk, 'VolumeElement': omfvtk.volume_to_vtk, 'Project': omfvtk.project_to_vtk, } # get the class name key = data.__class__.__name__ try: return wrappers[key](data) except KeyError: raise RuntimeError( 'Data of type ({}) is not supported currently.'.format(key))
def slice_along_axis(dataset, n=5, axis='x', tolerance=None, generate_triangles=False, contour=False): """Create many slices of the input dataset along a specified axis. Parameters ---------- n : int The number of slices to create axis : str or int The axis to generate the slices along. Perpendicular to the slices. Can be string name (``'x'``, ``'y'``, or ``'z'``) or axis index (``0``, ``1``, or ``2``). tolerance : float, optional The toleranceerance to the edge of the dataset bounds to create the slices generate_triangles: bool, optional If this is enabled (``False`` by default), the output will be triangles otherwise, the output will be the intersection polygons. contour : bool, optional If True, apply a ``contour`` filter after slicing """ axes = {'x':0, 'y':1, 'z':2} output = vtki.MultiBlock() if isinstance(axis, int): ax = axis axis = list(axes.keys())[list(axes.values()).index(ax)] elif isinstance(axis, str): try: ax = axes[axis] except KeyError: raise RuntimeError('Axis ({}) not understood'.format(axis)) # get the locations along that axis if tolerance is None: tolerance = (dataset.bounds[ax*2+1] - dataset.bounds[ax*2]) * 0.01 rng = np.linspace(dataset.bounds[ax*2]+tolerance, dataset.bounds[ax*2+1]-tolerance, n) center = list(dataset.center) # Make each of the slices for i in range(n): center[ax] = rng[i] slc = DataSetFilters.slice(dataset, normal=axis, origin=center, generate_triangles=generate_triangles, contour=contour) output[i, 'slice%.2d'%i] = slc return output
def test_multi_block_append(): """This puts all of the example data objects into a a MultiBlock container""" multi = vtki.MultiBlock() # Add examples multi.append(ex.load_ant()) multi.append(ex.load_sphere()) multi.append(ex.load_uniform()) multi.append(ex.load_airplane()) multi.append(ex.load_rectilinear()) # Now check everything assert multi.n_blocks == 5 assert multi.bounds is not None assert isinstance(multi[0], vtki.PolyData) assert isinstance(multi[1], vtki.PolyData) assert isinstance(multi[2], vtki.UniformGrid) assert isinstance(multi[3], vtki.PolyData) assert isinstance(multi[4], vtki.RectilinearGrid)
def test_export_multi(tmpdir): filename = str(tmpdir.mkdir("tmpdir").join('scene')) multi = vtki.MultiBlock() # Add examples multi.append(ex.load_ant()) multi.append(ex.load_sphere()) multi.append(ex.load_uniform()) multi.append(ex.load_airplane()) multi.append(ex.load_rectilinear()) # Create the scene plotter = vtki.Plotter(off_screen=OFF_SCREEN) plotter.add_mesh(multi) plotter.export_vtkjs(filename, compress_arrays=True) cpos_out = plotter.show() # Export must be called before showing! plotter.close() # Now make sure the file is there assert os.path.isfile('{}.vtkjs'.format(filename))
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 ['.e', '.exo']: return read_exodus(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 test_multi_block_set_get_ers(): """This puts all of the example data objects into a a MultiBlock container""" multi = vtki.MultiBlock() # Set the number of blocks multi.n_blocks = 6 assert multi.GetNumberOfBlocks() == 6 # Check that VTK side registered it assert multi.n_blocks == 6 # Check vtki side registered it # Add data to the MultiBlock data = ex.load_rectilinear() multi[1, 'rect'] = data # Make sure number of blocks is constant assert multi.n_blocks == 6 # Check content assert isinstance(multi[1], vtki.RectilinearGrid) for i in [0, 2, 3, 4, 5]: assert multi[i] == None # Check the bounds assert multi.bounds == list(data.bounds) multi[5] = ex.load_uniform() multi.set_block_name(5, 'uni') multi.set_block_name(5, None) # Make sure it doesn't get overwritten assert isinstance(multi.get(5), vtki.UniformGrid) # Test get by name assert isinstance(multi['uni'], vtki.UniformGrid) assert isinstance(multi['rect'], vtki.RectilinearGrid) # Test the del operator del multi[0] assert multi.n_blocks == 5 # Make sure the rect grid was moved up assert isinstance(multi[0], vtki.RectilinearGrid) assert multi.get_block_name(0) == 'rect' assert multi.get_block_name(2) == None # test del by name del multi['uni'] assert multi.n_blocks == 4 # test the pop operator pop = multi.pop(0) assert isinstance(pop, vtki.RectilinearGrid) assert multi.n_blocks == 3 assert multi.get_block_name(10) is None with pytest.raises(KeyError): idx = multi.get_index_by_name('foo')
def slice_orthogonal(dataset, x=None, y=None, z=None, generate_triangles=False, contour=False): """Creates three orthogonal slices through the dataset on the three caresian planes. Yields a MutliBlock dataset of the three slices Parameters ---------- x : float The X location of the YZ slice y : float The Y location of the XZ slice z : float The Z location of the XY slice generate_triangles: bool, optional If this is enabled (``False`` by default), the output will be triangles otherwise, the output will be the intersection polygons. contour : bool, optional If True, apply a ``contour`` filter after slicing """ output = vtki.MultiBlock() # Create the three slices if x is None: x = dataset.center[0] if y is None: y = dataset.center[1] if z is None: z = dataset.center[2] output[0, 'YZ'] = dataset.slice(normal='x', origin=[x,y,z], generate_triangles=generate_triangles) output[1, 'XZ'] = dataset.slice(normal='y', origin=[x,y,z], generate_triangles=generate_triangles) output[2, 'XY'] = dataset.slice(normal='z', origin=[x,y,z], generate_triangles=generate_triangles) return output
def tool(self, step=None, generate_triangles=False, contour=False, default_params=None, **kwargs): if default_params is None: default_params = {} if self.clean and self.input_dataset.active_scalar is not None: # This will clean out the nan values self.input_dataset = self.input_dataset.threshold() self.contour = contour x, y, z = self.input_dataset.center x = default_params.get("x", x) y = default_params.get("y", y) z = default_params.get("z", z) self._data_to_update = [None, None, None] self.output_dataset = vtki.MultiBlock() self._old = [None, None, None] axes = ['x', 'y', 'z'] def _update_slice(index, x, y, z): name = self.display_params.pop('name') self.plotter.subplot(*self.loc) self.plotter.remove_actor(self._data_to_update[index], reset_camera=False) self.output_dataset[index] = self.input_dataset.slice( normal=axes[index], origin=[x, y, z], generate_triangles=generate_triangles, contour=self.contour) self._data_to_update[index] = self.plotter.add_mesh( self.output_dataset[index], reset_camera=False, name='{}-{}'.format(name, index), **self.display_params) self._old[index] = [x, y, z][index] self.display_params['name'] = name def update(x, y, z, **kwargs): """Update the slices""" self._update_plotting_params(**kwargs) if x != self._old[0] or self._need_to_update: _update_slice(0, x, y, z) if y != self._old[1] or self._need_to_update: _update_slice(1, x, y, z) if z != self._old[2] or self._need_to_update: _update_slice(2, x, y, z) self._need_to_update = False # Set up the step sizes for the sliders if step is None: stepx = 0.05 * (self.input_dataset.bounds[1] - self.input_dataset.bounds[0]) stepy = 0.05 * (self.input_dataset.bounds[3] - self.input_dataset.bounds[2]) stepz = 0.05 * (self.input_dataset.bounds[5] - self.input_dataset.bounds[4]) elif isinstance(step, collections.Iterable): stepx = step[0] stepy = step[1] stepz = step[2] else: stepx = step stepy = step stepz = step # Now set up the widgets xsl = widgets.FloatSlider(min=self.input_dataset.bounds[0] + stepx, max=self.input_dataset.bounds[1] - stepx, step=stepx, value=x, continuous_update=self.continuous_update) ysl = widgets.FloatSlider(min=self.input_dataset.bounds[2] + stepy, max=self.input_dataset.bounds[3] - stepy, step=stepy, value=y, continuous_update=self.continuous_update) zsl = widgets.FloatSlider(min=self.input_dataset.bounds[4] + stepz, max=self.input_dataset.bounds[5] - stepz, step=stepz, value=z, continuous_update=self.continuous_update) # Create/display the widgets return interact(update, x=xsl, y=ysl, z=zsl, scalars=self._get_scalar_names())
def download_bolt_nut(): blocks = vtki.MultiBlock() blocks['bolt'] = _download_and_read('bolt.slc') blocks['nut'] = _download_and_read('nut.slc') return blocks