My code of Gmsh as follows:
def gmsh_step_to_stl(file_address, size=3):
try:
file_name = file_address.split('\\')[-1]
size = 0.5 if size < 0.5 else size
gmsh.initialize()
gmsh.open(file_address)
# ent = gmsh.model.getEntities()
# for e in ent:
# n = gmsh.model.getEntityName(e[0], e[1])
# if n and e[0]==3:
# part_name = n.split('/')[-1]
# print(part_name,e)
gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
gmsh.option.setNumber('Mesh.MeshSizeFromCurvature', 8)
gmsh.option.setNumber('Mesh.MeshSizeMax', size)
if size/5<0.3:
gmsh.option.setNumber("Mesh.MeshSizeMin", 0.3)
else:
gmsh.option.setNumber("Mesh.MeshSizeMin", size/5)
try:
# if second_order_bool:
# gmsh.model.mesh.generate(3)
# gmsh.model.mesh.setOrder(2)
# else:
# gmsh.model.mesh.generate(3)
gmsh.model.mesh.generate(2)
except:
print(f'WARNING : {file_name} need OCC heal.')
gmsh.finalize()
gmsh.initialize()
gmsh.open(file_address)
gmsh.model.occ.healShapes()
gmsh.model.occ.synchronize()
gmsh.option.setNumber("Mesh.MeshSizeExtendFromBoundary", 0)
gmsh.option.setNumber('Mesh.MeshSizeFromCurvature', 8)
gmsh.option.setNumber('Mesh.MeshSizeMax', size)
if size/5<0.3:
gmsh.option.setNumber("Mesh.MeshSizeMin", 0.3)
else:
gmsh.option.setNumber("Mesh.MeshSizeMin", size/5)
# if second_order_bool:
# gmsh.model.mesh.generate(3)
# gmsh.model.mesh.setOrder(2)
# else:
# gmsh.model.mesh.generate(3)
gmsh.model.mesh.generate(2)
file_address = file_address.replace(".stp","_OCCHealShape.stp").replace(".step","_OCCHealShape.step")
file_address = file_address.replace(".stp",".stl").replace(".step",".stl")
gmsh.write(file_address)
print(f'{file_name} : Gmsh convert STEP to STL FINISHED.')
print(f'## Gmsh STEP to STL saved : "{file_address}"')
gmsh.finalize()
return file_address
except:
[print("\t<<<"+line+">>>") for line in traceback.format_exc().split("\n")]
print(f'ERROR : gmsh_step_to_stl in {file_address}')
gmsh.finalize()
return file_address
def gmsh_stl_to_inp(file_address, size = 3,
second_order_bool = True,
with_surface_bool = True,
remove_degenerate_element_bool = True):
def tetrahedron_volume(tetrahedron_index):
node_indexs = gmsh.model.mesh.getElement(tetrahedron_index)[1]
node0 = gmsh.model.mesh.getNode(node_indexs[0])[0]
u = gmsh.model.mesh.getNode(node_indexs[1])[0] - node0
v = gmsh.model.mesh.getNode(node_indexs[2])[0] - node0
w = gmsh.model.mesh.getNode(node_indexs[3])[0] - node0
d = u[0]*(v[1]*w[2]-v[2]*w[1])+\
u[1]*(v[2]*w[0]-v[0]*w[2])+\
u[2]*(v[0]*w[1]-v[1]*w[0])
return 1.0/(1.0*2.0*3.0) * abs(d)
try:
gmsh.initialize()
file_name = file_address.split('\\')[-1]
print(f'{file_name} : Gmsh convert stl to inp ...')
# Clear all models and merge an STL mesh that we would like to remesh (from
# the parent directory):
gmsh.clear()
gmsh.merge(file_address)
# Create a volume from all the surfaces
s = gmsh.model.getEntities(2)
l = gmsh.model.geo.addSurfaceLoop([e[1] for e in s])
gmsh.model.geo.addVolume([l])
gmsh.model.geo.synchronize()
# We specify element sizes imposed by a size field, just because we can :-)
f = gmsh.model.mesh.field.add("MathEval")
gmsh.model.mesh.field.setString(f, "F", str(int(size)))
gmsh.model.mesh.field.setAsBackgroundMesh(f)
if second_order_bool:
gmsh.model.mesh.generate(3)
gmsh.model.mesh.setOrder(2)
else:
gmsh.model.mesh.generate(3)
if not with_surface_bool:
surface_elements_index = []
for i in [2,3]+[9,10]+[16]+[20,21,22,23,24,25]:
surface_elements_index += gmsh.model.mesh.getElementsByType(i)[0].tolist()
gmsh.model.mesh.setVisibility(surface_elements_index, 0)
gmsh.plugin.setNumber('Invisible', 'DeleteElements', 1)
gmsh.plugin.run('Invisible')
if remove_degenerate_element_bool:
tetrahedron_indexs = gmsh.model.mesh.getElementsByType(11)[0]
degenerate_element_indexs = []
for index in tetrahedron_indexs:
volume = tetrahedron_volume(index)
if volume<1e-05:
degenerate_element_indexs.append(index)
print(f'{file_name.replace(".stl","")} tetrahedron element {index} is degenerated, vol= {volume}')
gmsh.model.mesh.setVisibility(degenerate_element_indexs, 0)
gmsh.plugin.setNumber('Invisible', 'DeleteElements', 1)
gmsh.plugin.run('Invisible')
print(f'Remove {len(degenerate_element_indexs)} degenerated tetrahedrons')
#gmsh.option.setNumber('Mesh.SaveGroupsOfNodes', 1)
file_address = file_address.replace("_blender","_gmsh").replace(".stl",".inp")
gmsh.write(file_address)
gmsh.finalize()
print(f'{file_name} : Gmsh convert stl to inp FINISHED.')
f = open(file_address, 'r+',encoding="utf-8")
f.write( f'*Part, name={file_name.replace("_blender","_gmsh").replace(".stl","")}\n**')
f.close()
print(f'## Gmsh stl to inp saved : "{file_address}"')
return file_address
except:
[print("\t<<<"+line+">>>") for line in traceback.format_exc().split("\n")]
## open Gmsh
#gmsh.fltk.run()
# file_address = file_address.replace("_blender","_error_gmsh").replace(".stl",".inp")
# gmsh.write(file_address)
print(f'ERROR : gmsh_stl_to_inp in {file_address}')
gmsh.finalize()
return file_address