surf2solid - make a solid volume from a surface for 3D printing

Version (6.08 KB) by Sven
Turns thin surfaces into closed solids by adding a flat base or offsetting by a given thickness.
Updated 10 Feb 2014

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

SOLID_FV = SURF2SOLID(FV,...) takes in a triangulated patch defined by
FV (a structure with fields 'vertices' and 'faces'), and returns a
solid patch SOLID_FV closed by options (described below).

SOLID_FV = SURF2SOLID(F, V,...) takes faces and vertices separately.

[F,V] = SURF2SOLID(...) returns solid faces and vertices separately.

SURF2SOLID(...) with no output argument plots the 3 components
(orig-surface, side-walls, under-surface) to a new figure.

SURF2SOLID(X, Y, Z, ...) reads in surface data in X, Y, and Z matrices,
and triangulates this gridded data into a surface using triangulation
options specified below. Z must be a 2D matrix. X and Y can be 2D
matrices of the same size as Z, or vectors of length equal to SIZE(Z,2)
and SIZE(Z,1), respectively. If X or Y are scalar values, they are used
to specify the X and Y spacing between grid points.

SURF2SOLID(...,'PropertyName',VALUE,...) makes a solid volume from thin
surface using any of the following property/value options:

ELEVATION - Extends the surface down to a flat base at the given
(Z) elevation value. Useful for turning a thin
elevation map into a solid block with a flat base. The
ELEVATION value should be below the lowest (or above
the highest) data point. If no other options are given,
ELEVATION defaults to MIN(Z)-0.1*(MAX(Z)-MIN(Z)).
Variable ELEVATION may also be given per-point, via a
2D matrix (the same size as Z for X,Y,Z style input) or
a 1D array (with length equal to the number of vertices
given in face/vertex input).

THICKNESS - Value to offset the given thin surface to make a
thickened solid slab. Each node on the surface will be
projected along its normal direction by thickness. When
negative thickness is given, offset will be away from
face normal direction. Variable thickness can also be
specified via a 2D matrix (of same size as Z, for X,Y,Z
input) or an N-by-1 array of thicknesses (where N is
the number of vertices in the thin surface)

TRIANGULATION - When used with gridded data, TRIANGULATION is either:
'delaunay' - (default) Delaunay triangulation of X, Y
'f' - Forward slash division of grid quads
'b' - Back slash division of quadrilaterals
'x' - Cross division of quadrilaterals
Note that 'f', 'b', or 'x' triangulations use an
inbuilt version of FEX entry 28327, "mesh2tri". 'x'
style triangulation cannot be used with variable

NORMALS - When THICKNESS options is used, the direction to
thicken the surface is (by default) determined by the
surface (unit vector) normal directions at each vertex.
To override these default directions, you may specify
NORMALS as an N-by-3 array of normal directions (where
N is the number of vertices in the thin surface). This
is useful when underlying data gives more precise
normal directions than face orienatations (for an
example, see the isonormals function).

Note 1: Currently surf2solid will return a closed surface with face
normals pointing "out". With user feedback, I'd be happy to change this
behaviour to either "in" or "unchanged from input direction".
Note 2: If a single ELEVATION value is specified (i.e., flat base), the
resulting patch will have minimal triangles on the flat base to reduce
patch/file size.

Example (shows both THICKNESS and ELEVATION forms):
n = 30;
[X,Y] = meshgrid(linspace(0,1,2*n+1));
L = (40/51/0.9)*membrane(1,n);
figure, subplot(2,2,[1 3]), title 'Thin surface'
surf(X,Y,L,'EdgeColor','none'); colormap pink; axis image; camlight
subplot(2,2,2), title 'Block elevation'
surf2solid(X,Y,L,'elevation',min(L(:))-0.05); axis image; camlight; camlight
subplot(2,2,4), title 'Thickness'
surf2solid(X,Y,L,'thickness',-0.1); axis image; camlight;

Original idea adapted from Paul Kassebaum's blog post
Many thanks to Paul for his further input and improvements.

Cite As

Sven (2024). surf2solid - make a solid volume from a surface for 3D printing (, MATLAB Central File Exchange. Retrieved .

MATLAB Release Compatibility
Created with R2013a
Compatible with any release
Platform Compatibility
Windows macOS Linux

Inspired by: mesh2tri

Inspired: punctureSurface

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
Version Published Release Notes

Added optional normal direction input

Added ability to solidify self-enclosing surfaces without boundary edges

Added per-node elevation and thickness, minimal-flat-base file size, and default face orientation "out".

Set other-faces as opposite norm direction to input faces
Ensured optional per-node thickness input is accepted