How to convert a 3D model into an STL File ?

조회 수: 22 (최근 30일)
Arshiya Pandey
Arshiya Pandey 2023년 4월 19일
편집: DGM 2025년 7월 15일
I am having difficulty in converting my model into an stl file. When I used the stlwrite function directly, it gave me an error stating the argument should be a triangulation object. I tried using the delaunay triangulation metho but to no avail. I do'tt know how to proceed further. Can someone please point me in the right direction?
Here is a snippet of my matlab code:
% Define the dimensions of the room
roomWidth = 5;
roomLength = 10;
wallWidth = 0;
wallHeight = 3;
wallPositions = [0 0; roomWidth 0; roomWidth roomLength; 0 roomLength; 0 0; roomWidth/2 roomLength/2];
% Define the vertices of the walls
vertices = [
wallPositions(1,1) wallPositions(1,2) 0;
wallPositions(2,1) wallPositions(2,2) 0;
wallPositions(2,1) wallPositions(2,2) wallHeight;
wallPositions(1,1) wallPositions(1,2) wallHeight;
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth 0;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth 0;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth wallHeight;
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth wallHeight;
wallPositions(3,1) wallPositions(3,2) 0;
wallPositions(4,1) wallPositions(4,2) 0;
wallPositions(4,1) wallPositions(4,2) wallHeight;
wallPositions(3,1) wallPositions(3,2) wallHeight;
wallPositions(3,1)-wallWidth wallPositions(3,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth wallHeight;
wallPositions(3,1)-wallWidth wallPositions(3,2)+wallWidth wallHeight;
wallPositions(1,1) wallPositions(1,2) 0;
wallPositions(4,1) wallPositions(4,2) 0;
wallPositions(4,1) wallPositions(4,2) wallHeight;
wallPositions(1,1) wallPositions(1,2) wallHeight;
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth wallHeight;
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth wallHeight;
wallPositions(2,1) wallPositions(2,2) 0;
wallPositions(3,1) wallPositions(3,2) 0;
wallPositions(3,1) wallPositions(3,2) wallHeight;
wallPositions(2,1) wallPositions(2,2) wallHeight;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth 0;
wallPositions(3,1)+wallWidth wallPositions(3,2)+wallWidth 0;
wallPositions(3,1)+wallWidth wallPositions(3,2)+wallWidth wallHeight;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth wallHeight
];
% Define the faces of the walls
faces = [
1 2 3 4;
1 5 6 4;
2 5 6 3;
1 2 5 4;
4 3 6 5;
1 2 3 6];
% Define the colors of the walls
colors = [
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8];
% Create a patch object for the walls
walls = patch('Vertices', vertices, 'Faces', faces, 'FaceVertexCData', colors, 'FaceColor', 'flat');
view(3);
% Set the axis limits of the room
axis([0 roomWidth 0 roomLength 0 wallHeight]);
% Label the axes of the room
xlabel('X-axis');
ylabel('Y-axis');
zlabel('Z-axis');

답변 (2개)

Sai Kiran
Sai Kiran 2023년 4월 26일
편집: Sai Kiran 2023년 4월 26일
Hi,
As per my understanding you want to convert the 3D model into .stl format.
The 'stlwrite' function only supports conversion 2D triangulation objects to .stl format.
Tetrahedron triangulation(3D) is not supported as of now.
I hope it helps!
Thanks.

DGM
DGM 2025년 7월 15일
편집: DGM 2025년 7월 15일
I'm not sure what the goal was here, but this is mostly wrong.
% Define the dimensions of the room
roomWidth = 5;
roomLength = 10;
wallWidth = 1; % setting this to zero is hiding how wrong everything is
wallHeight = 3;
% these are xy positions of vertices, not "walls". points are not lines.
wallPositions = [0 0; roomWidth 0; roomWidth roomLength; 0 roomLength; % CCW sequence
0 0; % redundant closure vertex
roomWidth/2 roomLength/2]; % some interior vertex that's not used??
% Define the vertices of the walls
% again, these are vertices, not walls
% half of these vertices are redundant in all cases
% half of the remaining vertices are redundant when width = 0
% the ordering doesn't matter for a vertex list
% but i'm going to comment on the ordering, as the way these quads
% are being defined suggests they'll be used wrong
V = [
% front wall, correct winding for an exterior face
wallPositions(1,1) wallPositions(1,2) 0;
wallPositions(2,1) wallPositions(2,2) 0;
wallPositions(2,1) wallPositions(2,2) wallHeight;
wallPositions(1,1) wallPositions(1,2) wallHeight;
% front wall (interior?), wrong winding for an interior face
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth 0;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth 0;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth wallHeight;
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth wallHeight;
% rear wall, wrong winding for an exterior face
wallPositions(3,1) wallPositions(3,2) 0;
wallPositions(4,1) wallPositions(4,2) 0;
wallPositions(4,1) wallPositions(4,2) wallHeight;
wallPositions(3,1) wallPositions(3,2) wallHeight;
% rear wall (interior?), correct winding for an interior face
% these offsets are wrong
wallPositions(3,1)-wallWidth wallPositions(3,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth wallHeight;
wallPositions(3,1)-wallWidth wallPositions(3,2)+wallWidth wallHeight;
% left wall, wrong winding for an exterior face (redundant)
wallPositions(1,1) wallPositions(1,2) 0;
wallPositions(4,1) wallPositions(4,2) 0;
wallPositions(4,1) wallPositions(4,2) wallHeight;
wallPositions(1,1) wallPositions(1,2) wallHeight;
% left wall (interior?), correct winding for an interior face (redundant)
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth 0;
wallPositions(4,1)+wallWidth wallPositions(4,2)+wallWidth wallHeight;
wallPositions(1,1)+wallWidth wallPositions(1,2)+wallWidth wallHeight;
% right wall, correct winding for an exterior face (redundant)
wallPositions(2,1) wallPositions(2,2) 0;
wallPositions(3,1) wallPositions(3,2) 0;
wallPositions(3,1) wallPositions(3,2) wallHeight;
wallPositions(2,1) wallPositions(2,2) wallHeight;
% right wall (interior?), wrong winding for an interior face (redundant)
% these offsets are also wrong
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth 0;
wallPositions(3,1)+wallWidth wallPositions(3,2)+wallWidth 0;
wallPositions(3,1)+wallWidth wallPositions(3,2)+wallWidth wallHeight;
wallPositions(2,1)-wallWidth wallPositions(2,2)+wallWidth wallHeight
];
% Define the faces of the walls
% this is a seemingly random mix of intersecting quads and tetrahedra
F = [
1 2 3 4; % front face, correct winding
1 5 6 4; % not a planar quad
2 5 6 3; % not a planar quad
1 2 5 4; % not a planar quad
4 3 6 5; % this is at least planar, but it's a trapezoid on the wall diagonal
1 2 3 6]; % not a planar quad
% Define the colors of the walls
colors = [
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8;
0.8 0.8 0.8];
% pick a specific face to inspect
vk = 5;
tv = V(F(vk,:),:);
% Create a patch object for the walls
plot3(V(:,1),V(:,2),V(:,3),'*'); hold on % plot all vertices
plot3(tv(:,1),tv(:,2),tv(:,3),'-b','linewidth',2) % plot the edges of this quad
plot3(tv(end,1),tv(end,2),tv(end,3),'*b','linewidth',2,'markersize',10) % indicate direction
walls = patch('Vertices', V, 'Faces', F(vk,:), ...
'FaceVertexCData', colors(vk,:), 'FaceColor', 'flat');
view(3); grid on
% Set the axis limits of the room
% there are vertices outside this region
%axis([0 roomWidth 0 roomLength 0 wallHeight]);
% Label the axes of the room
xlabel('X-axis');
ylabel('Y-axis');
zlabel('Z-axis');
The goal is to make an STL, so you need a triangulation, but the given code generates no triangles. It generates a total of one plausible quadrilateral face, one implausible quadrilateral face, and four intersecting tetrahedra (which also intersect both quads). So not only do we not have triangles, we don't even have faces.
We also don't have a sensible vertex list. The offsets are wrong, and at least half of the vertex list is redundant. The most ridiculous part is that we don't even know which way the offsets are supposed to be, but we can tell they're necessarily wrong because they're not consistent.
This is what happens when you try to write everything and then run it without establishing the correctness of the parts as you create them. There was no point trying to throw things into an STL until you had checked the vertex positions and constructed some triangles.
How would I do it? That depends, because the design concept isn't clear. The goal appears to be to create a box with no top or bottom. With the given parameters, it has zero wall thickness, so all the faces would be coincident. There is no indication that the walls should be capped, but I guess things never got that far.
I'm going to assert that zero-thickness walls is unacceptable. Zero thickness walls means that the vertical faces are coincident, and the horizontal faces are degenerate. I'm also going to say the walls should be capped so that the model is a solid.
I'm also going to assert that the "room" dimensions are the interior of the box. A container is dimensioned with respect to the volume which does the containing. That said, I'll include code for both.
Instead of trying to construct things as quads or triangles, construct a single 2D polygon for the top. Triangulate it, then then extrude it.
% parameters
roomsize = [20 10]; % the interior of the box [x y]
wallt = 1.5; % wall thickness > 0
wallh = 5; % wall height
% assemble all 2D boundaries into a cell array (dimensioned on interior)
Vc = [{[0 1; 1 1; 1 0; 0 0].*roomsize}; % inner (cw)
{[0 0; 1 0; 1 1; 0 1].*roomsize + [-1 -1; 1 -1; 1 1; -1 1]*wallt}]; % outer (ccw)
% assemble all 2D boundaries into a cell array (dimensioned on exterior)
%Vc = [{[0 0; 1 0; 1 1; 0 1].*roomsize + [1 1; -1 1; -1 -1; 1 -1]*wallt}; % outer (ccw)
% {[0 1; 1 1; 1 0; 0 0].*roomsize}]; % inner (cw)
% plot the boundary curves to verify their position and direction
figure
C = {'b','r'};
for k = 1:numel(Vc)
hold on
plot(Vc{k}(:,1),Vc{k}(:,2),'-','linewidth',2,'color',C{k}) % plot the edges of this quad
plot(Vc{k}(end,1),Vc{k}(end,2),'*','linewidth',2,'markersize',10,'color',C{k}) % indicate direction
end
grid on; axis equal
% consolidate the complete vertex list (referenced by E)
V = cell2mat(Vc);
% construct the edge (index) lists in the same direction
sz = cellfun(@(x) size(x,1),Vc); % length of each vertex list
szc = [0; cumsum(sz)];
E = zeros(0,2);
for k = 1:numel(Vc)
v = 1+szc(k):szc(k+1);
thisE = [v; circshift(v,-1)].';
E = [E; thisE]; %#ok<AGROW>
end
% TRIANGULATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% do a constrained triangulation to generate the triangles
T = delaunayTriangulation(V,E);
F = T.ConnectivityList(isInterior(T),:);
V = T.Points;
% display it using patch()
figure
patch('faces',F,'vertices',V,'facecolor','w','edgecolor','k');
axis equal; grid on
xlabel('X'); ylabel('Y')
% EXTRUSION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% extrude the part into 3D
[F V] = extrude(F,V,wallh);
% write to file
stlwrite(triangulation(F,V),'testfile.stl')
% display it using patch()
figure
patch('faces',F,'vertices',V,'facecolor','w','edgecolor','k');
view(3); camlight; view(10,33)
axis equal; grid on
xlabel('X'); ylabel('Y'); zlabel('Z')
Granted, extrude() is something I wrote, but it's just a matter of sitting down with a piece of paper and working out the vertex sequences for the wall triangles between two offset curves of equal length.

카테고리

Help CenterFile Exchange에서 Lighting, Transparency, and Shading에 대해 자세히 알아보기

태그

제품

Community Treasure Hunt

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

Start Hunting!

Translated by