Find holes and gaps in .stl files

42 ビュー (過去 30 日間)
Eduardo
Eduardo 2012 年 2 月 2 日
コメント済み: mahmoud elmesery 2021 年 5 月 24 日
Hi,
I need to find gaps and holes in a stl file. I don´t know if there´s a function developed that can help me. I started to work with MATLAB recently and i´m finding some dificulties. I found 2 ways of doing this, each triangle should have 3 adjacent triangles or each edge must have 2 triangles in common. Hope someone could give a hand. Thank´s.
Eduardo G.
  3 件のコメント
Walter Roberson
Walter Roberson 2013 年 12 月 9 日
Please be more specific about the errors you are observing.
agdfg sdgfdg
agdfg sdgfdg 2013 年 12 月 10 日
[unqEdges, ~, edgeNos] = unique(edges,'rows'); | Error: Expression or statement is incorrect--possibly unbalanced (, {, or [. this the error i observed.
And i request you to suggest some other algorithms or codes for STL File Correction.

サインインしてコメントする。

採用された回答

Sven
Sven 2012 年 2 月 3 日
Hi Eduardo,
Firstly you need to read the .stl file in as faces and vertices. I'll presume you've already got that done (as Anton points out, stlread is available here http://www.mathworks.com/matlabcentral/fileexchange/22409-stl-file-reader).
Next, as you wrote: each edge must have 2 triangles in common... I think this is a good start. Here's some code that will make a test faces/vertices mesh, then determine such a thing:
% MAKE a face/vertices structure
tmpvol = zeros(20,20,20); % Empty voxel volume
tmpvol(8:12,8:12,5:15) = 1; % Turn some voxels on
fv = isosurface(tmpvol, 0.99);
% REMOVE a face
fv.faces(30,:) = []; % Remove a face!
% TEST for gaps or holes
edges = sort(cat(1, fv.faces(:,1:2), fv.faces(:,2:3), fv.faces(:,[3 1])),2);
[unqEdges, ~, edgeNos] = unique(edges,'rows');
if size(edges,1) == size(unqEdges,1)*2
% Every edge is used twice... consistent with a closed manifold mesh
disp('No problem!')
else
badEdgesMask = hist(edgeNos, 1:max(edgeNos))~=2;
badEdgeNos = edgeNos(badEdgesMask);
badNodeNos = edges(badEdgeNos,:);
badFaceNos = find(sum(ismember(fv.faces, badNodeNos),2)>=2);
end
Does this answer the question for you?
  2 件のコメント
Eduardo
Eduardo 2012 年 2 月 22 日
Thanks. This is exactly what i was looking for. Now i have to fill in the hole if one or more were found... Do you have any idea how to do it?
mahmoud elmesery
mahmoud elmesery 2021 年 5 月 24 日
Hello, How to substract two stl files in matlab

サインインしてコメントする。

その他の回答 (3 件)

Eduardo
Eduardo 2012 年 2 月 4 日
Hi,
First of all thanks. I´m using this 'stlread':
and then i´m using 'patchslim'. Now i´ll try your code and i´ll give you feedback.

Eduardo
Eduardo 2012 年 2 月 26 日
Hi. I´ve made some tests and discovered that when a hole is found this code is not working correctly. When we axecute "badEdgeNos = edgeNos(badEdgesMask);" this should compare badEdgesMask with the number 1 and not with the first element of edgeNos. Can you understand what i´m trying to explain?
  2 件のコメント
Sven
Sven 2012 年 2 月 29 日
If you mean that the variable badEdgesMask only contains ones and zeros, then you need to realise that it's using logical indexing... if you're sure there's a problem, make a small example (such as the one I made) and show how it's not working.
Eduardo
Eduardo 2012 年 2 月 29 日
I´ve made a test with a simple cube. I removed 1 face and badEdgesMask is correct. The problem is in "badEdgeNos = edgeNos(badEdgesMask);" because badEdgesMask has 18 elements and edgeNos has 33. The comparison is made 1 by 1 element, so it compares the first logical value with the first element of edgeNos, i think it should be the first logical value with the element 1 of edgeNos (corresponding edge "1 2").

サインインしてコメントする。


Eduardo
Eduardo 2012 年 3 月 25 日
I made it like this to solve the problem i´ve told you:
edges = sort(cat(1, fv.faces(:,1:2), fv.faces(:,2:3), fv.faces(:,[3 1])),2);
[unqEdges, ~, edgeNos] = unique(edges,'rows');
if size(edges,1) == size(unqEdges,1)*2
% Every edge is used twice... consistent with a closed manifold mesh
disp('No problem!')
else
badEdgesMask = hist(edgeNos, 1:max(edgeNos))~=2;
[~, ~, edgeNos1] = unique(unqEdges,'rows');
badEdgeNos = edgeNos1(badEdgesMask);
badNodeNos = unqEdges(badEdgesMask,:);
badFaceNos = find(sum(ismember(fv.faces, badNodeNos),2)>=2);
end
I don´t know if this the best way to do it, but it works...
  1 件のコメント
Muhammed Talu
Muhammed Talu 2021 年 1 月 5 日
How can I get deleted faces back?

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeSTL (STereoLithography) についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by