pyvista.CompositeFilters.generic_filter#
- CompositeFilters.generic_filter(
- function: str | Callable[..., _TypeMultiBlockLeaf],
- /,
- *args,
- **kwargs,
Apply any filter to all nested blocks recursively.
This filter applies a user-specified function or method to all blocks in this
MultiBlock
.Note
If an
inplace
keyword is used, thisMultiBlock
is modified in-place along with all blocks.Note
By default, the specified
function
is not applied to anyNone
blocks. These are simply skipped and passed through to the output.For advanced use, it is possible to apply the filter to
None
blocks by using the undocumented keyword_skip_none=False
.Added in version 0.45.
- Parameters:
- function
Callable
|str
Callable function or name of the method to apply to each block. The function should accept a
DataSet
as input and return either aDataSet
orMultiBlock
as output.- *args
Any
,optional
Arguments to use with the specified
function
.- **kwargs
Any
,optional
Keyword arguments to use with the specified
function
.
- function
- Returns:
MultiBlock
Filtered dataset.
- Raises:
RuntimeError
Raised if the filter cannot be applied to any block for any reason. This overrides
TypeError
,ValueError
,AttributeError
errors when filtering.
Examples
Create a
MultiBlock
with various mesh types.>>> import pyvista as pv >>> from pyvista import examples >>> import numpy as np >>> volume = examples.load_uniform() >>> poly = examples.load_ant() >>> unstructured = examples.load_tetbeam() >>> multi = pv.MultiBlock([volume, poly, unstructured])
>>> type(multi[0]), type(multi[1]), type(multi[2]) (<class 'pyvista.core.grid.ImageData'>, <class 'pyvista.core.pointset.PolyData'>, <class 'pyvista.core.pointset.UnstructuredGrid'>)
Use the generic filter to apply
cast_to_unstructured_grid()
to all blocks.>>> filtered = multi.generic_filter('cast_to_unstructured_grid')
>>> type(filtered[0]), type(filtered[1]), type(filtered[2]) (<class 'pyvista.core.pointset.UnstructuredGrid'>, <class 'pyvista.core.pointset.UnstructuredGrid'>, <class 'pyvista.core.pointset.UnstructuredGrid'>)
Use the
partition()
filter on all blocks. Any arguments can be specified as though the filter is being used directly.>>> filtered = multi.generic_filter('partition', 4, as_composite=True)
Any function can be used as long as it returns a
DataSet
orMultiBlock
. For example, we can normalize each block independently to have bounds between-0.5
and0.5
.>>> def normalize_bounds(dataset): ... # Center the dataset ... dataset = dataset.translate(-np.array(dataset.center)) ... # Scale the dataset ... bounds = dataset.bounds ... x_scale = 1 / (bounds.x_max - bounds.x_min) ... y_scale = 1 / (bounds.y_max - bounds.y_min) ... z_scale = 1 / (bounds.z_max - bounds.z_min) ... return dataset.scale((x_scale, y_scale, z_scale))
>>> filtered = multi.generic_filter(normalize_bounds) >>> filtered MultiBlock (...) N Blocks: 3 X Bounds: -5.000e-01, 5.000e-01 Y Bounds: -5.000e-01, 5.000e-01 Z Bounds: -5.000e-01, 5.000e-01
The generic filter will fail if the filter can only be applied to some blocks but not others. For example, it is not possible to use the
resample()
filter generically since theMultiBlock
above is heterogeneous and contains some blocks which are notImageData
.>>> multi.generic_filter('resample', 0.5) RuntimeError: The filter 'resample' could not be applied to the block at index 1 with name 'Block-01' and type PolyData.
Use a custom function instead to apply the generic filter conditionally. Here we filter the image blocks but simply pass-through a copy of any other blocks.
>>> def conditional_resample(dataset, *args, **kwargs): ... if isinstance(dataset, pv.ImageData): ... return dataset.resample(*args, **kwargs) ... return dataset.copy()
>>> filtered = multi.generic_filter(conditional_resample, 0.5)