
本文详细讲解如何利用 gmsh python api,基于给定的顶点坐标与三角面片索引(如 obj 格式),构建闭合几何体并生成高质量网格。重点涵盖点、线、环、面、体的逐级建模流程,并提供可直接运行的完整代码示例。
本文详细讲解如何利用 gmsh python api,基于给定的顶点坐标与三角面片索引(如 obj 格式),构建闭合几何体并生成高质量网格。重点涵盖点、线、环、面、体的逐级建模流程,并提供可直接运行的完整代码示例。
在 Gmsh 中,不能直接将面索引数组“一键”转化为几何面——它要求显式构造几何拓扑层级:点 → 边(线)→ 环(闭合边界)→ 面 → 体。这是因为 Gmsh 是一个基于边界表示(B-rep)的几何建模与网格生成器,其核心逻辑依赖于明确的几何关联关系,而非单纯的离散面片集合。
以下为完整实现步骤与代码:
✅ 步骤说明与关键要点
- 顶点编号从 1 开始:Gmsh 内部所有实体 ID 均从 1 起计(Python 索引从 0,需 +1 映射);
-
每条边由两个顶点定义:对每个三角形面
[i, j, k],需创建三条无向边(自动去重); -
每个面需用一个
Line Loop包裹其三条边:顺序影响法向方向(逆时针为正向); -
必须调用
gmsh.model.occ.synchronize():同步 OCC 几何内核,使后续操作可见; -
若目标是体积网格(如
.msh用于 FEM):需将所有面组合成Surface Loop,再addVolume;否则仅导出表面网格(.msh2D)。
✅ 完整可运行代码
import gmsh
import numpy as np
gmsh.initialize()
# 定义顶点(8 个立方体角点)
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
])
# 三角面片(注意:OBJ 索引通常从 1,此处已按 0-based 给出;Gmsh 要求 1-based 实体 ID)
faces = np.array([
[2, 1, 0], # 对应顶点索引 2→1→0 → Gmsh 点 ID: 3,2,1
[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 点 ID(从 1 开始)
point_ids = []
for v in vertices:
pid = gmsh.model.occ.addPoint(v[0], v[1], v[2])
point_ids.append(pid)
# Step 2: 构建唯一边(避免重复添加同一条边)
edge_set = set()
line_ids = {} # (min_id, max_id) → line_id
next_line_id = 1
def get_edge_id(i, j):
a, b = min(i, j), max(i, j)
if (a, b) not in line_ids:
lid = gmsh.model.occ.addLine(point_ids[a], point_ids[b])
line_ids[(a, b)] = lid
return line_ids[(a, b)]
# Step 3: 为每个三角面创建 Line Loop 和 Surface
surface_ids = []
for face in faces:
i, j, k = face[0], face[1], face[2]
# 创建三条边(确保顺序一致以维持面朝向)
l1 = get_edge_id(i, j)
l2 = get_edge_id(j, k)
l3 = get_edge_id(k, i)
# 构建环:注意 Gmsh 要求环中边方向首尾相接(逆时针绕面法向)
loop_id = gmsh.model.occ.addCurveLoop([l1, l2, l3])
surf_id = gmsh.model.occ.addSurfaceFilling([loop_id])
surface_ids.append(surf_id)
# Step 4: 同步 OCC 几何内核(必需!)
gmsh.model.occ.synchronize()
# ✅ 可选:若需生成体网格(3D volume),执行以下操作:
if surface_ids:
# 创建 Surface Loop(包围封闭体积)
surf_loop_id = gmsh.model.occ.addSurfaceLoop(surface_ids)
# 创建体积
vol_id = gmsh.model.occ.addVolume([surf_loop_id])
# 重新同步以包含体
gmsh.model.occ.synchronize()
# ✅ 设置物理组(便于后处理识别)
gmsh.model.addPhysicalGroup(2, surface_ids, name="Surface") # 2D 物理组(面)
if 'vol_id' in locals():
gmsh.model.addPhysicalGroup(3, [vol_id], name="Volume") # 3D 物理组(体)
# ✅ 生成网格(默认 2D 网格;若含体则自动生成 3D 四面体)
gmsh.model.mesh.generate(3) # 3 表示生成 3D 单元(tetrahedra)
# ✅ 导出为 MSH 文件(支持 ParaView/GMSH GUI 查看)
gmsh.write("custom_mesh.msh")
# ✅ 启动 GUI(可选,调试时启用)
# gmsh.fltk.run()
gmsh.finalize()⚠️ 注意事项
-
面方向一致性至关重要:若多个面法向不一致,
addSurfaceLoop可能失败或生成非流形几何。建议预处理面片,统一朝向(如用法向平均+点积校验); -
非流形输入会报错:若面片不封闭(如缺面、悬边),
addSurfaceLoop将无法构建有效体,此时应先检查faces是否构成封闭网格(可用trimesh或open3d验证); -
性能提示:对于大规模网格(>10⁴ 面),建议关闭 GUI 并禁用
fltk.run();批量建模时可调用gmsh.option.setNumber("Geometry.OCCBooleanPreserveNumbering", 1)提升稳定性; -
替代方案:若仅需表面三角网格(无几何建模需求),可考虑
meshio+pyvista直接写入.stl/.ply;但涉及后续有限元分析(如scikit-fem或scipy求解),Gmsh 的参数化网格控制(尺寸场、边界层等)仍具不可替代优势。
通过以上流程,你即可将任意三角网格数据(OBJ、STL 解析结果等)可靠导入 Gmsh,并为高保真数值仿真奠定几何基础。

















