Turn 3D co-ordinates into a solid and export to STL file
Afficher commentaires plus anciens
I've looked and I cannot find anything that solves the following problem:
Given a shape that is described by points in 3D space, create an STL file that will allow a CAD package to read in this 3D solid shape.
The bit that I'm confused with is that all the use-cases and examples are obsessed with creating infinitely thin, open 2D surfaces and writing these out to an STL file. Why? An open, infinitely thin 2D surface is an impossible object that cannot exist, why would you want to import it into a practical piece of software like a CAD package?
Surely the primary use-case is creating a real-world 3D object that is described by a closed surface.
As an example:
I have a unit cube given by 8 points in 3D space:
x = [0, 1, 1, 0, 0, 1, 1, 0];
y = [0, 0, 1, 1, 1, 1, 0, 0];
z = [0, 0, 0, 0, 1, 1, 1, 1];
How do I turn this into an STL that say Solidworks can import to create this unit cube?
Note that I will want to create more complex shapes in future, so I don't want to create a 2D surface and extrude or similar. Instead, as above, I can create a set of 3D points that define the object and then use convex hull or similar to describe the shape. Similarly, creating 6 separate open 2D surfaces and gluing them together probably isn't a very extensible or generally applicable method for other shapes.
Any help would be greatly appreciated, additionally, as I appear to missing something - any discussion on why the above isn't the main use-case and work flow would be great to hear.
10 commentaires
darova
le 5 Mar 2020
- use convex hull or similar to describe the shape
So why are asking? DOesn't it work? Can you show example of complex data?
nathan welch
le 5 Mar 2020
darova
le 5 Mar 2020
- So, it appears stlwrite is very popular, but if I pass in 3D data like the cube shown above, it gets confused because it's only set up to deal with an open surface, deletes data and fails to create the desired STL file.
stlwrite is not for creating/building surfaces/patches. It's only for writing
So if you have point of cloud - create patch/surface first
Or am i missing something?
nathan welch
le 5 Mar 2020
Kim
le 13 Oct 2020
Although it's 5 months in the past, I tried to compile your code since I have the same problem and got the error "Input argument must be a triangulation object." for the stlwrite-line. Have you ever encountered this problem?
Nathan Welch
le 13 Oct 2020
Modifié(e) : Nathan Welch
le 13 Oct 2020
I don't think so - can you copy and paste the full error message so I can see whereabouts in STLwrite it fails?
Also - what I've found is that MATLAB isn't great at this sort of stuff - it's effectively trying to turn MATLAB into a CAD package and functions like alphaShape aren't particularly useable or even powerful enough to be able to deal with complex objects and surfaces - I think this is why there aren't too many worked examples of how to turn geometries into closed surfaces and stl files.
Instead, consider building the point clouds (vertices) and faces yourself, for the example of a cube above I use something like:
%point cloud of unit cube
%made of 2 sets of 4 points, each going round anti-clockwise
x = [0, 1, 1, 0, 0, 1, 1, 0];
y = [0, 0, 1, 1, 0, 0, 1, 1];
z = [0, 0, 0, 0, 1, 1, 1, 1];
%turn into [8, 3] vertices
vertices = [x(:) y(:) z(:)];
%create faces by considering which vertices are assosciated with each face - make sure they're triangles to they can be written out by STLwrite
faces = zeros(12,3); %6 square sides, each made of 2 faces
%-ve z faces
faces(1,:) = [1, 2, 3];
faces(2,:) = [1, 3, 4];
%+ve z faces
faces(3,:) = [...
and so on....
%then create triangulation structure
fv.faces = faces;
fv.vertices = vertices;
So either fork out for SolidWorks or try and get good at this by-hand method. You may also need to consider the order of the nodes in the faces to get outward pointing normals that can be required by different packages.
On a similar issue, just as MATLAB can't create very good surface meshes, MATLAB can't mesh inside complex or nested objects to create 3D tetrahedra either. It can only handle simple or very specific cases, with lots of work. Again, you have to shell out on COMSOL.
Hope that all helps.
Kim
le 13 Oct 2020
Thanks a lot for your effort. Going by hand is out of question for my actual geometry since it's rather complex, consisting of interlinked functions. That was the reason why I chose Matlab in the first place, I didn't expect the export to be such a problem. Hence I'm going to look for another way.
jose daniel hoyos giraldo
le 9 Jan 2022
@nathan welch thank you for helping. I tried to change your code to create a 3d rectangle and not a cube, and the error says "The FACES input array should hold triangular faces (N x 3), but was detected as N x 0.
The STL format is for triangulated surfaces"
Any suggestion? thanks
alan cheville
le 14 Juin 2022
Try this out and see if it helps with what you are trying to do.
% create a cube for 3D printing
clf
% set vertices of cube
V = [1 1 1;1 1 0;1 0 1;1 0 0;0 1 1;0 1 0;0 0 1;0 0 0];
% plot the vertices to help with face identification
bogus = size(V);
for m = 1:bogus(1);
a = text(V(m,1),V(m,2),V(m,3),num2str(m));
end
axis([-1 2 -1 2 -1 2])
grid
rotate3d on
xlabel('X')
ylabel('Y')
zlabel('Z')
pause
% define faces as triangles with surface vector pointing out using RHR
f = [2 8 6
2 4 8
4 2 1
4 1 3
2 6 5
2 5 1
8 5 6
8 7 5
8 4 3
8 3 7
7 3 1
7 1 5]; % correct normals using RHR to all be out, check!
% set up struct variable and write the file
fv = struct('faces',f,'vertices',V);
% this is a free function on Matlab named STLWRITE.m, I renamed it
write_stl_file('ascii_cube.txt',fv,'mode','ascii')
% Look in real time what the demo surface looks like.
axis([-1 2 -1 2 -1 2])
hold on
for m = 1:max(size(fv.faces));
fp = fv.faces(m,:);
xx = colormap;
fc = xx(5*ceil(m/80),:);
a = patch('Faces',fp,'Vertices',fv.vertices);
set(a,'FaceAlpha',.25) %transparent
set(a,'EdgeColor',fc)
pause(.5)
end
hold off
DGM
le 18 Juil 2025
@alan cheville's example uses FEX #20922.
% use a triangulation object
T = triangulation(f,v);
% use the native encoder
stlwrite(T,'cube.stl')
As an aside, I don't think it's a good idea to get in the habit of using ASCII encoding unless you know that you need it. It wastes a colossal amount of space, and in order to mitigate the cost of using ASCII, some encoders will reduce data precision when using ASCII encoding instead of binary.
Also, you're writing an STL file, not a text file. Use the correct extension unless you're trying to confuse people.
Réponses (0)
Catégories
En savoir plus sur STL (STereoLithography) dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!