mmgpy 将 MMG 网格自适应能力带入 Python。通过原生 PyVista accessor 生成、优化并细化 2D、3D 与表面网格。
import pyvista as pv
import mmgpy # noqa: F401 -- registers the .mmg accessor + Medit reader/writer
mesh = pv.read("input.mesh")
remeshed = mesh.mmg.remesh(hmax=0.1)
remeshed.save("output.vtk")
立即试用
无需安装,直接用 uvx 运行:
# Remesh a mesh file from the command line
uvx mmgpy input.stl -o output.mesh -hmax 0.1
# Launch the interactive UI
uvx --from "mmgpy[ui]" mmgpy-ui
安装
推荐的安装方式:
uv pip install mmgpy
这会使用 PyPI 上预编译的 wheel,已捆绑所有原生库(MMG、VTK),无需编译器。
其他安装方式
# pip
pip install mmgpy
# conda-forge
conda install -c conda-forge mmgpy
# With UI support
uv pip install "mmgpy[ui]"
# With elasticity-based displacement propagation
uv pip install "mmgpy[fem]"
PyVista accessor(mesh.mmg.remesh(...))
.mmg accessor 与 Medit .mesh / .meshb 读写器(见 工作原理)会在 pyvista >= 0.48 与 mmgpy 处于同一环境且可导入时自动激活。以下任一方式均可:
pip install mmgpy pyvista # mmgpy + latest pyvista
pip install "mmgpy[pyvista]" # same effect, version-pinned to >=0.48,<1
如果未安装 pyvista(或版本低于 0.48,该版本早于插件入口点系统),accessor 不会被注册。import mmgpy 仍可正常使用,内存中的 MmgMesh2D / MmgMesh3D / MmgMeshS API 以及 mmgpy.mmgs.remesh(...) 文件路径仍然可用。
不使用 PyVista
对于无头 / 服务器 / CI 场景,精简安装(pip install mmgpy,不含 pyvista 与 VTK)直接暴露 C 绑定网格类。从 numpy 数组构建网格,通过 item 语法附加字段,并原地重划分:
import numpy as np
from mmgpy import MmgMeshS
mesh = MmgMeshS(vertices, triangles) # numpy arrays, shape (Nv, 3) and (Nt, 3)
mesh["metric"] = sizing_array # optional: per-vertex isotropic size
mesh.remesh(hmin=0.01, hmax=0.1, hausd=0.005)
verts_out = mesh.get_vertices()
tris_out = mesh.get_triangles()
MmgMesh2D(平面三角)与 MmgMesh3D(四面体)遵循相同模式。无需 pyvista 也可通过 mmgpy.mmg2d.remesh(in_path, out_path, options={...}) 及其 mmg3d / mmgs 同类方法进行基于文件的往返操作。
使用 uv 进行项目管理
uv add mmgpy # add to project dependencies
uv tool install mmgpy # install CLI tools globally
uv tool install "mmgpy[ui]" # install CLI tools + UI globally
PyPI vs conda-forge
| PyPI (pip/uv) | conda-forge (Linux/macOS) | |
|---|---|---|
| 安装速度 | 快(预编译 wheel) | 较慢(依赖求解 + 下载) |
| 依赖 | 捆绑(自包含) | 跨包共享 |
| 磁盘占用 | 较大(重复 VTK/库) | conda 环境中较小 |
| 最适合 | 快速搭建、独立使用、CI | 共享 VTK/NumPy 的科学栈 |
追求最快搭建请使用 PyPI(uv pip install)。当已有包含 VTK、PyVista 或其他科学包的 conda 环境时,请使用 conda-forge。
工作原理
导入 mmgpy 会注册一个 PyVista 插件,为每个 pv.UnstructuredGrid 与 pv.PolyData 添加两项能力:
.mmgaccessor:暴露完整 MMG API,包括remesh、remesh_optimize、remesh_uniform、remesh_levelset、move、validate、element_qualities等。- Medit 读写器:支持
.mesh与.meshb文件(并自动将配套的.sol文件加载到point_data/cell_data)。
每次 accessor 调用都会返回全新的 PyVista dataset,因此结果可与 PyVista 其余 API(切片、绘图、IO)自由组合。
功能特性
- 多维支持:2D 三角、3D 四面体与表面网格(通过
dataset.mmg.kind从单元类型自动检测)。 - 局部细化:球体 / 盒体 / 圆柱 / 基于点的尺寸控制,在
remesh上以local_sizing=[...]传入。 - 各向异性自适应:
point_data["metric"]中的 metric tensor,包括从标量场进行最小二乘 Hessian 恢复。 - Level-set 离散化:通过
mesh.mmg.remesh_levelset(...)从隐函数提取等值面;通过set_multi_materials进行多材质拆分。 - 拉格朗日运动:通过
mesh.mmg.move(displacement, ...)移动边界并重划分,支持 Laplacian 传播器或可选的弹性后端(fedoo)。 - Required entities:通过 kwargs(
required_triangles=...)或mmg_*数据标签在重划分过程中锁定顶点、边、三角形或四面体。 - 配套
.solI/O:通过load_sol、save_sol、load_all_sols、save_all_sols处理标量 / 矢量 / 张量场。 - 验证与质量:
mesh.mmg.validate(detailed=True)返回ValidationReport;mesh.mmg.element_qualities()返回 MMG 的 in-radius 比值。 - 40+ 文件格式:原生 Medit,以及 PyVista 支持的所有格式(VTK、STL、OBJ、GMSH、MED、Abaqus 等;meshio 后端格式需安装
pyvista[io])。
使用方法
基础重划分
import pyvista as pv
import mmgpy # noqa: F401
mesh = pv.read("input.mesh")
remeshed = mesh.mmg.remesh(hmax=0.1)
q_before = mesh.mmg.element_qualities()
q_after = remeshed.mmg.element_qualities()
print(f"Quality: {q_before.mean():.2f} -> {q_after.mean():.2f}")
remeshed.save("output.vtk")
局部尺寸控制
只在指定区域细化,不影响网格其余部分:
remeshed = mesh.mmg.remesh(
hmax=0.1,
local_sizing=[
{"shape": "sphere", "center": [0.5, 0.5, 0.5], "radius": 0.2, "size": 0.01},
{"shape": "box", "bounds": [[0, 0, 0], [0.3, 0.3, 0.3]], "size": 0.02},
{"shape": "cylinder", "point1": [0, 0, 0], "point2": [0, 0, 1],
"radius": 0.1, "size": 0.01},
{"shape": "from_point", "point": [0.5, 0.5, 0.5],
"near_size": 0.01, "far_size": 0.1, "influence_radius": 0.3},
],
)
类型化选项
from mmgpy import Mmg3DOptions
opts = Mmg3DOptions(hmin=0.01, hmax=0.1, hausd=0.001)
remeshed = mesh.mmg.remesh(opts)
# Or use presets
remeshed = mesh.mmg.remesh(Mmg3DOptions.fine(hmax=0.05))
各向异性 metric
在 point_data["metric"] 上放置逐顶点 metric,remesh() 会自动读取:
import numpy as np
import mmgpy.metrics as metrics
sizes = np.full(mesh.n_points, 0.05)
mesh.point_data["metric"] = metrics.create_isotropic_metric(sizes)
remeshed = mesh.mmg.remesh()
对于解自适应重划分,可恢复 Hessian 并转换为 metric:
from mmgpy.metrics import compute_hessian, create_metric_from_hessian
hessian = compute_hessian(vertices, triangles, field)
mesh.point_data["metric"] = create_metric_from_hessian(
hessian, target_error=5e-3, hmin=3e-3, hmax=8e-2,
)
remeshed = mesh.mmg.remesh(hgrad=2.0)
Level-set 离散化
import numpy as np
levelset = (
np.linalg.norm(mesh.points - [0.5, 0.5, 0.5], axis=1) - 0.3
).reshape(-1, 1)
discretized = mesh.mmg.remesh_levelset(levelset)
拉格朗日运动
应用逐顶点位移并重划分,以维持单元质量:
import numpy as np
displacement = np.zeros((mesh.n_points, 3))
displacement[:, 0] = 0.1
moved = mesh.mmg.move(displacement, hmax=0.1)
仅传入边界值并设置 propagate=True 可填充内部。默认为 Laplacian 平滑器;传入 propagation_method="elasticity" 可使用基于 fedoo 的线弹性求解器(uv pip install "mmgpy[fem]")。
锁定实体
在重划分过程中保持特定顶点、边、三角形或四面体固定:
remeshed = mesh.mmg.remesh(
hmax=0.1,
required_triangles=np.array([3, 7, 11], dtype=np.int32),
)
或将约束附加到 dataset 上(可随 save / copy 传递):
mask = np.zeros(mesh.n_cells, dtype=bool)
mask[[3, 7, 11]] = True
mesh.cell_data["mmg_required_triangles"] = mask
remeshed = mesh.mmg.remesh(hmax=0.1)
可视化
remeshed.plot(show_edges=True)
accessor 返回的是常规 PyVista dataset,因此 PyVista 的任何操作(切片、积分、自定义绘图器)都可直接作用于结果。
命令行
MMG 可执行文件已随 wheel 捆绑:
# Auto-detect mesh type
mmg input.mesh -o output.mesh -hmax 0.1
# Or use specific commands
mmg3d input.mesh -o output.mesh -hmax 0.1
mmgs surface.stl -o refined.mesh -hausd 0.001
mmg2d domain.mesh -o refined.mesh -hmax 0.05
# Check versions
mmg --version
为兼容性考虑,也提供 _O3 后缀变体(mmg3d_O3 等)。
文档
贡献
欢迎贡献。开发环境搭建、编码规范与 PR 流程请参见 CONTRIBUTING.md。
许可证
MIT
©版权声明:本站除原创作品外的资源均收集于网络,只做学习和交流使用,版权归原作者所有,若作商业用途,请购买正版。


评论0