Matlab program for loading binary STL files

In May 2010 I spent a bit of time optimizing a matlab program for reading in (loading) binary STL files into matlab. I know that my program works well for binary STL files exported by the Magics (Materialise) software. I use STL files to represent various 2D models when working with Raman tomography and the NIRFAST tomography software package. I did this primarily for use in Michael Morris' lab at the University of Michigan (more about Michael Morris), though I actually wrote this program while on vacation. Programs for reading ASCII STL files in matlab are also available, including one written for matlab.

STL files contain a list of triangles (defined as sets of vertices), which are used for rapid prototyping and modelling 3D objects in software. There are a lot of web pages with information about STL files, including a good wikipedia article).

There are several stlread.m files available, including stlread.m by Doron Harlev (2005), and STL File Reader (also stlread.m) by Eric Johnson (a Mathworks employee, last updated in 2009).

With 2 versions already working, why make another one? I found that the STL reading process was taking a long time, and I use it in several routines where several files are loaded. So I optimized the program to run faster. Here is a speed comparison of the 3 versions for 3 files with different sizes:

File Index File Size Number of Facets
1 0.783 mb 16018 facets
2 3.197 mb 65468 facets
3 11.154 mb 228432 facets

Version Time to Read File 1 (s) Time to Read File 2 (s) Time to Read File 3 (s)
Harlev (2005) 2.618346 6.567528 20.946232
Johnson (2009) 3.542618 11.886920 42.004691
Esmonde-White (2010) 0.136647 0.528272 1.568755

An important difference between the different files is that they output different formats.

Harlev's program outputs X, Y, Z, and (optionally C) matrices that contain lists of vertex positions in sets of 3, with each dimension in it's own matrix. This is a convenient output format where you can then plot the surface using "patch(X, Y, Z);".

Johnson's program outputs F (faces), V (vertices), N (face normal vectors). This can be plotted using "patch('Faces', f, 'Vertices', v);". While it may initially seem less convenient than the XYZ output, it is much faster for plotting patch objects because matlab patch objects require the face/vertex format. So XYZ data must be converted internally to FV data before plotting, and this slows it down by about 50%. Also, the face normal vectors can be used for additional linear algebra computations (like testing for collisions/intersections or looking for face distance between specified objects and the mesh model).

My program (Esmonde-White) also outputs F (faces), V (vertices), and N (face normal vectors). It's essentially equivalent to Johnson (2009), but much faster for loading the binary file.

The matlab code for my stlread.m program is attached here and on the mathworks web site.

Update 1

I initially forgot to include the file patchslim.m in my mathworks submission, which I refer to in the stlread.m help. It is used to remove duplicate vertices in the faces & vertices model loaded by stlread.m.

In one of my small test-meshes, patchslim has the following results:

v matrix size (# elements) f matrix size (# elements)
before patchslim [17592 3] [5864 3]
after patchslim [2934 3] [5864 3]

The matlab code for my patchslim.m program is attached here and on the mathworks web site.

Update 2

(Jan. 12, 2011)

With suggestions from John D'Errico, I have updated patchslim and it now runs about 30x faster than the original version.