VTK Learning Thirty-seven- Voxelize a Surface Mesh

三維像素化曲面網格(網格曲面的體元化)

創建封閉曲面網格網格體的體元模型。

示例演示瞭如何從包圍盒計算隱式距離。

體元化步驟

  • 確定體元的大小。
  • 生成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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章