三維像素化曲面網格(網格曲面的體元化)
創建封閉曲面網格和網格體的體元模型。
示例演示瞭如何從包圍盒計算隱式距離。
體元化步驟
- 確定體元的大小。
- 生成vtkUnStructuredGrid
- 確定體元是否在封閉曲面內或體中
def voxelize(mesh, density=None, check_surface=True):
"""Voxelize mesh to UnstructuredGrid.
Parameters
----------
density : float
The uniform size of the voxels. Defaults to 1/100th of the mesh length.
check_surface : bool
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.
"""
if not pyvista.is_pyvista_dataset(mesh):
mesh = pyvista.wrap(mesh)
if density is None:
density = mesh.length / 100
x_min, x_max, y_min, y_max, z_min, z_max = mesh.bounds
x = np.arange(x_min, x_max, density)
y = np.arange(y_min, y_max, density)
z = np.arange(z_min, z_max, density)
x, y, z = np.meshgrid(x, y, z)
# Create unstructured grid from the structured grid
grid = pyvista.StructuredGrid(x, y, z)
ugrid = pyvista.UnstructuredGrid(grid)
# get part of the mesh within the mesh's bounding surface.
selection = ugrid.select_enclosed_points(mesh.extract_surface(),
tolerance=0.0,
check_surface=check_surface)
mask = selection.point_arrays['SelectedPoints'].view(np.bool)
# extract cells from point indices
return ugrid.extract_points(mask)
體元賦值屬性
- 簡單 Cell 單元屬性
- 節點屬性,計算每一個體元到封閉曲面的距離(隱式距離)
- 根據隱式距離屬性,抽取等值面
效果
封閉曲面:
體元化:
常值屬性體元:
隱式距離屬性生成等值面:
Code
"""
Voxelize a Surface Mesh
~~~~~~~~~~~~~~~~~~~~~~~
Create a voxel model (like legos) of a closed surface or volumetric mesh.
This example also demonstrates how to compute an implicit distance from a
bounding :class:`pyvista.PolyData` surface.
"""
# sphinx_gallery_thumbnail_number = 2
import pyvista as pv
import numpy as np
# Load a surface to voxelize
surface =pv.read("footbones.ply")
surface
###############################################################################
# cpos (list) – List of camera position, focal point, and view up.
# 相機位置,焦點(朝向),頂方向
cpos = [(7.656346967151718, -9.802071079151158, -11.021236183314311),
(0.2224512272564101, -0.4594554282112895, 0.5549738359311297),
(-0.6279216753504941, -0.7513057097368635, 0.20311105371647392)]
surface.plot(cpos=cpos, opacity=0.75)
###############################################################################
# Create a voxel model of the bounding surface
#
voxels = pv.voxelize(surface, density=surface.length/200)
p = pv.Plotter()
p.add_mesh(voxels, color=True, show_edges=True, opacity=0.5)
p.add_mesh(surface, color="lightblue", opacity=0.5)
p.show(cpos=cpos)
###############################################################################
# We could even add a scalar field to that new voxel model in case we
# wanted to create grids for modelling. In this case, let's add a scalar field
# for bone density noting:
voxels["density"] = np.full(voxels.n_cells, 3.65) # g/cc
voxels
###############################################################################
voxels.plot(scalars="density", cpos=cpos)
###############################################################################
# A constant scalar field is kind of boring, so let's get a little fancier by
# added a scalar field that varies by the distance from the bounding surface.
voxels.compute_implicit_distance(surface, inplace=True)
voxels
###############################################################################
contours = voxels.contour(6, scalars="implicit_distance")
p = pv.Plotter()
p.add_mesh(voxels, opacity=0.25, scalars="implicit_distance")
p.add_mesh(contours, opacity=0.5, scalars="implicit_distance")
p.show(cpos=cpos)