Comments (2)
Great idea! Here's a possible way to implement this for voxelize
using the sample
and split_values
filters. See code/images below.
A few notes about this method:
sample
seems to only operate on point data, not sure how to make it work directly with cell data. Usingptc
seems is a bit hacky because it means the data will be interpolated twice.- the tolerance for
sample
must be sufficiently large, (maybe set it toinf
? or just really large) split_values
is a new filter (pyvista==0.44.0
), currently only available from themain
(dev) branch.
import pyvista as pv
from pyvista import examples
import numpy as np
# 1. Load mesh and add cell data labels
mesh = examples.download_bunny_coarse().clean()
labels = np.zeros((mesh.n_cells,))
labels[:700] = 1
mesh['labels'] = labels
mesh.plot()
# 2. Voxelize and sample
vox = pv.voxelize(mesh, density=0.01)
sampled = vox.sample(target=mesh, tolerance=1)
sampled.set_active_scalars('labels')
sampled.plot(show_edges=True)
# 3. We want cell data not point data
sampled = sampled.ptc()
sampled['labels'] = np.round(sampled['labels'])
sampled.plot(show_edges=True)
# 4. Split into multiblock
multiblock = sampled.split_values()
multiblock[0].plot()
# Also multiblock[1].plot(show_edges=True)
Output:
- Inital labeled mesh:
![image](https://private-user-images.githubusercontent.com/89109579/339965245-3c8ce49c-bdf4-4186-b441-824f0ce68f37.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ1MzIyMzYsIm5iZiI6MTcyNDUzMTkzNiwicGF0aCI6Ii84OTEwOTU3OS8zMzk5NjUyNDUtM2M4Y2U0OWMtYmRmNC00MTg2LWI0NDEtODI0ZjBjZTY4ZjM3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI0VDIwMzg1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTQ0N2ZhMTE4NDRmYjYxOGQwMjViMzk4NzdkMmNkZmU2YmYzMTE4NDUwNWI3ZDZlZDMwYWRhNWY1ZWZiNGQyYTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.9NEVZRVQE-EPrchfs7xz8xbhBwPINR_QxqLSiH6yGdo)
- Sampled voxelized mesh. The cell data is interpolated as point data (bad), but we want cell data
![image](https://private-user-images.githubusercontent.com/89109579/339965447-9e81a1d5-f022-4154-a38f-cfda0bdec4af.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ1MzIyMzYsIm5iZiI6MTcyNDUzMTkzNiwicGF0aCI6Ii84OTEwOTU3OS8zMzk5NjU0NDctOWU4MWExZDUtZjAyMi00MTU0LWEzOGYtY2ZkYTBiZGVjNGFmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI0VDIwMzg1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWFjNDdiY2I3MDBlOWNkZDMzMDM4YTk4OGU0Mzc2NjBiM2JhYjMwNGFlNzIxNTQ4MzM4MGNjZmVhN2MyNGNlMGEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.RuCLEuyPFKY4o8_VCs0dtPdfMfxZPKE4vC6UBnn_knM)
- After fixing cell data
![image](https://private-user-images.githubusercontent.com/89109579/339965467-5ae0daf1-55df-40b8-be07-f3c1e06f071f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ1MzIyMzYsIm5iZiI6MTcyNDUzMTkzNiwicGF0aCI6Ii84OTEwOTU3OS8zMzk5NjU0NjctNWFlMGRhZjEtNTVkZi00MGI4LWJlMDctZjNjMWUwNmYwNzFmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI0VDIwMzg1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTdjYmJiYjNlMjc1YjE1YzYxOWUwZmI4Y2E1NjZiOWE1MGI3YTE4NDBhOGUzZTE0NjEyMWMxNjRjNDc0NTdmYTkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.GscwnJDCMe04NQQUahvadm5QDzScX2P4X8hKVw0kqTU)
- First block of the split voxelized labels
![image](https://private-user-images.githubusercontent.com/89109579/339965509-42971d88-2d04-4245-941c-a9e85b9a8b34.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ1MzIyMzYsIm5iZiI6MTcyNDUzMTkzNiwicGF0aCI6Ii84OTEwOTU3OS8zMzk5NjU1MDktNDI5NzFkODgtMmQwNC00MjQ1LTk0MWMtYTllODViOWE4YjM0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA4MjQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwODI0VDIwMzg1NlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTE3OTNmMjRhYTE4MTIzZTVkNTlkY2Q0ODk0Nzg5NTRmYzFlM2YzMTRhNDU1MWVjYmM2MjM0N2JhNWVhZGEzZTEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.XCyPq5uy5CpoReRqyM032o8sWFHqf1of1WkVsLjrBQQ)
from pyvista.
Thanks. I will check it out. I am fairly new to pyvista in terms of experinece so I don't know lots of capaiblities (e.g., sample function.
I also gave it a ago by modifying the voxelize_volume function. I was able to produce the desired result. I used a for loop so I don't to go over the blocks in the mesh so I don't know if it is the most efficient way of doing it. Here is an example of the result:
import collections
import numpy as np
import pyvista
def voxelize_volume_multiblock_label(mesh, density=None, check_surface=True):
"""Voxelize mesh to create a RectilinearGrid voxel volume.
Creates a voxel volume that encloses the input mesh and discretizes the cells
within the volume that intersect or are contained within the input mesh.
``InsideMesh``, an array in ``cell_data``, is ``1`` for cells inside and ``0`` outside.
Parameters
----------
mesh : pyvista.DataSet
Mesh to voxelize.
density : float | array_like[float]
The uniform size of the voxels when single float passed.
Nonuniform voxel size if a list of values are passed along x,y,z directions.
Defaults to 1/100th of the mesh length.
check_surface : bool, default: True
Specify whether to check the surface for closure. If on, then the
algorithm first checks to see if the surface is closed and
manifold. If the surface is not closed and manifold, a runtime
error is raised.
Returns
-------
pyvista.RectilinearGrid
RectilinearGrid as voxelized volume with discretized cells.
See Also
--------
pyvista.voxelize
pyvista.DataSetFilters.select_enclosed_points
Examples
--------
Create an equal density voxel volume from input mesh.
>>> import pyvista as pv
>>> import numpy as np
Load file from PyVista examples.
>>> from pyvista import examples
>>> mesh = examples.download_cow()
Create an equal density voxel volume and plot the result.
>>> vox = pv.voxelize_volume(mesh, density=0.15)
>>> cpos = [(15, 3, 15), (0, 0, 0), (0, 0, 0)]
>>> vox.plot(scalars='InsideMesh', show_edges=True, cpos=cpos)
Slice the voxel volume to view ``InsideMesh``.
>>> slices = vox.slice_orthogonal()
>>> slices.plot(scalars='InsideMesh', show_edges=True)
Create a voxel volume from unequal density dimensions and plot result.
>>> vox = pv.voxelize_volume(mesh, density=[0.15, 0.15, 0.5])
>>> vox.plot(scalars='InsideMesh', show_edges=True, cpos=cpos)
Slice the unequal density voxel volume to view ``InsideMesh``.
>>> slices = vox.slice_orthogonal()
>>> slices.plot(scalars='InsideMesh', show_edges=True, cpos=cpos)
"""
mesh = pyvista.wrap(mesh)
if density is None:
density = mesh.length / 100
if isinstance(density, (int, float, np.number)):
density_x, density_y, density_z = [density] * 3
elif isinstance(density, (collections.abc.Sequence, np.ndarray)):
density_x, density_y, density_z = density
else:
raise TypeError(f"Invalid density {density!r}, expected number or array-like.")
x_min, x_max, y_min, y_max, z_min, z_max = mesh.bounds
x = np.arange(x_min, x_max, density_x)
y = np.arange(y_min, y_max, density_y)
z = np.arange(z_min, z_max, density_z)
# Initialize the voi
voi = pyvista.RectilinearGrid(x, y, z)
voi["InsideMesh"] = np.zeros(voi.n_cells)
# check and pre-process input mesh
sub_mesh: pyvista.PolyData
for i, sub_mesh in enumerate(mesh):
sub_mesh_number = i + 1
surface: pyvista.PolyData = sub_mesh.extract_geometry()
# filter preserves topology
if not surface.faces.size:
# we have a point cloud or an empty mesh
raise ValueError("Input mesh must have faces for voxelization.")
if not surface.is_all_triangles:
# reduce chance for artifacts, see gh-1743
surface.triangulate(inplace=True)
# get part of the mesh within the mesh's bounding surface.
selection = voi.select_enclosed_points(
surface, tolerance=0.0, check_surface=check_surface
)
mask_vol = selection.point_data["SelectedPoints"].view(np.bool_)
# Get voxels that fall within input mesh boundaries
cell_ids = np.unique(
voi.extract_points(np.argwhere(mask_vol))["vtkOriginalCellIds"]
)
# Create new element of grid where all cells _within_ mesh boundary are
# given new name 'MeshCells' and a discrete value of 1
voi["InsideMesh"][cell_ids] = sub_mesh_number
return voi
from pyvista.
Related Issues (20)
- RGB scalars not working with `Plane` on Windows
- Duplicate ray tracing example in 0.44 docs HOT 1
- "Toggle axis" button state on Trame Plotter Menu is incorrect when showing axes on startup HOT 2
- Field Data Doesnt Save on Nested MultiBlocks HOT 4
- Cannot serialize MultiBlock (dataset of type 13) with pickle HOT 1
- Instantiating an ExplicitStructuredGrid is slower than casting from UnstructuredGrid HOT 4
- Loading STL mesh file: Header value too long (Jupyter desktop)
- Plots do not show HOT 2
- `MultiBlock` repr does not format bounds using scientific notation
- `inplace` is designed to modify the object itself and return the object HOT 1
- `fit_plane_to_points` crashes python with many points HOT 4
- Trame ui can not hide menu HOT 1
- Make `center` consistently return a tuple
- `clip` filter with `return_clipped=True` returns mesh with same bounds as input HOT 1
- Reduce size of documentation build or modify actions to use less disk space
- AttributeError: module 'colorcet' has no attribute 'cm' HOT 8
- `add_field_data` breaks `_repr_html_` HOT 1
- pyvista cannot be installed properly (multiple approaches tried)
- Interpolation of scaler field in a 20-node brick element seems incorrect
- Add a figure of CellTypes to explain the shape and the order of node in `pyvista.CellType` section HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyvista.