You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pygmsh从2D截面放样生成3D网格时,创建曲面遇报错求助

用pygmsh实现两个Shapely多边形的放样(Loft)生成3D网格

问题根源:重复创建Surface

你之前调用geom.add_surface(poly1.curve_loop)报错,是因为geom.add_polygon()已经自动创建了对应的Surface和Curve Loop。poly1本身就是一个Surface对象,不需要再手动用Curve Loop创建Surface,重复操作导致了边界数量异常的错误。

正确实现方式:使用add_loft函数

pygmsh提供了add_loft()函数,专门用于在多个截面之间创建放样(扫掠)的3D几何体,完全匹配你的需求。以下是具体步骤和代码示例:

1. 基础示例:两个正方形截面的放样

假设你有两个Shapely正方形Polygon,分别位于z=0和z=d的平面:

import pygmsh
from shapely.geometry import Polygon

# 定义两个正方形截面(Shapely Polygon)
polygon1 = Polygon([(0,0), (1,0), (1,1), (0,1)])
polygon2 = Polygon([(0.2,0.2), (0.8,0.2), (0.8,0.8), (0.2,0.8)])
depth = 2.0  # 放样深度

with pygmsh.geo.Geometry() as geom:
    # 处理Shapely坐标:移除最后一个重复的闭合点
    coords1 = polygon1.exterior.coords[:-1]
    coords2 = polygon2.exterior.coords[:-1]
    
    # 创建第一个截面的Surface(z=0平面)
    surf1 = geom.add_polygon(coords1, z=0.0)
    # 创建第二个截面的Surface(z=depth平面)
    surf2 = geom.add_polygon(coords2, z=depth)
    
    # 执行放样,生成3D Volume
    loft = geom.add_loft([surf1, surf2])
    
    # 生成网格
    mesh = geom.generate_mesh()

# 可以保存网格或进行后续处理
mesh.write("lofted_mesh.vtk")

2. 带孔洞的截面处理

如果你的多边形包含孔洞,需要分别添加外边界和孔洞的Curve Loop,再创建带孔洞的Surface,之后再进行放样:

import pygmsh
from shapely.geometry import Polygon

# 定义带孔洞的正方形截面
polygon1 = Polygon(
    [(0,0), (2,0), (2,2), (0,2)],
    holes=[[(0.5,0.5), (1.5,0.5), (1.5,1.5), (0.5,1.5)]]
)
polygon2 = Polygon(
    [(0.3,0.3), (1.7,0.3), (1.7,1.7), (0.3,1.7)],
    holes=[[(0.7,0.7), (1.3,0.7), (1.3,1.3), (0.7,1.3)]]
)
depth = 1.5

with pygmsh.geo.Geometry() as geom:
    # 处理第一个截面:外边界+孔洞
    outer_coords1 = polygon1.exterior.coords[:-1]
    outer_loop1 = geom.add_curve_loop(geom.add_polygon(outer_coords1, z=0.0).curves)
    
    hole_loops1 = []
    for hole in polygon1.interiors:
        hole_coords = hole.coords[:-1]
        hole_loop = geom.add_curve_loop(geom.add_polygon(hole_coords, z=0.0).curves)
        hole_loops1.append(hole_loop)
    
    # 创建带孔洞的Surface
    surf1 = geom.add_plane_surface(outer_loop1, holes=hole_loops1)
    
    # 处理第二个截面(z=depth平面)
    outer_coords2 = polygon2.exterior.coords[:-1]
    outer_loop2 = geom.add_curve_loop(geom.add_polygon(outer_coords2, z=depth).curves)
    
    hole_loops2 = []
    for hole in polygon2.interiors:
        hole_coords = hole.coords[:-1]
        hole_loop = geom.add_curve_loop(geom.add_polygon(hole_coords, z=depth).curves)
        hole_loops2.append(hole_loop)
    
    surf2 = geom.add_plane_surface(outer_loop2, holes=hole_loops2)
    
    # 放样生成3D Volume
    loft = geom.add_loft([surf1, surf2])
    
    # 生成网格
    mesh = geom.generate_mesh()
    mesh.write("lofted_mesh_with_holes.vtk")

关键注意事项

  • Shapely的coords会包含闭合的重复点(最后一个点等于第一个点),需要切片[:-1]移除,否则pygmsh会生成多余的边。
  • 放样时,两个截面的孔洞数量必须对应,否则会生成无效几何体。
  • add_loft会自动连接两个截面的对应边,生成封闭的3D体,后续可以直接生成网格。

内容的提问来源于stack exchange,提问作者anuv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:57:39