polytex.mesh

polytex.mesh.decimation

polytex.mesh.decimation.adjacent_from_edge(cells, edges, cell_idx=None, return_dict={})[source]

Returns the adjacent cells of the edges with the index of the edge as key.

Parameters
cells: (n, 4) array

cell list of the mesh expressed in node connectivity

edges: (m, 2) array

edge list to be collapsed

cell_idx: (n,) array

cell index. If None, it will be generated as np.arange(n). (default: None)

Returns
return_dict: dictionary

a dictionary of adjacent cells with key as the edge

polytex.mesh.decimation.adjacent_from_edge_parallel(cells, edge_collapse, n_cores=4)[source]

Get the adjacent cells of the edges to be collapsed.

Parameters
cells: (n, 4) array

cell list of the mesh expressed in node connectivity

edge_collapse: (m, 2) array

edge list to be collapsed

n_cores: int

number of cores to use for multiprocessing (default: 4)

Returns
return_dict: a dictionary of adjacent cells with key as the edge
polytex.mesh.decimation.construct_tetra_vtk(points, cells, save=False, filename='tetra.vtk', path='./', binary=True)[source]

Construct a UnstructuredGrid tetrahedral mesh from vertices and connectivity.

Parameters
points: (n, 3) array

vertices

cells: (m, 4) array

connectivity

save: bool

whether to save the mesh

filename: str

if save=True, provide a file name

path: str

if save=True, provide a path to save the mesh

binary: bool

whether to save the mesh in binary format

Returns
grid: pyvista.UnstructuredGrid

UnstructuredGrid tetrahedral mesh

polytex.mesh.decimation.edge_collapse_pipeline(mesh, surf, iteration=1, threshold=2, n_cores=4)[source]

Edge collapse pipeline. Edges containing boundary and independent points will not be collapsed.

Parameters
points: (n, 3) array

vertices

cells: (m, 4) array

connectivity

surf: a surface mesh of interfaces between materials (subdomains)
iteration: int

number of iterations for edge collapse

threshold: float

threshold for edge collapse

Returns
new_points: (n’, 3) array

vertices after edge collapse

new_cells: (m’, 4) array

connectivity after edge collapse

polytex.mesh.decimation.get_boundary_points(mesh)[source]

Returns a list of boundary points from this mesh.

Parameters
mesh: pyvista mesh object
boundary_points: A list of boundary points
Returns
pts_boundary_idx: NumPy array

A numpy array in the shape of [n_boundary_points] containing the index of boundary points.

polytex.mesh.decimation.get_cells(mesh)[source]

Returns a list of the cells from this mesh with mixed cell types. This properly unpacks the VTK cells array.(safe but now so fast)

Parameters
mesh: pyvista unstructured mesh object

A pyvista mesh object.

Returns
cells: list

A list of cells. The first element of each cell is the number of nodes in the cell.

polytex.mesh.decimation.get_collapse_direction(edge_indicator)[source]

Get the direction of edge collapse. The direction is determined by the indicator function of the two vertices.

Parameters
edge_indicator: (n, 2) array

indicator function of the two vertices of an edge

Returns
collapse_indicator: (n,) array

direction of edge collapse. possible values are “forward”, “backward”, “bilateral”, and “neither”

polytex.mesh.decimation.get_edge_collapse(points, edges, surf_dist, edge_indicator, threshold=1.2)[source]

Get the edge collapse list.

Parameters
points: (n, 3) array

vertex list

edges: (n’, 2) array

edge list

surf_dist: (n,) array

surface distance of the vertices to interfaces

edge_indicator: (n’, 2) array

indicator function of the two vertices of an edge. possible values are 0, 1, and 2 for each containing boundary, independent, and free vertices respectively.

threshold: float
# TODO: explain this parameter

threshold for the surface distance to filter out the edges to be collapsed. The edges to be collapsed are the ones with edge length less than the threshold and surface distance of the two vertices are both greater than the threshold.

Returns
edge_collapse: (n’’, 2) array

edge collapse list

collapse_indicator: (n’’, 2) array

indicator function of the two vertices of an edge to be collapsed. possible values are “forward”, “backward”, “bilateral”, and “neither”

polytex.mesh.decimation.get_edge_length(points, edges)[source]

Returns the length of an edge given node position and the edge.

Parameters
points: A numpy array in the shape of [n_points, 3]

The points array containing node position

edges: A numpy array in the shape of [n_edges, 2]

The edges array containing node connectivity

Returns
edge_length: A numpy array in the shape of [n_edges]
polytex.mesh.decimation.get_edges_from_tetra(cells)[source]

Given cells of tetrahedral mesh, return all the edges.

Parameters
cells: A numpy array in the shape of [n_cells, 4]

The cells array containing node connectivity.

Returns
edges_for_cell: A list of edges

The edges are sorted so that the first node is always smaller than the second. This is to ensure easy searching neighbors. The edges of a cell can be retrieved by edges[cell_index]

edges: A numpy array in the shape of [n_edges, 2]

The edges array containing node connectivity.

polytex.mesh.decimation.get_maximal_independent_node(edges)[source]

Get the maximal independent node set from the edge list.

Parameters
edges: (n, 2) array

edge list

Returns
pts_independent: (m,) array

maximal independent node set

polytex.mesh.decimation.get_surf_dist(surf, points)[source]

Get the distance from a point to the surface mesh by finding the closest point on the surface mesh with KDTree.

Parameters
surf: A pyvista triangular mesh object
points: (n, 3) array

points to be measured

Returns
surf_dist: (n,) array of float

distance from the points to the surface mesh

idx: (n,) array of int

index of the closest point on the surface mesh

polytex.mesh.decimation.get_vertex_indicator(n_points, pts_boundary_idx, pts_independent, edges)[source]
Get the indicator function of the vertices:

0 for boundary vertices, 1 for independent vertices, 2 for free vertices.

The indicator function is used to determine the nodes to be collapsed. The nodes to be collapsed are the ones with indicator function equal to 2 while 0 and 1 are fixed.

Parameters
n_points: int

number of vertices

pts_boundary_idx: (m,) array

indices of boundary points

pts_independent: (n,) array

indices of independent points

edges: (n’, 2) array

edge list

Returns
vertex_indicator: (n_points,) array

indicator function of the vertices

edge_indicator: (n’, 2) array

indicator function of the two vertices of an edge

polytex.mesh.decimation.renumber_points(pts_del, cells, proc_num, return_dict={})[source]

Renumber the points in cells after some points are deleted.

Parameters
pts_del: A list of points to be deleted
cells: A numpy array in the shape of [n_cells, 4]

The cells array containing node connectivity

proc_num: Int, the number of process for multiprocessing.
return_dict: A dictionary to store the result of each process.
Returns
num_diff: A numpy array in the shape of [n_cells, 4]

The difference between the original node index and the new node index

polytex.mesh.decimation.tetra_edge_collapse(edges, collapse_indicator, edge_adjacent, points, cells, n_cores)[source]

Collapse edges of tetrahedral mesh.

Parameters
edges: (n, 2) array
collapse_indicator: (n,) array

direction of edge collapse. possible values are “forward”, “backward”, “bilateral”, and “neither”

edge_adjacent: dict

adjacent cells of each edge

points: (n, 3) array

node positions

cells: (n, 4) array

node connectivity

Returns
points: (n, 3) array

node positions after edge collapse

cells: (n, 4) array

node connectivity after edge collapse

polytex.mesh.features

polytex.mesh.features.voxelize(mesh, density=None, check_surface=True, density_type='cell_number', contained_cells=False)[source]

Voxelize surface mesh to UnstructuredGrid. The bounding box of the voxelized mesh possibly smaller than the bounding box of the surface mesh when cell_size type of density is used.

Parameters
meshpyvista.PolyData

Surface mesh to be voxelized.

densityfloat, int, or list of float or int

Uniform size of the voxels when single float passed. A list of densities along x,y,z directions. Defaults to 1/100th of the mesh length for cell_size (float or list) flavor density and 50 cells in each direction for cell_number density (int or list).

check_surfacebool

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.

density_typestr

Specify the type of density to use. Options are ‘cell_number’ or ‘cell_size’. When ‘cell_number’ is used, the density is the number of cells in each direction. When ‘cell_size’ is used, the density is the size of cells in each direction.

contained_cellsbool

If True, only cells that fully are contained in the surface mesh will be selected. If False, extract the cells that contain at least one of the extracted points.

Returns
voxpyvista.UnstructuredGrid

Voxelized unstructured grid of the original mesh.

ugridpyvista.UnstructuredGrid

The backgrond mesh for voxelization

Examples:
Create an equal density voxelized mesh using cell_size density.
>>> import pyvista as pv
    ..
>>> from pyvista import examples
    ..
>>> import polytex.mesh as ms
    ..
>>> mesh = pv.PolyData(examples.load_uniform().points)
    ..
>>> vox, _ = ms.voxelize(mesh, density=0.5, density_type='cell_size')
    ..
>>> vox.plot(show_edges = True)
    ..
Create a voxelized mesh with specified number of elements in x, y, and z dimensions.
>>> mesh = pv.PolyData(examples.load_uniform().points)
    ..
>>> vox, _ = ms.voxelize(mesh, density=[50, 50, 50], density_type='cell_number', contained_cells=False)
    ..
>>> vox.plot(show_edges = True)
    ..

polytex.mesh.from_image

To check the use of this module, please refer to the example “mesh_from_image.py”

in the test folder of PolyTex.

polytex.mesh.from_image.get_vcut_plane(surf_mesh, direction='x', skip=1)[source]

Get the vertical cut plane of the surf mesh in the direction of x, y, or z axis through (boundary) cutting edge extraction.

Parameters
surf_meshpyvista.PolyData

The surface mesh.

directionstr, optional

The direction of the vertical cut plane, by default ‘x’. The direction can be ‘x’, ‘y’, or ‘z’.

skipint, optional

The number of cut planes to skip. The unit is slice in the direction of the vertical cut plane, by default 1.

Returns
vcut_planenumpy.ndarray

The vertical cut planes of the surf mesh.

trajectorynumpy.ndarray

The trajectory (centroid) of the vertical cut plane calculated by averaging the coordinates of the points on the cutting edge.

polytex.mesh.from_image.im_to_ugrid(im)[source]

Convert image or image sequence to an unstructured grid.

Parameters
imimage object

The image sequence stored as a single tif file.

Returns
ugridpyvista.UnstructuredGrid

The unstructured grid discretized from the image with voxels.

im_dimnumpy.ndarray

The image dimension.

Examples

>>> import polytex as ptx
>>> im = ptx.example("image")
>>> mesh, mesh_dim = ptx.mesh.im_to_ugrid(im)
polytex.mesh.from_image.mesh_extract(ugrid, threshold, pointdata='Tiff Scalars', type='foreground')[source]

Extract part of the mesh from the unstructured grid according to the value of point data.

Parameters
ugridpyvista.UnstructuredGrid

The unstructured grid discretized from the image with voxels.

thresholdfloat

The threshold value of the point data specified by the parameter ‘pointdata’.

pointdatastr, optional

The point data name, by default ‘Tiff Scalars’.

typestr, optional

The type of the extracted mesh, by default “forground”. The type can be “forground” or “background”. If the type is “foreground”, the extracted mesh is where the point data is greater than the threshold value. If the type is “background”, the extracted mesh is where the point data is less than the threshold value.

Returns
subset_finalpyvista.UnstructuredGrid

The extracted volume mesh.

surfpyvista.PolyData

The extracted surface mesh.

polytex.mesh.from_image.mesh_separation(mesh, plot=False)[source]

Separate the mesh object into different regions according to the connectivity of the mesh. It may not work for mesh with multiple regions that are connected.

Parameters
meshpyvista.UnstructuredGrid

The mesh object.

Returns
mesh_dictdict

The dictionary of the separated mesh objects. The key is the region number and the value is the mesh object.

polytex.mesh.from_image.slice_plot(vcut_planes, skip=10, marker='o', marker_size=0.1, direction='z', dpi=300, save=False, save_path=None)[source]

Plot the vertical cut planes.

Parameters
vcut_planesnumpy.ndarray

The vertical cut planes of the surf mesh stored in a numpy array. The shape of the array is (n_points, 3).

skipint, optional

The number of cut planes to skip when plotting the vertical cut planes, by default 10.

markerstr, optional

The marker type, by default ‘o’.

marker_sizefloat, optional

The marker size, by default 0.1.

dpiint, optional

The resolution of the figure, by default 300.

savebool, optional

Whether to save the figure, by default False.

save_pathstr, optional

The path to save the figure, by default None. If save is True, the save_path must be specified.

Returns
None

polytex.mesh.mesh

polytex.mesh.mesh.background_mesh(bbox, voxel_size=None)[source]

Generate a voxel background mesh.

Parameters
bbox: bounding box of the background mesh specified through a numpy array

contains the minimum and maximum coordinates of the bounding box [xmin, xmax, ymin, ymax, zmin, zmax]

voxel_size: voxel size of the background mesh, type: None, float, or numpy.ndarray

if None, the voxel size is set to the 1/20 of the diagonal length of the bounding box;

if float, the voxel size is set to the float value in x, y, z directions;

if list, set, or tuple of size 3, the voxel size is set to the values for the x-, y- and z- directions.

Returns
gridpyvista mesh object (UnstructuredGrid)
mesh_shapetuple

shape of the mesh

polytex.mesh.mesh.construct_tetra_vtk(points, cells, save=None, binary=True)[source]

Construct a UnstructuredGrid tetrahedral mesh from vertices and connectivity.

Parameters
points: (n, 3) array

vertices

cells: (m, 4) array

connectivity

save: str

The path and file name of the vtk file to be saved (“./tetra.vtk”). If None, the vtk file will not be saved.

binary: bool

whether to save the mesh in binary format

Returns
grid: pyvista.UnstructuredGrid

UnstructuredGrid tetrahedral mesh

polytex.mesh.mesh.find_cells_within_bounds(mesh, bounds)[source]

Find the index of cells in this mesh within bounds.

Parameters
mesh: pyvista mesh
bounds: type: iterable(float)

list of 6 values, [xmin, xmax, ymin, ymax, zmin, zmax]

Returns
type: numpy.ndarray

array of cell indices within bounds.

Examples

>> mesh = pv.PolyData(np.random.rand(10, 3)) >> indices = find_cells_within_bounds(mesh, [0, 1, 0, 1, 0, 1])

polytex.mesh.mesh.intersection_detect(label_set_dict)[source]

Find the intersection of fiber tows from implicit surface.

Parameters
label_set_dict: dictioanry

dictionary of the label sets of the fiber tows (key: yarn indices, value: sparse matrix of cell queries)

Returns
type: dictionary of the indices of intersected cell

key: yarn indices 1_yarn indices 2, value: sparse matrix of cell indices

polytex.mesh.mesh.isInbBox(bbox, point)[source]

Determine if point is within a bounding box (bbox) that parallel to the principle axes of global Cartesian coordinate.

Parameters
bbox: list

bounding box, [xmin, xmax, ymin, ymax, zmin, zmax].

point: list

[x, y, z]

Returns
True or False
polytex.mesh.mesh.label_mask(mesh_background, mesh_tri, tolerance=1e-07, check_surface=False)[source]

Store the label of each fiber tow for intersection detection.

Parameters
mesh_background: pyvista.UnstructuredGrid

background mesh

mesh_tri: pyvista.PolyData

tubular mesh of the fiber tows

tolerance: float

tolerance for the enclosed point detection

Returns
mask: type: numpy.ndarray (bool)

mask of the background mesh, True for the cells that are within the bounds of the tubular mesh

label_yarn: type: numpy.ndarray (int) (1D)
polytex.mesh.mesh.mesh_correction(cells, points, theta_res)[source]

Close the ends of the tubular mesh with triangles.

Parameters
cells: list

list of cells

points: numpy.ndarray

vertices of the tubular mesh

theta_res: int

number of points in the radial direction of the tubular mesh. The first and the last vertex of each radial direction point list are repeated. However, they are considered as two different points when considering theta resolution (theta_res).

Returns
points: numpy.ndarray

vertices of the tubular mesh

cells: list

list of cells

polytex.mesh.mesh.structured_cylinder_vertices(a, b, h, theta_res=5, h_res=5)[source]

Generate points on an ellipse.

Parameters
afloat

semi-major axis

bfloat

semi-minor axis

hfloat

height

theta_resint, optional

number of points, by default 5.

h_res: int, optional

number of points. by default 5.

Returns
points: numpy.ndarray

vertices on the ellipse surface (x, y, z).

polytex.mesh.mesh.to_meshio_data(mesh, theta_res, correction=True)[source]

Convert PyVista flavor data structure to meshio.

Parameters
mesh: PyVista.DataSet

Any PyVista mesh/spatial data type.

theta_res:

number of points in the radial direction

correction: boolean

if True, tubular mesh will be closed at the ends with triangles.

Returns
points: numpy.ndarray

vertices of the tubular mesh

cells: list

list of cells

point_data: numpy.ndarray

point data

cell_data: numpy.ndarray

cell data

polytex.mesh.mesh.tubular_mesh_generator(theta_res, h_res, vertices, plot=True)[source]

Generate a tubular mesh.

Parameters
theta_res: int

number of points

h_res: int

number of points

vertices: numpy.ndarray

vertices of the tubular mesh, shape (n, 3) The vertices of the tubular mesh are sorted in the radial direction first, then in the vertical direction. The first vertex is repeated at the end of each radial direction point list.

Returns
meshpoints on the tubular mesh