使用 gmsh 从 stl 文件创建 3D Mesh

计算科学 网格生成 gmsh
2021-12-06 02:52:17

经过长时间寻找答案后,我认为向社区询问可能会更好。

我遇到的问题是我需要将 STL 文件转换为网格文件。我知道我因此需要从 STL 文件向曲面添加一个体积。

当我在 gmsh 中手动操作时

模块->几何->基本实体->添加->体积->在表面网格上单击->按'e'->按'q')

效果很好。

由于我必须为数百个 .stl 文件执行此过程,因此我无法使用 gui 手动执行此过程。因此,我创建了一个脚本,它使用命令行参数来执行上述操作并避免打开 gui。到目前为止,我有:

gmsh input.stl -string "Surface Loop(2)={1}; Volume(3)={2};" -3 -o output.msh

当我运行它时,我得到了错误,即表面 1 是未知的。但是当我在 gui 中手动检查 STL 文件并且除了打开这个 STL 文件什么都不做时,它显示表面的 id 为 1。那么为什么脚本版本中的表面是未知的?是否有更好的方法可以使用 gmsh 向表面网格添加体积?

PS:我不能使用.geo-file 来执行命令,因为我正在使用 shell 脚本来遍历我的文件(文件名中有变量)。使用.geo-file 将不再允许我使用这些变量。

PPS:这是我现在使用的脚本:

#!/bin/bash

# amount of files to be processed
endVal=400

# amount of slices per timestep to be processed
sliceCount=2

# create output folders for .msh and remeshed .stl files, if necessary
cd Slices/

# save current working directory to a variable
cwd=$(pwd)

# folder structure should be:
# /                     the Slices folder, created by the user or another script
#   MSH/                after running the script it should contain the meshes created by gmsh
#       Remeshed/       after running the script it should contain the remeshed meshes generated by mmg
#   STL/                should contain the .stl files
#   STL_Remeshed/       after running it should contain the remeshed meshes converted back to the .stl format by gmsh
if [[ ! -d MSH/ ]]; then
    mkdir -p MSH/Remeshed
fi
if [[ ! -d STL_Remeshed/ ]]; then
    mkdir STL_Remeshed
fi

for ((a = 0; a < $sliceCount; a++))
do
	for ((i = 0; i < $endVal; i++))
    do
        # convert .stl to .msh
        /Volumes/User/Gmsh.app/Contents/MacOS/gmsh $cwd/STL/slice$a.$i.stl -string "Merge '$cwd/STL/slice$a.$i.stl'; Surface Loop(2)={1}; Volume(3)={2};" -3 -o $cwd/MSH/slice$a.$i.msh -format "msh22"

        # remesh
        /Volumes/User/mmg/mmg3d_debug -in $cwd/MSH/slice$a.$i.msh -out $cwd/MSH/Remeshed/slice$a.$i.msh -hausd 0.00005

        # convert remeshed .msh to .stl
        /Volumes/User/Gmsh.app/Contents/MacOS/gmsh $cwd/MSH/Remeshed/slice$a.$i.msh -0 -o $cwd/STL_Remeshed/slice$a.$i.stl
    done
done
2个回答

我不完全确定您的命令行方法版本出了什么问题。但是,我认为它适用于我的测试 STL 文件(使用 gmsh 4.0.7),其中包含以下行:

gmsh -string "Merge 'input.stl'; Surface Loop(2)={1}; Volume(3)={2};" -3 -o output.msh

使用输入文件的完整路径来避免gmsh“跑来跑去”也可能更容易。

我的猜测是打开 STL(您的命令行)与合并它(我的提议)具有不同的效果。

我现在解决了我的问题。尽管最初不想这样做,但我现在在我的脚本中生成 .geo 文件。我这样做

echo "Merge '$cwd/STL/slice$a.$i.stl';\nSurface Loop(1) = {1};\nVolume(1) = {1};" >$cwd/GEO/slice$a.$i.geo
        # convert .stl to .msh
        /Volumes/User/Gmsh.app/Contents/MacOS/gmsh $cwd/GEO/slice$a.$i.geo -3 -o $cwd/MSH/slice$a.$i.msh -format "msh22"

第一行分别为我的每个 .stl 文件生成 .geo 文件。之后,我可以运行 .geo 文件并获得我最初想要的内容。

我认为问题在于,在我上面发布的原始脚本中,所有命令都写在一行中:

/Volumes/User/Gmsh.app/Contents/MacOS/gmsh $cwd/STL/slice$a.$i.stl -string "Merge '$cwd/STL/slice$a.$i.stl'; Surface Loop(2)={1}; Volume(3)={2};" -3 -o $cwd/MSH/slice$a.$i.msh -format "msh22"

Gmsh 似乎只执行三个命令中的第一个(合并命令)而忽略其余的。我还尝试将 .geo 文件中的所有命令写在一行中(因此上面的 echo 命令没有换行符)。这也会导致 .msh 文件没有添加卷。当我直接在 .geo 文件的一行中手动编写所有内容时,同样发生了同样的情况,并带有明确的换行符(命令之间的 \n)。似乎 gmsh 中的命令解析器仅在遇到第一个分号之前才按行解析。之后的一切都会被忽略。

再次感谢所有在这里帮助我的人。

PS:由于我没有在其他任何地方写过:我使用了 Gmsh 4.3.0