Accelerating the pace of engineering and science

# export::stl

Export STL data

### Use only in the MuPAD Notebook Interface.

This functionality does not run in MATLAB.

## Syntax

```export::stl(filename, [x, y, z], u = umin .. umax, v = vmin .. vmax, options)
export::stl(n, [x, y, z], u = umin .. umax, v = vmin .. vmax, options)
export::stl(filename, object1, <object2, …>, options)
export::stl(n, object1, <object2, …>, options)
```

## Description

export::stl is used to create a triangulation of a parametrized surface and write the triangulation data in STL format to an external file.

STL files contain triangulation data of 3D surfaces. Each triangle is stored as a unit normal and three vertices. The normal and the vertices are specified by three coordinates each, so there is a total of 12 numbers stored for each triangle. Read the "Background" section of this help page for further details.

If the surface is closed, it is regarded as the boundary of a 3D solid. The normals of the triangles written into the STL file should point from the inside of the body to the outside.

 Note:   Note that the direction of the normals that export::stl writes into the STL file depend on the parametrization x(u, v), y(u, v), z(u, v)!

If p1 = (x(u, v), y(u, v), z(u, v)), p2 = (x(u + du, v), y(u + du, v), z(u + du, v)), p3 = (x(u, v + dv), y(u, v + dv), z(u, v + dv)) are the corners of a triangle, the normal associated with this triangle is the cross product of the side p2 - p1 times the side p3 - p2. The routine export::stl chooses neighboring values of the surface parameters with du = (`u_{max}` - `u_{min}`)/(n_u - 1) and dv = (`v_{max}` - `v_{min}`)/(n_v - 1), respectively.

 Note:   Thus, if your parametrization is such that the cross product of the vectors p2 - p1 and p3 - p2 does not point to the outside of your body, you just need to let one of the parameters (u, say) run from umax to umin instead of from umin to umax. Just replace your callexport::stl(filename, [x,y,z], u = `u_{min}` .. `u_{max}`, v = `v_{min}` .. `v_{max}`)byexport::stl(filename, [x,y,z], u = `u_{max}` .. `u_{min}`, v = `v_{min}` .. `v_{max}`).

Up to the irrelevant ordering in the STL file, the triangles generated by these calls are the same apart from the direction of the normal associated with each triangle.

If the file is specified by a character string, the corresponding file is opened and closed, automatically.

As an alternative to specifying the file by a string, the user may open the file herself via fopen in Write mode and pass the file descriptor returned by fopen to export::stl. If binary data are to be written to the file, make sure that it is opened with the Raw, i.e., call fopen(filename, Write, Raw).

 Note:   Note that export::stl does not close the file automatically if it is specified by a file descriptor. It remains open after export::stl has finished its job. The file needs to be closed explicitly by the user using fclose.

If the file is specified by a character string, the name may correspond to an absolute or a relative path name. In particular, the environment variable WRITEPATH is taken into account. The details on the help page of fopen hold for export::stl, too.

 Note:   With the option Append, the file is first opened for reading and, after reading of the data in the file, opened for writing. If no absolute pathname is used to specify the file, make sure that the environment variables READPATH and WRITEPATH point to the same folder. Alternatively, it is a good idea to place the file in the same folder as the MuPAD® notebook which you are currently using. If this notebook is saved on the disk of your computer, the absolute path is available as the environment variable NOTEBOOKPATH. Thus, specifying a file named "myfile.stl", say, by the absolute path name NOTEBOOKPATH."myfile.stl" ensures that the file is found in the same folder as your notebook.

Text files generated with the option Text or the equivalent Ascii can be opened and read with any text editor. However, binary files generated with the option Bin or the equivalent options Binary or Raw are faster to create and to process.

The file generated by export::stl can be read and visualized in MuPAD using the plot primitive plot::SurfaceSTL.

If the file name given ends in ".gz", export::stl writes a compressed file which can be read by any program supporting gzip compression.

## Environment Interactions

The function is sensitive to the environment variable DIGITS which determines the numerical working precision. The current value of DIGITS determines the number of significant decimal digits with which the STL data are written to the specified file. (This holds for text files. In binary STL files all numerical values have a precision of about 7 decimal digits.) For the internal computation of the data by MuPAD, the value of DIGITS is temporarily increased by 10 to minimize round-off effects.

The STL data generated by export::stl are written to the specified file.

## Examples

### Example 1

We generate a sphere given by the following parametrization:

```x:= cos(u)*sin(v):
y:= sin(u)*sin(v):
z:= cos(v):```

We call export::stl to generate the STL data and write them into a file named "sphere.stl". The file is to be generated in the same directory as the current MuPAD notebook that we are using. Hence, we specify an absolute path name for the file using the path of the current notebook. If this notebook was saved to the disk of your computer, this path is available in the environment variable NOTEBOOKPATH:

```filename:= NOTEBOOKPATH."sphere.stl":
export::stl(filename, [x, y, z], u = 0 .. 2*PI, v = 0 .. PI, Text)```

Since the file was created in Text format, it can be opened with any text editor. It should look like this:

```solid MuPADtoSTL1
facet normal -0.06540070486 -0.008610166138 -0.9978219344
outer loop
vertex 100.0 100.0 300.0
vertex 112.607862 103.3782664 298.7167292
vertex 113.0526192 100.0 298.7167292
endloop
endfacet
facet normal -0.1950260058 -0.02567566076 -0.9804619409
outer loop
vertex 113.0526192 100.0 298.7167292
vertex 112.607862 103.3782664 298.7167292
vertex 125.0 106.6987298 294.8888739
endloop
endfacet

...

```

We reimport the STL data and visualize the surface using plot::SurfaceSTL:

`plot(plot::SurfaceSTL(filename, MeshVisible))`

We reduce the number of significant output digits to a reasonable size. Further, we specify a mesh size and request a specific output box:

```DIGITS:= 7:
export::stl(filename, [x, y, z], u = 0..2*PI, v = 0..PI,
Mesh = [10, 10],
OutputBox = [-100..100, -100..100, -100..100],
Text):```

The file now should look like this:

```solid MuPADtoSTL2
facet normal -0.1733024 -0.06307691 -0.9828467
outer loop
vertex -3.10912 0.000000002143114 100.0
vertex 24.32249 22.66816 93.96926
vertex 32.7003 0.000000002143114 93.96926
endloop
endfacet

...

```

We visualize the new content of the file:

`plot(plot::SurfaceSTL(filename, MeshVisible))`

`delete x, y, z, filename, DIGITS:`

### Example 2

We specify the parametrization of the surface by a mixture of expressions and procedures:

```x:= piecewise([0.1 < u < 0.9, u*cos(v)], [Otherwise, 0]):
y:= (u, v) -> piecewise([0.1 < u < 0.9, u*sin(v)], [Otherwise, 0]):
z:= (u, v) -> if u <= 0.1 then exp(-0.1)
elif u < 0.9 then exp(-u)
else exp(-0.9)
end_if:```

This is the surface that we wish to export to STL:

```plot(plot::Surface([x, y, z], u = 0..1, v = 0..2*PI,
Mesh = [100, 36])):```

We assume that there is no external file "sample.stl". We create it by opening it in Write mode in the same directory as the current MuPAD notebook that we are using. Hence, we specify an absolute path name for the file using the path of the current notebook. If this notebook was saved to the disk drive of your computer, this path is available in the environment variable NOTEBOOKPATH. The file descriptor n returned by fopen is passed to export::stl:

```filename:= NOTEBOOKPATH."sample.stl":
DIGITS:= 7:
export::stl(filename, [x, y, z], u = 0..1, v = 0..2*PI,
Mesh = [30, 36])```

We reimport the STL data and visualize the surface using plot::SurfaceSTL:

`plot(plot::SurfaceSTL(filename, MeshVisible))`

We can append a further surface to the file using the option Append:

```export::stl(filename, [x, y, -z], u = 0..1, v = 0..2*PI,
Mesh = [30, 36],
OutputBox = [0..100, 0..100, -100..0],
Append)```

We visualize the new content of the file via plot::SurfaceSTL:

`plot(plot::SurfaceSTL(filename, MeshVisible))`

`delete x, y, z, filename, DIGITS:`

### Example 3

We wish to create a closed surface consisting of a "bowl" with a "lid".

```bowl:= [u*cos(v), u*sin(v), u^2], u = 0 .. 1, v = 0 .. 2*PI:
lid:=  [u*cos(v), u*sin(v),  1 ], u = 0 .. 1, v = 0 .. 2*PI:```
```filename:= NOTEBOOKPATH."sample.stl":
DIGITS:= 7:
export::stl(filename, bowl, Mesh = [30, 36]):
export::stl(filename, lid, Mesh = [30, 36], Append):
plot(plot::SurfaceSTL(filename), Scaling = Constrained):```

`delete filename, DIGITS:`

### Example 4

We demonstrate the options Scaling = Constrained and Scaling = Unconstrained. With Scaling = Constrained, the coordinates given by the parametrization x, y, z are scaled by the same factor to fit the surface into the output box. Here, we create a sphere of radius 1. The output box is not a cube: the range for the z coordinate is notably larger than for x and y. Nevertheless, the sphere stays a sphere when using Scaling = Constrained. However, the output box is not completely filled by the sphere:

```x:= cos(u)*sin(v):
y:= sin(u)*sin(v):
z:= cos(v):
DIGITS:= 7:
filename:= NOTEBOOKPATH."sphere.stl":
export::stl(filename, [x, y, z], u = 0 .. 2*PI, v = 0 .. PI,
OutputBox = [-1 .. 1, -1 .. 1, -3 .. 3],
Scaling = Constrained):

plot(plot::SurfaceSTL(filename,
Scaling = Constrained,
MeshVisible))```

With Scaling = Unconstrained, the sphere is deformed to an ellipsoid filling the output box:

```export::stl(filename, [x, y, z], u = 0..2*PI, v = 0..PI,
OutputBox = [-1..1, -1..1, -3..3],
Scaling = Unconstrained):

plot(plot::SurfaceSTL(filename,
Scaling = Constrained,
MeshVisible))```

`delete x, y, z, filename, DIGITS:`

## Parameters

 filename A file name: a non-empty character string n A file descriptor provided by fopen: a positive integer object1, object2, … 3D graphical objects of the plot library x, y, z The coordinate functions: arithmetical expressions or piecewise objects depending on the surface parameters u and v. Alternatively, procedures that accept 2 input parameters u, v and return a numerical value when the input parameters are numerical. u The first surface parameter: an identifier or an indexed identifier. umin .. umax The range for the parameter u: umin, umax must be numerical real values. v The second surface parameter: an identifier or an indexed identifier. vmin .. vmax The range for the parameter v: vmin, vmax must be numerical real values.

## Options

Mesh

Option, specified as Mesh = [nu, nv]

Sets the mesh size: the integer nu determines, how many equidistant points in the u direction are used to sample the parametrization x, y, z numerically. Correspondingly, the integer nv determines, how many equidistant points in the v direction are used. Thus, a regular mesh of (nu - 1) (nv - 1) rectangles is used. Each rectangle is split into 2 triangles, resulting in a triangulation consisting of 2 (nu - 1) (nv - 1) triangles. The default is Mesh = [25, 25].

OutputBox

Option, specified as OutputBox = [xmin .. xmax, ymin .. ymax, zmin .. zmax]

By default, the coordinates of the mesh points defining the STL object are written into the file as provided by the parametrization of the surface. Thus, if several objects are written into the file via the option Append, the position of the objects in space is transparent and can be controlled by the user via a suitable parametrization. However, many devices such as Rapid Prototyping tools with which the STL file shall be processed, impose severe restrictions on the data in the STL file. E.g., the original STL specification requires that the x, y, z coordinates of the mesh points are positive. Many devices require that the coordinates must lie in a prescribed range (between 0 and 100, say). The option OutputBox provides a simple mean to shift and scale the coordinates given by the parametrization to a prescribed range.

The option OutputBox = [ xmin.. xmax, ymin.. ymax, zmin.. zmax] sets the output box defined by numerical values xmin, …, zmax. The mathematical coordinates x(u, v), y(u, v), z(u, v) with u, v ranging from umin to umax and from vmin to vmax, respectively, are shifted and scaled such that the output coordinates written to the STL file range between the values xmin and xmax, ymin and ymax, zmin and zmax.

 Note:   If several objects are written to the file via the option Append, only the very last call of export::stl should bear the option OutputBox!

This last call shifts and scales all coordinates of all surfaces inside the file such that the entire scene of objects fits into the output box. The relative size and positions of the objects are preserved.

See Example 3.

This option is rather expensive since all data in the STL file need to be modified!

This option is not available if the file was opened outside export::stl and passed by a file descriptor n.

Scaling

Option, specified as Scaling = Unconstrained or Scaling = Constrained

With Scaling = Unconstrained, the surface is scaled by different factors in the x, y, and z direction, such that it fills the output box set by the option OutputBox - [`x_{min}` .. `x_{max}`, `y_{min}` .. `y_{max}`, `z_{min}` .. `z_{max}`] . Thus, the output coordinates of a sphere define an ellipsoid with diameters given by the side lengths of the output box. This is the default setting.

With Scaling = Constrained, the surface is scaled by the same factor in the x, y, and z direction such that it fits into the output box set by the option OutputBox = [`x_{min}` .. `x_{max}`, `y_{min}` .. `y_{max}`, `z_{min}` .. `z_{max}`] . A sphere will remain a sphere even if the sides of the output box have different lengths.

This option is ignored if not used in conjunction with the OutputBox option.

Ascii, Bin, Binary, Raw, Text

With the synonymous flags Bin, Binary, or Raw, respectively, the STL file is created as a binary file. If a binary file is specified by a file descriptor n, make sure that is was opened by the command n:= fopen(filename, Write, Raw). With the synonymous flags Text and Ascii, repectively, the STL file is created as a text file. The default is Bin.

Append

With this flag, the STL data of the surface are appended to an existing STL file named "filename". If no such file exists, it is created and processed as without Append. This option is not available if the file was opened outside export::stl and passed by a file descriptor n.

null() object.

## Algorithms

There are two storage formats available for STL files, which are ASCII and BINARY. ASCII files are human-readable while BINARY files are smaller and faster to process. Both ASCII as well as BINARY files can be generated by export::stl. A typical ASCII STL file looks like this:

```    solid sample
facet normal -4.470293E-02 7.003503E-01 -7.123981E-01
outer loop
vertex -2.812284E+00 2.298693E+01 0.000000E+00
vertex -2.812284E+00 2.296699E+01 -1.960784E-02
vertex -3.124760E+00 2.296699E+01 0.000000E+00
endloop
endfacet
...
endsolid sample
```

STL BINARY files have the following format:

```    Bytes  Type   Description
80     ASCII  header, no data significance
4      uint   number of facets in file

4      float  normal  x - start of facet
4      float  normal  y
4      float  normal  z
4      float  vertex1 x
4      float  vertex1 y
4      float  vertex1 z
4      float  vertex2 x
4      float  vertex2 y
4      float  vertex2 z
4      float  vertex3 x
4      float  vertex3 y
4      float  vertex3 z
2      byte   not used  - end of facet
...
```

Facet orientation: The facets define the surface of a 3D object. As such, each facet is part of the boundary between the interior and the exterior of the object. The orientation of the facets (which way is "out" and which way is "in") is specified redundantly in two ways which should be consistent. First, the direction of the normal is outward. Second, which is most commonly used nowadays, the facet vertices are listed in counter-clockwise order when looking at the object from the outside (right-hand rule).

Vertex-to-vertex rule: Each triangle must share two vertices with each of its adjacent triangles. In other words, a vertex of one triangle cannot lie on the side of another.

Axes: The format specifies that all vertex coordinates must be strictly positive numbers. However, it seems that – with a few exceptions – most software used today (MuPAD included) allow negative coordinates as well.

Units: The STL file does not contain any scale information; the coordinates may be interpreted in arbitrary units.

Further details about the STL file format are available in the web, e.g., at:

• www.ennex.com/fabbers/StL.asp,

• www.math.iastate.edu/burkardt/data/stl/stl.html and

• rpdrc.ic.polyu.edu.hk/content/stl/stl_introduction.htm.

Collections of STL sample files can be found in the web, e.g., at:

• www.wohlersassociates.com/Software-for-Rapid-Prototyping.html and

• www.cs.duke.edu/~edels/Tubes.

Information about rapid prototyping technologies is available in the web, e.g., at: