Documentation |
Export STL data
This functionality does not run in MATLAB.
export::stl(filename, [x, y, z], u = u_{min} .. u_{max}, v = v_{min} .. v_{max}, options) export::stl(n, [x, y, z], u = u_{min} .. u_{max}, v = v_{min} .. v_{max}, options) export::stl(filename, object_{1}, <object_{2}, …>, options) export::stl(n, object_{1}, <object_{2}, …>, options)
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 p_{1} = (x(u, v), y(u, v), z(u, v)), p_{2} = (x(u + du, v), y(u + du, v), z(u + du, v)), p_{3} = (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 p_{2} - p_{1} times the side p_{3} - p_{2}. 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 p_{2} - p_{1} and p_{3} - p_{2} does not point to the outside of your body, you just need to let one of the parameters (u, say) run from u_{max} to u_{min} instead of from u_{min} to u_{max}. Just replace your call export::stl(filename, [x,y,z], u = `u_{min}` .. `u_{max}`, v = `v_{min}` .. `v_{max}`) by export::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.
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.
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 ... endsolid MuPADtoSTL1
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 ... endsolid MuPADtoSTL2
We visualize the new content of the file:
plot(plot::SurfaceSTL(filename, MeshVisible))
delete x, y, z, filename, DIGITS:
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:
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:
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:
filename |
A file name: a non-empty character string |
n |
A file descriptor provided by fopen: a positive integer |
object_{1}, object_{2}, … |
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. |
u_{min} .. u_{max} |
The range for the parameter u: u_{min}, u_{max} must be numerical real values. |
v |
The second surface parameter: an identifier or an indexed identifier. |
v_{min} .. v_{max} |
The range for the parameter v: v_{min}, v_{max} must be numerical real values. |
Mesh |
Option, specified as Mesh = [nu, nv] Sets the mesh size: the integer n_{u} determines, how many equidistant points in the u direction are used to sample the parametrization x, y, z numerically. Correspondingly, the integer n_{v} determines, how many equidistant points in the v direction are used. Thus, a regular mesh of (n_{u} - 1) (n_{v} - 1) rectangles is used. Each rectangle is split into 2 triangles, resulting in a triangulation consisting of 2 (n_{u} - 1) (n_{v} - 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 = [ x_{min}.. x_{max}, y_{min}.. y_{max}, z_{min}.. z_{max}] sets the output box defined by numerical values x_{min}, …, z_{max}. The mathematical coordinates x(u, v), y(u, v), z(u, v) with u, v ranging from u_{min} to u_{max} and from v_{min} to v_{max}, respectively, are shifted and scaled such that the output coordinates written to the STL file range between the values x_{min} and x_{max}, y_{min} and y_{max}, z_{min} and z_{max}.
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. |
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:
www.cs.hut.fi/~ado/rp/rp.html.