使用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
相关产品推荐
相关产品推荐

