Get regular grid and points of a given stl file
34 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Diego Hens
il 14 Ago 2020
Commentato: Diego Hens
il 21 Ago 2020
Hello,
I have have a stl file, which has many points (ca. ten thousand) but they are not uniformly distributed. As you know, a stl object has Faces, Vertices and Normals. The Vertices are the points (they can be repeated a few times, depending on how many triangles you can form with them).
I would like to create points in between the vertices (I don't care if I lose these initial points) so that they are evenly distributed. Imagine I project the object (just the points) in a 2D plane. I would like the points to be regularly distributed (like a grid but without the lines).
4 Commenti
Risposta accettata
Bruno Luong
il 18 Ago 2020
Modificato: Bruno Luong
il 21 Ago 2020
I load the stl, cleanup the vertices, compute the face normal then I extract the top cap and interpolate on grid.
% Read mesh and compute normal vector
TR = stlread('Zahn_15_Bibliotheksmodell.stl'); % contains "Mesh" structure
[X,~,J] = unique(TR.Points,'rows');
F = J(TR.ConnectivityList).';
X = X.';
XF = reshape(X(:,F),3,3,[]);
N = cross(XF(:,2,:)-XF(:,1,:),XF(:,3,:)-XF(:,2,:),1);
% Extract the points on the top cap
Fup = F(:,N(3,:)>0);
Fup = sort(Fup,1);
n = max(Fup(:));
A = accumarray([Fup([1 2],:), Fup([1 3],:), Fup([2 3],:)]', 1, [n,n], [], 0, true);
G = graph(A+A');
bins = G.conncomp;
n = accumarray(bins(:),1);
[~,icap] = max(n);
icap = find(bins==icap);
Xcap = X(:,icap);
x = Xcap(1,:);
y = Xcap(2,:);
z = Xcap(3,:);
% Interpolation on grid
xmin = min(x); xmax = max(x);
ymin = min(y); ymax = max(y);
nx = 513; ny = 513; % define resolution of grids
xi = linspace(xmin,xmax,nx);
yi = linspace(ymin,ymax,ny);
[XI,YI] = meshgrid(xi,yi);
I = scatteredInterpolant(x(:),y(:),z(:),'linear','none');
ZI = I(XI,YI);
% Plot the result
figure(1);
ax=subplot(1,2,1);
imagesc(ax,xi,yi,ZI);
set(ax,'Ydir','normal','clim',[28 31])
colormap(ax,gray);
axis(ax,'equal');
axis(ax,'tight');
ax=subplot(1,2,2);
surf(ax,xi,yi,ZI,'linestyle','none');
There are some artefact, and did not try to see why, but it gives you an idea.
4 Commenti
Più risposte (1)
Diego Hens
il 17 Ago 2020
7 Commenti
Bruno Luong
il 18 Ago 2020
The difficult part is you need to filter the points and keep only the point on the cap of the tooth. Because - as I said - your data is not of the form z=f(x,y) and there are multiple z for the same (x,y) (close to the boundary if one looks from the above). This will polute the interpolation.
Vedere anche
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!