Truncating and re-saving a Mesh (in .stl format)

I would like to load a .stl file of triangular facets, remove most from the mesh and save as a new .stl file.

using FileIO, MeshIO
mesh = load("test.stl")
using GeometryBasics
new_mesh = Mesh(mesh[1:3])  # grab first three triangles
save("test_out.stl", new_mesh)

The code above fails with a method error. Other more detailed forms of setting up a new Mesh from the old have also met with issues deeper in GeometryBasics, so I must be missing something.

What is the accepted approach? Can someone provide a short working example of this?
Thanks!

Can you help by making the example reproducible?
What’s the method error?
It looks good in theory, but maybe just some wrongly ordered arguments or so… or a bug!

new_mesh = Mesh(mesh[1:3])

This could work, but is definitely untested :wink:

Thanks for the quick reply Simon! This code :

open("test.stl", "w") do io 
    write(io, "solid \n")
    write(io, " facet normal 1.0 1.0 1.0\n")
    write(io, "    outer loop\n")
    write(io, "        vertex 1.0 0.0 0.0\n")
    write(io, "        vertex 0.0 1.0 0.0\n")
    write(io, "        vertex 0.0 0.0 1.0\n")
    write(io, "    endloop\n")
    write(io, " endfacet\n")
    write(io, " facet normal 1.0 1.0 1.0\n")
    write(io, "    outer loop\n")
    write(io, "        vertex 2.0 0.0 0.0\n")
    write(io, "        vertex 0.0 2.0 0.0\n")
    write(io, "        vertex 0.0 0.0 2.0\n")
    write(io, "    endloop\n")
    write(io, " endfacet\n")
    write(io, " facet normal 1.0 1.0 1.0\n")
    write(io, "    outer loop\n")
    write(io, "        vertex 3.0 0.0 0.0\n")
    write(io, "        vertex 0.0 3.0 0.0\n")
    write(io, "        vertex 0.0 0.0 3.0\n")
    write(io, "    endloop\n")
    write(io, " endfacet\n")
    write(io, "endsolid \n")
end

using FileIO, MeshIO
mesh = load("test.stl")
using GeometryBasics
new_mesh = Mesh(mesh[1:2])  # grab first two triangles
save("test_out.stl", new_mesh)

will produce this error :

Error encountered while saving "test_out.stl".

Fatal error:
ERROR: LoadError: MethodError: no method matching coordinates(::Mesh{3,Float32,GeometryBasics.Ngon{3,Float32,3,PointMeta{3,Float32,Point{3,Float32},(:normals,),Tuple{Vec{3,Float32}}}},Array{GeometryBasics.Ngon{3,Float32,3,PointMeta{3,Float32,Point{3,Float32},(:normals,),Tuple{Vec{3,Float32}}}},1}})
Closest candidates are:
  coordinates(::GeometryBasics.Ngon) at /home/user/.julia/packages/GeometryBasics/csguK/src/basic_types.jl:73
  coordinates(::LineString) at /home/user/.julia/packages/GeometryBasics/csguK/src/basic_types.jl:187
  coordinates(::TupleView) at /home/user/.julia/packages/GeometryBasics/csguK/src/viewtypes.jl:39
  ...
Stacktrace:
 [1] handle_error(::MethodError, ::File{DataFormat{:STL_ASCII}}) at /home/user/.julia/packages/FileIO/2fEu2/src/error_handling.jl:82
 [2] handle_exceptions(::Array{Any,1}, ::String) at /home/user/.julia/packages/FileIO/2fEu2/src/error_handling.jl:77
 [3] save(::Formatted, ::Any; options::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/user/.julia/packages/FileIO/2fEu2/src/loadsave.jl:238
 [4] save at /home/user/.julia/packages/FileIO/2fEu2/src/loadsave.jl:217 [inlined]
 [5] #save#19 at /home/user/.julia/packages/FileIO/2fEu2/src/loadsave.jl:139 [inlined]
 [6] save(::String, ::Mesh{3,Float32,GeometryBasics.Ngon{3,Float32,3,PointMeta{3,Float32,Point{3,Float32},(:normals,),Tuple{Vec{3,Float32}}}},Array{GeometryBasics.Ngon{3,Float32,3,PointMeta{3,Float32,Point{3,Float32},(:normals,),Tuple{Vec{3,Float32}}}},1}}) at /home/user/.julia/packages/FileIO/2fEu2/src/loadsave.jl:139
 [7] top-level scope at /home/user/mesh_save_error.jl:36
 [8] include(::String) at ./client.jl:439
 [9] top-level scope at REPL[1]:1
in expression starting at /home/user/mesh_save_error.jl:36

on Julia v1.4.1 with recent packages :

...
  [5789e2e9] FileIO v1.4.4
...
  [5c1252a2] GeometryBasics v0.3.3
...
  [7269a6da] MeshIO v0.4.3
...