# Exporting a surface

**URL:** <https://discourse.julialang.org/t/exporting-a-surface/38040>\
**Category:** General Usage\
**Tags:** visualization\
**Created:** [April 22, 2020, 7:01pm UTC](https://discourse.julialang.org/t/exporting-a-surface/38040 "2020-04-22T19:01:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bigorneau](https://avatars.discourse-cdn.com/v4/letter/b/4491bb/32.png) [@Bigorneau](https://discourse.julialang.org/u/Bigorneau)\
**Post date:** [April 22, 2020, 7:01pm UTC](https://discourse.julialang.org/t/exporting-a-surface/38040/1 "2020-04-22T19:01:20Z")

</div>

Hi, I could not find any resources online about exporting a surface as a mesh in Julia. To be more precise, suppose at the end of some computation I have a surface only known as the three matrices `X,Y,Z`.  
I can visualize it in `Makie` using `scene = surface(X,Y,Z)` and save the plot as an image. However, I would like to obtain the actual mesh corresponding to the surface.  
Initially, I thought that it would be contained somewhere in `scene.plots[2]`? But I cannot figure out where though.

In short, is there a way in Julia to create the mesh of a surface (or retrieve the one build by Makie) and save it via `FileIO/MeshIO` as (for instance) .obj?

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [April 22, 2020, 8:41pm UTC](https://discourse.julialang.org/t/exporting-a-surface/38040/2 "2020-04-22T20:41:16Z")

</div>

Makie’s OpenGL backend uses an optimized shader, that doesn’t actually create a mesh, but renders the surface directly from the matrix.  
I was lazy in WGLMakie and just create a mesh:  
[https://github.com/JuliaPlots/WGLMakie.jl/blob/master/src/imagelike.jl#L67](https://github.com/JuliaPlots/WGLMakie.jl/blob/master/src/imagelike.jl#L67)  
Without all the WGLMakie shenanigans, this comes out as:

```julia
px, py, pz = plot[1], plot[2], plot[3]
x, y, z = px[], py[], pz[] # get the values

positions = vec(map(CartesianIndices(z)) do i
    GeometryBasics.Point{3, Float32}(
        get_dim(x, i, 1, size(z)),
        get_dim(y, i, 2, size(z)),
        z[i]
    )
end)

faces = decompose(GLTriangleFace, Rect2D(0f0, 0f0, 1f0, 1f0), size(z))

normals = WGLMakie.surface_normals(x, y, z)

vertices = GeometryBasics.meta(positions; normals=normals)

mesh = GeometryBasics.Mesh(vertices, faces)
using FileIO, MeshIO

# and save it in your favorite format
FileIO.save("mesh.obj", mesh)

```

---

<div class="post-metadata">

**Author:** ![Bigorneau](https://avatars.discourse-cdn.com/v4/letter/b/4491bb/32.png) [@Bigorneau](https://discourse.julialang.org/u/Bigorneau)\
**Post date:** [April 22, 2020, 9:09pm UTC](https://discourse.julialang.org/t/exporting-a-surface/38040/3 "2020-04-22T21:09:44Z")

</div>

Thanks for the complete answer 🙂  
Unfortunately, the last command does not work, I get the error

> Error encountered while saving “mesh.obj”.  
> Fatal error:  
> ERROR: MethodError: no method matching save(::Stream{DataFormat{:OBJ},IOStream}, ::GeometryBasics.Mesh{3,Float32,GeometryBasics.Ngon{3,Float32,3,PointMeta{3,Float32,Point{3,Float32},(:normals,),Tuple{Vec{3,Float32}}}},FaceView{GeometryBasics.Ngon{3,Float32,3,PointMeta{3,Float32,Point{3,Float32},(:normals,),Tuple{Vec{3,Float32}}}}}})  
> Closest candidates are:  
> save(::Stream{DataFormat{:OFF},IOtype} where IOtype\<:IO, ::AbstractArray{Element,1} where Element) at /Users/olivier/.julia/packages/MeshIO/zr3db/src/io/off.jl:5  
> save(::Stream{DataFormat{:PLY\_BINARY},IOtype} where IOtype\<:IO, ::AbstractArray{Element,1} where Element) at /Users/olivier/.julia/packages/MeshIO/zr3db/src/io/ply.jl:2  
> save(::Stream{DataFormat{:PLY\_ASCII},IOtype} where IOtype\<:IO, ::AbstractArray{Element,1} where Element) at /Users/olivier/.julia/packages/MeshIO/zr3db/src/io/ply.jl:29

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [April 22, 2020, 9:11pm UTC](https://discourse.julialang.org/t/exporting-a-surface/38040/4 "2020-04-22T21:11:50Z")

</div>

I haven’t run the code, but my first guess is, that you need to update meshio

---

<div class="post-metadata">

**Author:** ![Bigorneau](https://avatars.discourse-cdn.com/v4/letter/b/4491bb/32.png) [@Bigorneau](https://discourse.julialang.org/u/Bigorneau)\
**Post date:** [April 22, 2020, 9:21pm UTC](https://discourse.julialang.org/t/exporting-a-surface/38040/5 "2020-04-22T21:21:34Z")

</div>

I ran `]up`, re-executed the code but still no luck (btw I use Julia 1.4.1).  
The code you provided work for .ply though 🙂
