how to find area and volume from a .stl file?

62 views (last 30 days)
I need to find the area and volume of 3D triangulation. I used [F,V] = stlBinaryRead('DWB1.stl'); to read the file "DWB1.stl". But when I used stlBinaryRead.m to get volume, it gives NaN. Hot to fix this? I used V'( all( isnan( V' ), 2 ), : )) = (); to remove NaN. but did not work.
  1 Comment
DGM
DGM on 15 Apr 2024
Edited: DGM on 15 Apr 2024
As far as I can tell, stlBinaryRead.m is not a part of base MATLAB, or any of its toolboxes. It's also not from any submission on the File Exchange or GitHub. In fact, the only mention of this file that I can find anywhere on the web is this thread. There are plenty of other binary STL file reader scripts and functions with similar names, but that doesn't tell us anything.
So you're using a function which ostensibly returns lists of face and vertex data, but somehow you got the function to return volume instead? If you're not getting volume from stlBinaryRead(), then you haven't told us how you're calculating it.
In sum, all we know is that you have an STL file, you did something with it, and you got NaN. Maybe it's a problem with stlBinaryRead() (what is it? is it being used correctly?). Maybe it's a problem with your STL file (is it binary? is it manifold?). Maybe it's a problem with whatever other calculations you're using that you aren't telling us about.
Say what tools you're using, show the actual code you're using and the actual errors you're getting, and attach the actual file that's being read (you'll probably have to zip it).

Sign in to comment.

Accepted Answer

Pratyush Swain
Pratyush Swain on 14 Apr 2024
Hi Surya,
It appears you are trying to calculate volume after extracting the faces and vertices from a stl file. In order to achieve that, you are trying to remove the NaN values from the vertices matrix.
The statement "V'( all( isnan( V' ), 2 ), : )) = ();" seems to aim at transposing V, filtering out rows that entirely consist of NaNs, and then somehow attempting to remove them, but it contains some logical and syntax errors.
The "=();" in the statement is not a valid MATLAB syntax for removing elements.Also it is not clear how transposing elements (V') is helpful in this case.
You can use this alternative statement in your implementation:
V(any(isnan(V), 2), :) = [];
This line correctly identifies any row in V that contains at least one NaN value and removes those rows.
You can refer to this example as follows:
% Preparing a demo Vertices Matrix with NaN values %
V = [0 0 0; NaN 0 NaN; 1 1 0; 0 1 0; 0.5 0.5 1]
V = 5x3
0 0 0 NaN 0 NaN 1.0000 1.0000 0 0 1.0000 0 0.5000 0.5000 1.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% Removing Rows containing NaN Values %
V(any(isnan(V), 2), :) = [];
% Displaying processed Vertices Matrix after NaN rows removal %
disp(V);
0 0 0 1.0000 1.0000 0 0 1.0000 0 0.5000 0.5000 1.0000
Please note you may also need to reconfigure your F(face) matrix later, given you have made changes to the V(vertices) matrix.
For more information regarding deleting NaN records, you can refer to this thread:
Hope this helps.
  1 Comment
Surya
Surya on 17 Apr 2024
Moved: Dyuman Joshi on 19 Apr 2024
Thank you for helping! I have been following you.
I have 10 digital scans of prosthetic limbs in .stl file format. Out of which 4 of them work as below. In work space I have F=38340x3 double
and V=115020x3 double
______________________________________________________________________
>> [F,V] = stlBinaryRead('DWB1.stl');
>> [totalVolume,totalArea] = stlVolume(V',F')
totalVolume =
2.8390e+06
totalArea =
1.0035e+05
____________________________________________________________________________________
However, Rest 6 give me only area but not volume. it gives NaN as below. In Work space F=40860x3 double
and V=122580x3 double
______________________________________________________________
>> [F,V] = stlBinaryRead('DWB4.stl');
>> [totalVolume,totalArea] = stlVolume(V',F')
totalVolume =
NaN
totalArea =
9.1950e+04
__________________________________________________________________________
After I put these files together in Current folder,
I use these two comands:
[F,V] = stlBinaryRead('DWB4.stl');
[totalVolume,totalArea] = stlVolume(V',F')
____________________________________________________________________
As you can see the first example using the same code. Now the problem is somewhere in the V' matrix (not F') there is NaN that is giving me hard time. As you see in the second example.
After you corrected the NaN removel command (V( :, all( isnan( V ), 1 ) ) = [];), I transposed V to get V' in [totalVolume,totalArea] = stlVolume(V',F'), it again gives me NaN in V.
________________________________________
I have attached the data file .zip and the Matlab functions. Do you mind figuring out where is the problem?
Thanks a lot for the help.

Sign in to comment.

More Answers (1)

DGM
DGM on 17 Apr 2024
Edited: DGM on 17 Apr 2024
Your STL, like many scans, is not a closed surface, and it has defects. According to admesh, it has 180 disconnected edges and 70 degenerate faces. I'd guess that's enough to potentially cause problems. It also has 102188 redundant vertices, but I doubt those do anything other than make the file bigger.
Given that several of the people commenting on the stlVolume.m implementation suggest that it has problems, I would assume that's where to look. We might expect that it should return 0 volume as it does for other open surfaces, but with the number of degenerate faces creating cross-products of zero, the output will be NaN.
unzip DWB4.zip
% using the same reader
[F,V] = stlBinaryRead('DWB4.stl');
% use the modified tool, discarding contributions from degenerate faces
[totalVolume,totalArea] = stlVolume(V',F')
totalVolume = 2.3832e+06
totalArea = 9.1950e+04
% display the thing
patchargs = {'facecolor',[1 1 1],'edgecolor','none'};
patch('faces',F,'vertices',V,patchargs{:})
% set up lighting, etc
az = 30;
l1 = lightangle(az,45);
l2 = lightangle(az+180,-45);
set(l1,'color',[1 0.9 0.3]);
set(l2,'color',[0.9 0.3 1]);
material dull
axis image
view(3)
grid on
That looks like the same volume returned by admesh.
  3 Comments
DGM
DGM on 21 Apr 2024
Are you using the modified version of stlVolume() that I attached, or are you using the one you were using before?
I ran the same code on the other files, and these are the [volume, area] that I got:
% DWB4 [2383161 91950]
% DWB5 [2028928 83337]
% DWB8 [2246068 88991]
% DWB9 [2926249 103179]
% DWB10 [2658433 98833]
% DWB11 [3142772 109394]
Surya
Surya on 22 Apr 2024
Great!
I tried the new version of stlVolume() and it works for all of my files. Appreciate you kind help.
Anything I can do you?
Best

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!