python gmesh剖分step、stl模型
阿新 • • 發佈:2021-01-26
1.gmsh配置
首先需要安裝gmsh庫,但是用pip有時候會安裝不上,比如一直顯示在安裝卡死等等,可以參考這篇部落格進行本地安裝。
就是將gmsh安裝包下載下來,用7z之類的軟體解壓完後,註釋steup.py中下載gmesh軟體的程式碼,然後自己手動下載gmesh軟體的壓縮包,放在gmsh解壓目錄下再進行安裝即可。
2.剖分
首先STEP與STL檔案的模型工藝是完全不一樣的,STEP記錄了模型的各種組成部分,是用來網格剖分比較良好的格式,而STL檔案實際只是記錄了大量的三角面資訊,所以剖分時也只是對三角面進行進一步剖分,所以如果原本STL的模型就不是很好,那麼剖分後也不會好到哪裡去。
所以STEP能影響網格剖分質量的引數有兩個:
- MeshSizeFactor:網格大小因素,值越小一個模型剖分的網格也越多越小。
- MeshSizeFromCurvature:根據曲率決定網格大小,每2pi弧度剖分n個網格,簡單理解就是這個n設定的越大,曲面上剖分的網格也越多。
STL影響網格剖分質量的有一個:
- MathEval:這個不是很懂,但是測試發現無論stl檔案原本什麼樣,MathEval同一個值的時候,網格數量都基本一致,可以理解為是一個規模,越小網格越多。
import math import os import gmsh import numpy as np import time import argparse parser = argparse.ArgumentParser(description='用於網格剖分的命令列工具') parser.add_argument('path',type=str,help="指定step或stl檔案") parser.add_argument('-o','--out',type=str,default="out.npy",help="輸出指定路徑") parser.add_argument('-s','--size',type=float,default=0.05,help="step使用,網格剖分的密度,越小越密") parser.add_argument('-n','--num',type=int,default=3,help="step使用,每2pi弧度剖分n個網格") parser.add_argument('-t','--target',type=str,default="3",help="stl使用,將三角形分割至目標程度,2-3大致與剖分密度0.05相同") parser.add_argument('-g',help="是否顯示模型",action="store_true") args = parser.parse_args() path = args.path if not os.path.exists(path): raise Exception("指定檔案錯誤") start = time.time() gmsh.initialize() # step部分 if os.path.splitext(path)[1].lower() == ".step": gmsh.open(path) gmsh.option.setNumber('Mesh.MeshSizeFactor',args.size) gmsh.option.setNumber('Mesh.MeshSizeFromCurvature',args.num) # stl部分,大概就是重新構建一個模型進行剖分 elif os.path.splitext(path)[1].lower() == ".stl": gmsh.merge(path) angle = 40 forceParametrizablePatches = False includeBoundary = True curveAngle = 180 gmsh.model.mesh.classifySurfaces(angle * math.pi / 180., includeBoundary, forceParametrizablePatches, curveAngle * math.pi / 180.) gmsh.model.mesh.createGeometry() s = gmsh.model.getEntities(2) l = gmsh.model.geo.addSurfaceLoop([s[i][1] for i in range(len(s))]) gmsh.model.geo.addVolume([l]) gmsh.model.geo.synchronize() funny = False f = gmsh.model.mesh.field.add("MathEval") if funny: gmsh.model.mesh.field.setString(f, "F", "2*Sin((x+y)/5) + 3") else: # 2-3大概是step0.05的程度 gmsh.model.mesh.field.setString(f, "F", args.target) gmsh.model.mesh.field.setAsBackgroundMesh(f) else: raise Exception("不支援的格式") # 生成模型,並取得點 gmsh.model.mesh.generate(3) _, coord, _ = gmsh.model.mesh.getNodes() # 直接轉換成n行3列的形式 array = coord.reshape((-1,3)) np.save(args.out,array) # 啟動gui顯示模型 if args.g: gmsh.fltk.run() gmsh.finalize() elapsed = (time.time()-start) print("耗時:{}".format(elapsed))
順便附上matplotlib顯示模型的程式碼:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import warnings warnings.simplefilter(action="ignore", category=FutureWarning) warnings.simplefilter(action="ignore", category=UserWarning) if __name__ == '__main__': buf = np.load(r"D:\wyman\proj\echartDemo\gmeshNpy1.npy") fig = plt.figure() ax = Axes3D(fig) # print(buf) x = buf[0:,0] y = buf[0:,1] z = buf[0:,2] ax.set_zlabel("Z") ax.set_ylabel("Y") ax.set_xlabel("X") ax.scatter(x, y, z) plt.show()