meshio
meshio is a very powerful and widely used tool for reading, writing and converting mesh data. According to the homepage, meshio currently supports the following formats:
Abaqus (.inp),
ANSYS msh (.msh),
AVS-UCD (.avs),
CGNS (.cgns),
DOLFIN XML (.xml),
Exodus (.e, .exo),
FLAC3D (.f3grid),
H5M (.h5m),
Kratos/MDPA (.mdpa) ,
Medit (.mesh, .meshb),
MED/Salome (.med),
Nastran (bulk data, .bdf, .fem, .nas),
Netgen (.vol, .vol.gz),
Neuroglancer precomputed format, Gmsh ( format versions 2.2, 4.0, and 4.1, .msh),
OBJ (.obj),
OFF (.off),
PERMAS (.post, .post.gz, .dato, .dato.gz),
PLY (.ply),
STL (.stl),
Tecplot .dat,
TetGen . TetGen .node/.ele,
SVG (2D output only) (.svg),
SU2 (.su2),
UGRID (.ugrid),
VTK (.vtk),
VTU (.vtu),
WKT (TIN) (.wkt),
XDMF (.xdmf, .xmf).
The common properties of the meshio object are points, cells and cells_dict.
-
points is an array containing the coordinates of all vertices.
-
cells is a list where each element is a meshio CellBlock containing mainly dim, type and data (an array of node indices for that cell type) properties. This is useful for situations where both cell type and node indexes need to be handled, especially when traversing all cells.
-
cells_dict is similar to cells, but is stored as a dictionary. The key is the cell type and the value is an array of node indices for that cell type. Ideal for situations where cell data needs to be accessed or manipulated by cell type, facilitating separate processing of specific types of cells.
Installation method:
pip install meshio
Multi-type mesh reading case:
import meshio
mesh = meshio.read('test.inp')
print(f'Number of vertices:{mesh.points.shape[0]}')
for cell in mesh.cells: print(f'Type:{cell.cells.shape[0]}')
print(f'Type:{cell.type}, Number:{cell.data.shape[0]}')
# Number of vertices:25653
# Type:hexahedron20, Number:1900
# Type:hexahedron, Number:1900
# Type:tetra10, Number:8709
# Type:tetra, Number:8701
Github homepage: GitHub - nschloe/meshio: 🕸 input/output for many mesh formats
pyvista
pyvista is a very powerful visualization library that also includes mesh reading, saving, and displaying (currently there seems to be no support for meshing, only the voxelization function pv.Voxelize). pyvista has a built-in mesh IO tool in the form of meshio, which can be read using pyvista.read_meshio and pyvista.save_meshio. pyvista.read_meshio and pyvista.save_meshio can be used to read and export meshes.
The grid information read by pyvista can be retrieved from the cells_dict property. pyvista’s cells_dict is basically the same format as meshio’s cells_dict, but the cell types are stored in the form of type numbers, which are described in the official website, and some of the relationships are as follows:
TRIANGLE = <CellType.TRIANGLE: 5> # linear triangle cell
QUAD = <CellType.QUAD: 9> # Linear quadrilateral cell
TETRA = <CellType.TETRA: 10> # Linear tetrahedral cell
VOXEL = <CellType.VOXEL: 11> # Linear voxel cell
HEXAHEDRON = <CellType.HEXAHEDRON: 12> # Linear hexahedral cell
QUADRATIC_TRIANGLE = <CellType.QUADRATIC_TRIANGLE: 22> # Quadratic triangle cell
QUADRATIC_QUAD = <CellType.QUADRATIC_QUAD: 23> # Quadratic quadrilateral cell
QUADRATIC_TETRA = <CellType.QUADRATIC_TETRA: 24> # Quadratic tetrahedral cell
QUADRATIC_HEXAHEDRON = <CellType.QUADRATIC_HEXAHEDRON: 25> # Quadratic hexahedral cell
Installation method (Python >= 3.9):
pip install pyvista
Read, write and visualize cases:
import pyvista as pv
# Read inp
grid = pv.read_meshio('test.inp')
# Display grid information
for typeID,cell in grid.cells_dict.items()::
print(f'Type:{typeID}, Number:{cell.shape[0]}')
# Type:10, Number:8701
# Type:12, Number:1900
# Type:24, Number:8709
# Type:25, Number:1900
grid.plot(show_edges=True)
# save inp
pv.save_meshio('out.inp', grid)
(There seems to be some problems with the display of the second-order cells, the left and right are actually second-order tetrahedral and second-order hexahedral cells, and it looks like the second-order cells are broken up to be displayed as first-order cells)
Github homepage: GitHub - pyvista/pyvista: 3D plotting and mesh analysis through a streamlined interface for the Visualization Toolkit (VTK)
Official example (works great): Examples — PyVista 0.44.2 documentation
Cell type numbering comparison table: pyvista.CellType — PyVista 0.44.2 documentation
pygalmesh
pygalmesh encapsulates CGAL’s 2D and 3D mesh generation functionality, supporting the creation of body meshes, periodic body meshes, surface meshes, and more.
Installation: Windows may have problems when installing directly from pip, refer to 如何在Windows上安装pygalmesh (依赖于本征)?-腾讯云开发者社区-腾讯云 and use conda to install:
conda install -c conda-forge pygalmesh
Small problem: after installing pygalmesh, importing pyvista may give an error, ImportError: initialization failed, reinstall pyvista, pip install pyvista --force-reinstall.
Example: Read stl to delimit tetrahedral mesh and use pyvista to visualize the mesh (you need to manually adjust min_facet_angle, max_radius_surface_delaunay_ball, max_facet_distance, max_circumradius_edge_ ratio, etc. to get the ideal mesh). ratio to get the desired mesh)
import pygalmesh
import pyvista as pv
mesh = pygalmesh.generate_volume_mesh_from_surface_mesh(
“test.stl”,
min_facet_angle=25.0,
max_radius_surface_delaunay_ball=1,
max_facet_distance=0.5,
max_circumradius_edge_ratio=1.3,
verbose=False,
) # meshio object
mesh_pv = pv.wrap(mesh) # Wrap to pyvista object using wrap() function
# Split the visual mesh
crinkled = mesh_pv.clip(normal=(1, 0, 0), crinkle=True) # profile
p = pv.Plotter()
p.add_mesh(crinkled, color='w', show_edges=True)
stl_model = pv.read(“test.stl”) # original model as reference
p.add_mesh(stl_model, color='w', opacity=0.2)
p.add_mesh(stl_model.extract_feature_edges(), color='r')
p.show()
Github homepage: GitHub - meshpro/pygalmesh: 🕸 A Python interface to CGAL's meshing tools
pygmsh/gmsh
gmsh is a very famous open source meshing tool which supports many meshing algorithms. pygmsh wraps the python API of gmsh, which makes it more convenient to use (well, it feels that the steps are still tedious).
gmsh/pygmsh generally uses gmsh.option.setNumber(“xxx.xxx”, x) to control the meshing, such as
- gmsh.option.setNumber(“Mesh.ElementOrder”, 1) means to divide the first-order cells.
- gmsh.option.setNumber(“Mesh.Algorithm3D”, 10) means use HXT algorithm to divide 3D mesh.
- gmsh.option.setNumber(“General.NumThreads”, threads) means set the number of threads (the actual speedup does not seem to be obvious)
Some of the currently supported algorithms:
- 2D meshing algorithms (1: MeshAdapt, 2: Automatic, 3: Initial mesh only, 5: Delaunay, 6: Frontal-Delaunay, 7: BAMG, 8: Frontal-Delaunay for Quads, 9: Packing of Parallelograms, 11: Quasi-structured Quad)
- 3D Mesh Algorithms (1: Delaunay, 2: New Delaunay, 3: Initial mesh only, 4: Frontal, 5: Frontal Delaunay, 6: Frontal Hex, 7: MMG3D, 9: R-tree, 10: HXT) - currently only HXT supports parallelism.
Installation
pip install pygmsh
Example: Read stl and partition linear or quadratic tetrahedral cells, specify global mesh size, use pyvista visualization.
import gmsh
from pygmsh.helpers import extract_to_meshio
import pyvista as pv
def generate_tetra(model, mesh_size, mesh_order=1, threads=2):
# 初始化
gmsh.initialize()
gmsh.option.setNumber("General.Terminal", 0) # 控制台信息输出 0:不输出 1:输出
gmsh.option.setNumber("General.NumThreads", threads) # 多线程 (加速效果不明显)
gmsh.clear()
if mesh_order == 1:
cell_type = pv.CellType.TETRA
elif mesh_order == 2:
cell_type = pv.CellType.QUADRATIC_TETRA
else:
raise ValueError('mesh_order must be 1 or 2')
# 加载STL模型
gmsh.merge(model)
# 识别面
gmsh.model.mesh.classifySurfaces(40 * 3.1415926 / 180.)
# 创建体
gmsh.model.mesh.createGeometry()
s = gmsh.model.getEntities(2)
l = gmsh.model.geo.addSurfaceLoop([e[1] for e in s])
gmsh.model.geo.addVolume([l])
gmsh.model.geo.synchronize()
# 利用背景网格的场数据指定全局网格尺寸
f = gmsh.model.mesh.field.add("MathEval")
gmsh.model.mesh.field.setString(f, "F", str(mesh_size))
gmsh.model.mesh.field.setAsBackgroundMesh(f)
# 指定网格阶次
gmsh.option.setNumber("Mesh.ElementOrder", mesh_order)
# 2D 网格划分算法 (1: MeshAdapt, 2: Automatic, 3: Initial mesh only, 5: Delaunay, 6: Frontal-Delaunay,
# 7: BAMG, 8: Frontal-Delaunay for Quads, 9: Packing of Parallelograms, 11: Quasi-structured Quad)
gmsh.option.setNumber("Mesh.Algorithm", 2)
# 3D 网格划分算法 (1: Delaunay, 2: New Delaunay, 3: Initial mesh only, 4: Frontal, 5: Frontal Delaunay,
# 6: Frontal Hex, 7: MMG3D, 9: R-tree, 10: HXT) - 目前只有HXT支持并行
gmsh.option.setNumber("Mesh.Algorithm3D", 10)
# 划分网格
gmsh.model.mesh.generate(3)
# 转pyvista UnstructuredGrid
mesh = pv.wrap(extract_to_meshio())
gmsh.clear()
gmsh.finalize()
# 提取四面体 (完整的网格包含点、面、体单元)
mesh = mesh.extract_cells_by_type(cell_type)
# 二次四面体节点编号顺序修正
if cell_type == pv.CellType.QUADRATIC_TETRA:
mesh.cells = mesh.cells.reshape(-1, 11)[:, [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 9]].ravel()
mesh.cells_dict[24] = mesh.cells_dict[24][:, [0, 1, 2, 3, 4, 5, 6, 7, 9, 8]]
return mesh
model = 'test.stl'
mesh = generate_tetra(model, mesh_size=2, mesh_order=1)
# 剖分可视化网格
crinkled = mesh.clip(normal=(1, 0, 0), crinkle=True) # 剖面
p = pv.Plotter()
p.add_mesh(crinkled, show_edges=True)
stl_model = pv.read(model) # 原始模型作为参照
p.add_mesh(stl_model, color='w', opacity=0.2)
p.add_mesh(stl_model.extract_feature_edges(), color='r')
p.remove_scalar_bar()
p.show()
Description of parameter control: Gmsh 4.13.1
Selection of meshing algorithm: Gmsh 4.13.1 20right%20unstructured%20algorithm,-Gmsh%20provides%20a
Grid division directly from pv.PolyData object can be found here: GitHub - pyvista/scikit-gmsh: Scikit for Gmsh to generate 3D finite element mesh
tetgen
tetgen is a high-quality tetrahedral meshing tool, developed by Dr. Sihang, which can generate tetrahedral meshes from point sets or boundary surfaces in 3D space. tetgen is well linked with pyvista, and tetgen can directly encapsulate pv.PolyData into a tetgen object and divide the mesh, and then extract the UnstructuredGrid object and visualize it. PolyData into a tetgen object and divide it into grids, after dividing the grid, you can also extract the UnstructuredGrid object from pyvista and visualize it directly, so the code is more concise overall.
Install:
pip install tetgen
Example: Read stl and divide tetrahedral cells, use pyvista to visualize.
import tetgen
import pyvista as pv
sphere = pv.read('test.stl')
tet = tetgen.TetGen(sphere)
tet.tetrahedralize(order=1, mindihedral=20, minratio=1.2)
grid = tet.grid
# Split the visualization grid
crinkled = grid.clip(normal=(1, 0, 0), crinkle=True) # profile
p = pv.Plotter()
p.add_mesh(crinkled, show_edges=True)
stl_model = pv.read('test.stl') # original model as reference
p.add_mesh(stl_model, color='w', opacity=0.2)
p.add_mesh(stl_model.extract_feature_edges(), color='r')
p.remove_scalar_bar()
p.show()
Official website: WIAS Software
Explanation of the meaning of parameters: API Reference — tetgen 0.6.5 documentation
Others
In addition to the above tools, there are many open source meshing tools available for Python, such as Netgen (tetrahedral meshing), MeshPy (tetrahedral meshing), and SALOME (simulation software that provides the meshing tool SMESH).
More open source/commercial meshing tools can be found at: Mesh Generation and Grid Generation: Software