After long hours of searching for an answer I thought it might be better to ask the community.

The problem I have is that I need to convert STL files to mesh files. I know that I therefore need to add a volume to the surfaces from the STL file.

When I do it manually in gmsh

Modules->Geometry->Elementary entities->Add->Volume->klick on the surface-mesh->pressing 'e'->pressing 'q')

that works very well.

Since I have to do this process for multiple hundreds of .stl-files I can't do it manually with the gui. Therefore I created a script which uses command line arguments to do the above and avoids opening the gui. Up until now I have:

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

When I run this I get the error, that the surface 1 is unknown. But when I inspect the STL file manually in the gui and do nothing but opening this STL file it shows me that the surface has id 1. So why is the surface in the script-version unknown? Is there maybe a better way to add a volume to a surface-mesh with gmsh?

P.S.: I can't use a .geo-file for the commands since I am using a shell script to iterate through my files (with variables in the file names). Using a .geo-file would not allow me to use the variables anymore.

P.P.S.: Here is the script I'm now using:


# amount of files to be processed

# amount of slices per timestep to be processed

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

# save current working directory to a variable

# 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
if [[ ! -d STL_Remeshed/ ]]; then
    mkdir STL_Remeshed

for ((a = 0; a < $sliceCount; a++))
	for ((i = 0; i < $endVal; i++))
        # 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

2 Answers 2


I am not entirely sure what is going wrong in your version of the command-line approach. However, I think it works on my test STL file (with gmsh 4.0.7) with the following line:

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

It might be also easier to use the full path of the input file to avoid gmsh "running around".

My guess would be that opening an STL (your command-line) vs merging it (my proposition) has a different effect.

  • $\begingroup$ I had finally time to try this. The command doesn't result in errors. But when I inspect the resulting file in the gmsh gui, there is no volume added. So it seems, that the command line doesn't do anything. $\endgroup$
    – A.M.
    May 21, 2019 at 15:03
  • $\begingroup$ I also added the script that I use to the above posting. The line with mmg3d and the command after that won't work because the first command with gmsh is the problem. But maybe the error that I get from mmg is helpful: currently I get "Check that your mesh contains tetrahedra." I think this is because of the missing volume. $\endgroup$
    – A.M.
    May 21, 2019 at 15:13
  • 1
    $\begingroup$ @A.M. have you tried adding some physical ids? The default GMSH behaviour is to only output tagged entities. $\endgroup$
    – origimbo
    May 21, 2019 at 16:16
  • $\begingroup$ @origimbo Yes, I've tried that. To no effect. There is still no volume added when I manually inspect the resulting .msh-file in the gmsh gui. $\endgroup$
    – A.M.
    May 22, 2019 at 11:27

I solved my problem now. Despite initially not wanting to do that, I now generate .geo-files in my script. I do it with

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"

The first line generates .geo-files for each of my .stl-files individually. After that I can just run the .geo-file and get what I initially wanted.

I think the problem was that in the original script I posted above all commands were written in one single line:

/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 seems to only execute the first of the three commands (the merge command) and ignores the rest. I also tried to write all the commands in the .geo-file in one line (so the echo command from above just without the linebreaks). That also lead to .msh-files without the added volume. The same happend when I wrote everything manually in one line directly in the .geo-file with explicit linebreaks (\n between the commands). It seems that the command parser from gmsh parses line-wise only until it encounters the first semicolon. Everything after that gets ignored.

Thanks again to all who helped me here.

P.S.: Since I didn't write it anywhere else: I used Gmsh 4.3.0

  • $\begingroup$ Maybe the problem with the single line command is some inadequate/archaic 128 character limit, it's 191 characters long... $\endgroup$ Sep 8, 2020 at 6:47
  • $\begingroup$ @TobiasKienzler Maybe that's the case. Unfortunately, I can't test it because I'm working elsewhere and do not have the resources to test that. But wouldn't it be a problem, when the string isn't properly closed? The second double quote comes after the 128 character limit. I think that would cause a different error or no output at all. $\endgroup$
    – A.M.
    Sep 9, 2020 at 11:35
  • $\begingroup$ Ah true, and shell limits are around 1e5. Then maybe it's a bug (or design decission) that gmsh only performs the first command passed via -string $\endgroup$ Sep 9, 2020 at 11:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.