
本文详解如何在 python 中调用 gmsh api,基于给定的顶点坐标与三角形面索引(如 obj 格式),构建闭合几何体并生成高质量体积网格。
本文详解如何在 python 中调用 gmsh api,基于给定的顶点坐标与三角形面索引(如 obj 格式),构建闭合几何体并生成高质量体积网格。
Gmsh 并不支持直接“导入面”或“一键生成曲面”,其建模遵循严格的几何构造层级:点 → 线(边)→ 环(线环)→ 面 → 面环 → 体。因此,要将 vertices 和 faces 转为可网格化的实体,必须显式构造每条边、每个三角形面及其包围的封闭体。
以下为完整可运行代码(已适配 Gmsh 4.11+ Python API):
import gmsh
import numpy as np
gmsh.initialize()
# 定义顶点(注意:Gmsh 索引从 1 开始)
vertices = np.array([
[-0.5, -0.5, -0.5], # 0
[0.5, -0.5, -0.5], # 1
[-0.5, 0.5, -0.5], # 2
[0.5, 0.5, -0.5], # 3
[-0.5, -0.5, 0.5], # 4
[0.5, -0.5, 0.5], # 5
[-0.5, 0.5, 0.5], # 6
[0.5, 0.5, 0.5] # 7
])
faces = np.array([
[2, 1, 0], # 对应顶点索引 2→1→0(即 [-0.5,0.5,-0.5] → [0.5,-0.5,-0.5] → [-0.5,-0.5,-0.5])
[1, 2, 3],
[4, 2, 0],
[2, 4, 6],
[1, 4, 0],
[4, 1, 5],
[6, 5, 7],
[5, 6, 4],
[3, 6, 7],
[6, 3, 2],
[5, 3, 7],
[3, 5, 1]
])
# Step 1: 添加所有顶点,保存其 Gmsh 标签(从 1 开始)
point_tags = []
for v in vertices:
tag = gmsh.model.occ.addPoint(v[0], v[1], v[2])
point_tags.append(tag)
# Step 2: 为每个三角形面添加三条边(线),避免重复创建相同边
line_tags = {}
def get_or_add_line(p1, p2):
key = tuple(sorted([p1, p2]))
if key not in line_tags:
tag = gmsh.model.occ.addLine(p1, p2)
line_tags[key] = tag
return line_tags[key]
# Step 3: 为每个面创建线环(3 条有向边构成的闭合环)
surface_loops = []
for face in faces:
# 将 OBJ 风格的 0-based 索引转为 Gmsh 的 1-based point tag
pts = [point_tags[i] for i in face]
# 创建三条边(按面顶点顺序定向)
l1 = get_or_add_line(pts[0], pts[1])
l2 = get_or_add_line(pts[1], pts[2])
l3 = get_or_add_line(pts[2], pts[0])
# 构造线环(注意:Gmsh 要求逆时针绕行以保证外法向朝外)
loop_tag = gmsh.model.occ.addCurveLoop([l1, l2, l3])
# 创建平面三角形面
surf_tag = gmsh.model.occ.addSurfaceFilling([loop_tag])
surface_loops.append(surf_tag)
# Step 4: 合并所有面为一个表面壳(shell),再封装为实体(volume)
# ⚠️ 关键:必须确保所有面构成**水密(watertight)封闭体**,否则 addVolume() 失败
shell_tag = gmsh.model.occ.addShell(surface_loops)
volume_tag = gmsh.model.occ.addVolume([shell_tag])
# Step 5: 同步 OCC 几何内核,使拓扑生效
gmsh.model.occ.synchronize()
# Step 6(可选但推荐):设置物理组以便后续识别和控制网格
gmsh.model.addPhysicalGroup(3, [volume_tag], name="Body")
gmsh.model.addPhysicalGroup(2, surface_loops, name="Surface")
# Step 7: 生成网格(自动选择合适算法,对闭合体默认生成四面体)
gmsh.model.mesh.generate(3)
# 输出 MSH 文件(兼容 Gmsh 4+,含几何与网格)
gmsh.write("custom_mesh.msh")
# 可视化(仅限交互模式;脚本中可注释)
# gmsh.fltk.run()
gmsh.finalize()✅ 关键注意事项:
-
顶点顺序决定面朝向:Gmsh 要求三角形面的顶点按逆时针顺序(从外部观察)排列,否则法向错误,导致体构建失败。若输入面方向混乱,需先做一致性检查(如使用
trimesh或open3d修复法向)。 -
避免重复边:手动缓存
line_tags可显著提升性能并防止几何冲突。 -
必须调用
synchronize():OCC 操作是延迟执行的,不调用则后续addVolume无法识别面。 -
水密性要求严格:任何缝隙、重叠或非流形边都会导致
addVolume返回 0 或崩溃。建议先用gmsh.model.occ.removeAllDuplicates()和gmsh.model.occ.synchronize()清理。 -
OBJ 面索引处理:示例中
faces使用的是 0-based 索引,需映射到point_tags列表;若原始数据为 1-based(如部分 OBJ),请先减 1。
该流程不仅适用于立方体,也适用于任意由三角面片组成的封闭网格(如 STL/OBJ 导入场景)。掌握此模式后,即可将任意表面重建结果无缝接入 Gmsh 进行有限元网格划分与仿真前处理。

















