How to Export MatLab (fsurf) into .stl file please? [surf2stl not working]

5 views (last 30 days)
I am able to use the surf2stl file and functionalities to convert "surf" into .stl
However, for "fsurf" (surf defined as functions), the conversion functionalities does not seem to work. Does anyone have experience on how to resolve this issue please?
(For the typical X,Y,Z surf, the surf2stl works fine. However, for X,Y,Z defined as functions, hence fsurf, the surf2stl no longer works. The fsurf still plots/creates the model graph correctly, but the .stl is not created successfully: "Wrote 0 facets". Thank you for your help.)
Below is my code:
f_x = @(u,v) 1.4*cos(u);
f_y = @(u,v) 1.04*sin(u);
f_z = @(u,v) 2.4*sin(v).*sin(u);
umin = 0;
umax = pi;
vmin = -pi;
vmax = 0;
figure(1); clf;
fsurf(f_x,f_y,f_z, [umin umax vmin vmax])
colormap jet
xlabel('x-axis')
ylabel('y-axis')
zlabel('z-axis')
xlim([-4 4])
ylim([-4 4])
zlim([-4 4])
surf2stl('EXPORT_ATTEMPT.stl', f_x,f_y,f_z)

Answers (1)

DGM
DGM on 29 Jun 2025
Edited: DGM on 29 Jun 2025
Let's start with a basic example:
% an example
hfs = fsurf(@(x,y) 5*besselj(1,hypot(x,y)));
axis equal
% reshape the fsurf data so it's gridded
smd = hfs.MeshDensity;
Xm = reshape(hfs.XData(1:smd^2),smd,[]);
Ym = reshape(hfs.YData(1:smd^2),smd,[]);
Zm = reshape(hfs.ZData(1:smd^2),smd,[]);
% now it's compatible with tools that take gridded data
figure
hs = surf(Xm,Ym,Zm);
axis equal
% triangulate it with surf2patch()
% and write it with whatever writing tool is period-correct
[F V] = surf2patch(hs,'triangles'); % triangulate
stlwrite(triangulation(F,V),'test1.stl') % R2018b+
% triangulate and write it with surf2stl() (FEX #4512)
surf2stl('test2.stl',Xm,Ym,Zm)
There you have two ways to get the data into an STL. There are some problems though. Let's look at the STL:
As simple as this height map is, the usefulness of the result depends on what you're trying to do with the STL. Bear in mind that this mesh describes an open surface with zero thickness. If you just need a way to transport a mesh for some sort of mathematical analysis, then maybe it's fine. However, if you're trying to use it as a solid model, it's not a solid.
Consider another case where the result may be problematic:
% from the fsurf() synopsis (Boy's surface iirc)
A = 2/3;
B = sqrt(2);
xfcn = @(u,v) A*(cos(u).*cos(2*v) + B*sin(u).*cos(v)).*cos(u) ./ (B - sin(2*u).*sin(3*v));
yfcn = @(u,v) A*(cos(u).*sin(2*v) - B*sin(u).*sin(v)).*cos(u) ./ (B - sin(2*u).*sin(3*v));
zfcn = @(u,v) B*cos(u).^2 ./ (B - sin(2*u).*sin(3*v));
figure
hfs = fsurf(xfcn,yfcn,zfcn,[0 pi 0 pi]);
This surface is self-intersecting and one-sided, so half of it is inside-out. We can apply the same code to generate the STL. Here we can see where the two sides of the surface connect, and we can see that much of the surface normals are reversed. If you needed this to be a solid model, fixing the triangulation would be quite a bit more challenging than the prior height map.
Now let's consider the given problem:
% note that we're evaluating sin(v) over [-pi 0]
f_x = @(u,v) 1.4*cos(u);
f_y = @(u,v) 1.04*sin(u);
f_z = @(u,v) 2.4*sin(v).*sin(u); % sin(v) term will produce duplicates
urange = [0 pi];
vrange = [-pi 0];
figure
hfs = fsurf(f_x,f_y,f_z, [urange vrange]);
As before, we don't see any problems yet. Let's look at the STL:
Because we're producing duplicate Zdata, we end up with a ton of (nominally) coincident faces with opposite face normals. It's a little more complicated than that, but let's just say it's probably not good. If we restrict the range of v, we cover one side of the surface.
vrange = [-pi -pi/2]; % sin(v) doesn't repeat, so z data isn't duplicated
The result is now like it was in the first example, a simple open surface.

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!