Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Volume of a patch

Subject: Volume of a patch

From: Chris Clark

Date: 16 Aug, 2010 12:18:04

Message: 1 of 15

i have two matrices (faces and vertices)which i use to create a 3d reconstruction either using patch or trisurf. i need to calculate the volume of the 3d reconstruction. Can any one give me a way to do this?
I've tried convhulln but that only generates images like this
http://dl.dropbox.com/u/6765472/incorrect1.jpg
http://dl.dropbox.com/u/6765472/incorrect2.jpg
so the volume it returns is for these volumes,
when use patch or trisurf with the 2 matricies i get this correct image
http://dl.dropbox.com/u/6765472/correct.jpg
which is the shape i want the volume ofh.
Any help would be much appreciated.
Thank You

Subject: Volume of a patch

From: Walter Roberson

Date: 16 Aug, 2010 15:10:24

Message: 2 of 15

Chris Clark wrote:
> i have two matrices (faces and vertices)which i use to create a 3d
> reconstruction either using patch or trisurf. i need to calculate the
> volume of the 3d reconstruction. Can any one give me a way to do this?
> I've tried convhulln but that only generates images like this
> http://dl.dropbox.com/u/6765472/incorrect1.jpg
> http://dl.dropbox.com/u/6765472/incorrect2.jpg
> so the volume it returns is for these volumes,
> when use patch or trisurf with the 2 matricies i get this correct image
> http://dl.dropbox.com/u/6765472/correct.jpg
> which is the shape i want the volume ofh.

It is a bit difficult to be sure from those images, but I get the
impression that some of the subvolumes intersect other subvolumes (or to
put it another way, that some of the edges pass through some of the
faces.) Is that the case, or is it certain that there are no intersections?

Subject: Volume of a patch

From: Chris Clark

Date: 16 Aug, 2010 15:18:27

Message: 3 of 15

if you have the information (like in the correct image) of both the vertices and the faces then i dont think that they do. convhulln though can only take in one matrix so im not entirely sure in that case.
Walter Roberson <roberson@hushmail.com> wrote in message <Axcao.15102$wJ1.4116@newsfe08.iad>...
> Chris Clark wrote:
> > i have two matrices (faces and vertices)which i use to create a 3d
> > reconstruction either using patch or trisurf. i need to calculate the
> > volume of the 3d reconstruction. Can any one give me a way to do this?
> > I've tried convhulln but that only generates images like this
> > http://dl.dropbox.com/u/6765472/incorrect1.jpg
> > http://dl.dropbox.com/u/6765472/incorrect2.jpg
> > so the volume it returns is for these volumes,
> > when use patch or trisurf with the 2 matricies i get this correct image
> > http://dl.dropbox.com/u/6765472/correct.jpg
> > which is the shape i want the volume ofh.
>
> It is a bit difficult to be sure from those images, but I get the
> impression that some of the subvolumes intersect other subvolumes (or to
> put it another way, that some of the edges pass through some of the
> faces.) Is that the case, or is it certain that there are no intersections?

Subject: Volume of a patch

From: Sean

Date: 16 Aug, 2010 15:37:08

Message: 4 of 15

"Chris Clark" <boozelclark@gmail.com> wrote in message <i4ba9s$i1f$1@fred.mathworks.com>...
> i have two matrices (faces and vertices)which i use to create a 3d reconstruction either using patch or trisurf. i need to calculate the volume of the 3d reconstruction. Can any one give me a way to do this?
> I've tried convhulln but that only generates images like this
> http://dl.dropbox.com/u/6765472/incorrect1.jpg
> http://dl.dropbox.com/u/6765472/incorrect2.jpg
> so the volume it returns is for these volumes,
> when use patch or trisurf with the 2 matricies i get this correct image
> http://dl.dropbox.com/u/6765472/correct.jpg
> which is the shape i want the volume ofh.
> Any help would be much appreciated.
> Thank You

Dip it in water...

On a serious note: could you traverse 2d slices of it, keeping the exterior coordinates, and use the surveyor's formula? You would either have to round or interpolate in some places but it seems like a possible.

I asked the surveying professor down the hall and they're going to get back to me. I'm interested in this if you find a solution.

Subject: Volume of a patch

From: Adam A

Date: 16 Aug, 2010 15:45:35

Message: 5 of 15

If your volume is a closed triangulated surface then you may be able to use the following:

http://www.mathworks.co.uk/matlabcentral/fileexchange/24593-volume-enclosed-by-a-triangulated-surface

Alternatively, you could voxelise the volume (see the link below), and then simply count the number of voxels that lie within the object and multiply that by the volume of each individual voxel. This will give an approximate answer, but the finer your mesh the closer it will be to the true answer.

http://www.mathworks.co.uk/matlabcentral/fileexchange/27390-mesh-voxelisation

You might need to rearrange your data from faces, vertices into the appropriate format to use either of these methods. But if you can use two different methods and get the same answer, then it should give you more confidence in the result.

Hope this helps,
Adam

Subject: Volume of a patch

From: Chris Clark

Date: 16 Aug, 2010 16:15:24

Message: 6 of 15

Hi Adam
Thanks for your help.
Im have looked at both these methods.
with regard to:
> If your volume is a closed triangulated surface then you may be able to use the following:
>
> http://www.mathworks.co.uk/matlabcentral/fileexchange/24593-volume-enclosed-by-a-triangulated-surface
>
this looks like exactly what i am looking for but i do not have the normal matrix that is needed. I have created a small function to find it, shown below

function [tnorm] = getNorms(faces,verticies)
d=[0 0 0];
[s1 s2] = size(faces);
tnorm=zeros(s1,3);
for i=1:s1
    P1=verticies(faces(i,1),:);
    P2=verticies(faces(i,2),:);
    P3=verticies(faces(i,3),:);
    u = cross(P2-P1,P3-P1);
    tnorm(i,:)= u/norm(u);
end

but the directions are not consistantly outward which is necessary. do you know how to check for this?

with regard to
> Alternatively, you could voxelise the volume (see the link below), and then simply count the number of voxels that lie within the object and multiply that by the volume of each individual voxel. This will give an approximate answer, but the finer your mesh the closer it will be to the true answer.
>
> http://www.mathworks.co.uk/matlabcentral/fileexchange/27390-mesh-voxelisation
>

this seems to work but i cannot find a way to get a 3D plot of the data it returns which is in the format of a 100x100x100 logical?

Thanks

"Adam A" <adamaitkenheadNOSPAM@NOSPAMhotmail.com> wrote in message <i4bmev$d38$1@fred.mathworks.com>...
> If your volume is a closed triangulated surface then you may be able to use the following:
>
> http://www.mathworks.co.uk/matlabcentral/fileexchange/24593-volume-enclosed-by-a-triangulated-surface
>
> Alternatively, you could voxelise the volume (see the link below), and then simply count the number of voxels that lie within the object and multiply that by the volume of each individual voxel. This will give an approximate answer, but the finer your mesh the closer it will be to the true answer.
>
> http://www.mathworks.co.uk/matlabcentral/fileexchange/27390-mesh-voxelisation
>
> You might need to rearrange your data from faces, vertices into the appropriate format to use either of these methods. But if you can use two different methods and get the same answer, then it should give you more confidence in the result.
>
> Hope this helps,
> Adam

Subject: Volume of a patch

From: Adam A

Date: 17 Aug, 2010 08:24:20

Message: 7 of 15

Hi Chris,

> the directions are not consistantly outward which is necessary. do you know how to check for this?

I'm afraid I don't know a good way around this problem.

> this seems to work but i cannot find a way to get a 3D plot of the data it returns which is in the format of a 100x100x100 logical?

Visualising a logical volume in 3D is probably done most easily by plotting the data in a 2D plane.

You can plot the sum of the data as follows:

> a = 1;
> imagesc(squeeze(sum(gridOUTPUT,a))) ;

Where setting a=1, 2 or 3 sums the data in the x, y or z direction respectively.


Or you can select a particular plane to plot as follows:

> a = 10;
> imagesc(squeeze(gridOUTPUT(:,a,:))) ;

Where a defines which plane is to be plotted.

Hope this helps again,
Adam

Subject: Volume of a patch

From: Chris Clark

Date: 17 Aug, 2010 08:42:14

Message: 8 of 15

Hi

I think i found a solution to my normal problem.
http://www.mathworks.com/access/helpdesk/help/techdoc/ref/trirep.facenormals.html
this method seems like it will work but is only available in 2009 so i am busy upgrading now and will see. Before i found this i wrote a small function which looks like it works but hasn't been tested 100%. its pasted below in case any one else needs it.

function [tnorm] = getNorms(faces,verticies,pInside)
% pInside is the [x y z] of any internal point
[s1 s2] = size(faces);
tnorm=zeros(s1,3);
for i=1:s1
    P1=verticies(faces(i,1),:);
    P2=verticies(faces(i,2),:);
    P3=verticies(faces(i,3),:);
     u = cross(P1-P2,P1-P3);
     
     if (dot(u,pInside-P1)>0)
       u= u.*-1 ;
     end
     
    tnorm(i,:)= u/norm(u);
end

Thanks for the help.
Do you know any way to plot the voxelised logical volume as a 3D plot like view(3) as it may be necessary later on in the work im doing. The 2d plots are fine for now but i may need to rotate and move the image around later on.
Thanks again.


"Adam A" <adamaitkenheadNOSPAM@NOSPAMhotmail.com> wrote in message <i4dgvk$7ag$1@fred.mathworks.com>...
> Hi Chris,
>
> > the directions are not consistantly outward which is necessary. do you know how to check for this?
>
> I'm afraid I don't know a good way around this problem.
>
> > this seems to work but i cannot find a way to get a 3D plot of the data it returns which is in the format of a 100x100x100 logical?
>
> Visualising a logical volume in 3D is probably done most easily by plotting the data in a 2D plane.
>
> You can plot the sum of the data as follows:
>
> > a = 1;
> > imagesc(squeeze(sum(gridOUTPUT,a))) ;
>
> Where setting a=1, 2 or 3 sums the data in the x, y or z direction respectively.
>
>
> Or you can select a particular plane to plot as follows:
>
> > a = 10;
> > imagesc(squeeze(gridOUTPUT(:,a,:))) ;
>
> Where a defines which plane is to be plotted.
>
> Hope this helps again,
> Adam

Subject: Volume of a patch

From: Adam A

Date: 17 Aug, 2010 09:20:27

Message: 9 of 15


> I think i found a solution to my normal problem.
> http://www.mathworks.com/access/helpdesk/help/techdoc/ref/trirep.facenormals.html
> this method seems like it will work but is only available in 2009 so i am busy upgrading now and will see.

That looks useful, thanks for the link. Unfortunately I'm on an old version of Matlab at the moment too, but hopefully will be ugrading sometime soon.

> Before i found this i wrote a small function which looks like it works but hasn't been tested 100%. its pasted below in case any one else needs it.

That looks like a nice solution too. However, I have a feeling it might not work for highly concave shapes. For example, if you can imagine a triangulated mesh of a horse-shoe, then I suspect that might cause problems. But it looks like it will work nicely for a convex shapes.

> Do you know any way to plot the voxelised logical volume as a 3D plot like view(3) as it may be necessary later on in the work im doing. The 2d plots are fine for now but i may need to rotate and move the image around later on.

There are a few threads on this, but no great answer. For example:
http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/284180

The only other method I could suggest (which is more a bodge than a method really...) is to create a mesh of your voxelised data (see link below) and plot that as a patch. Although it seems a bit of a circular method, it does do the job by plotting your logical volume.

http://www.mathworks.co.uk/matlabcentral/fileexchange/27733-convert-a-voxelised-object-into-an-stl-mesh

The following code would do this: (The function READ_stl is contained in the mesh voxelisation code that you've already downloaded, so you should have it already.)

CONVERT_voxels_to_stl('temp.stl',gridOUTPUT,gridCOx,gridCOy,gridCOz);
[coordVERTICES] = READ_stl('temp.stl');
xco = squeeze( coordVERTICES(:,1,:) )';
yco = squeeze( coordVERTICES(:,2,:) )';
zco = squeeze( coordVERTICES(:,3,:) )';
patch(xco,yco,zco,'b');
axis equal;

Adam

Subject: Volume of a patch

From: Adam A

Date: 18 Aug, 2010 08:10:35

Message: 10 of 15

Hi Chris,

Just to let you know, I've put an improved method of plotting 3D logical volumes using a patch on the file exchange, in case that is any use:

http://www.mathworks.com/matlabcentral/fileexchange/28497-plot-a-3d-logical-array-using-patch

Adam

Subject: Volume of a patch

From: Chris Clark

Date: 18 Aug, 2010 10:42:05

Message: 11 of 15

Hi Adam
Thanks, this code looks very useful.

when i run it however it plots a 2D surface in 3D, is this what it is meant to do or is it meant to plot the 3D Voxel volume?
My code is below:

    fv = struct('faces', kMesh', 'vertices', pMesh');
    const=1000;
    gridX=ceil((max(pMesh(1,:))-min(pMesh(1,:)))*const) %these 3 lines just keep the scaling
    gridY=ceil((max(pMesh(2,:))-min(pMesh(2,:)))*const)
    gridZ=ceil((max(pMesh(3,:))-min(pMesh(3,:)))*const)
    OUTPUTgrid = VOXELISE(gridX,gridY,gridZ,fv);
    NewFigure3D('light', 1);
    PATCH_3Darray(OUTPUTgrid);

"Adam A" <adamaitkenheadNOSPAM@NOSPAMhotmail.com> wrote in message <i4g4hr$2oa$1@fred.mathworks.com>...
> Hi Chris,
>
> Just to let you know, I've put an improved method of plotting 3D logical volumes using a patch on the file exchange, in case that is any use:
>
> http://www.mathworks.com/matlabcentral/fileexchange/28497-plot-a-3d-logical-array-using-patch
>
> Adam

Subject: Volume of a patch

From: Adam A

Date: 18 Aug, 2010 11:27:22

Message: 12 of 15

Hi Chris,

Yes, it's just a fairly simple tool which plots the 2D surface to represent the 3D volume. If you need something which handles 3D volumes, the following might be more like what you're looking for:

http://www.mathworks.co.uk/matlabcentral/fileexchange/21993-viewer3d

Adam


"Chris Clark" <boozelclark@gmail.com> wrote in message <i4gddt$31l$1@fred.mathworks.com>...
> Hi Adam
> Thanks, this code looks very useful.
>
> when i run it however it plots a 2D surface in 3D, is this what it is meant to do or is it meant to plot the 3D Voxel volume?

Subject: Volume of a patch

From: Pinpress

Date: 18 Aug, 2010 12:52:06

Message: 13 of 15

Hi all,

Interesting to see all the discussion on this topic. I actually have a code to calculate the volume given a triangulated surface mesh is available. The code can be easily adapted if a quadrilateral surface is given (divide each quadrilateral element into two triangles). In order for the code to work, we assume that the surface mesh is regular (no self-intersection), surface normals are consistent (either all pointing inward or outward, but not a mixture). Also, assumes that the density is identical (otherwise it's much more difficult). The code follows. It doesn't need you to upgrade to higher Matlab versions.

Cheers!

function vol = volumeTri(nod, tri)
%
% function vol = volumeTri(nod, tri);
%
% Program that computes the volume of the enclosed domain given by the
% triangulated surface mesh. The input surface mesh must have the surface
% normal consistently either pointing outward (vol>0) or inward (vol<0).
%
% Pinpress; 10/1/2007.


v0 = nod(tri(:,1),:);
v1 = nod(tri(:,2),:);
v2 = nod(tri(:,3),:);

vol = cross(v1,v2, 2);
vol = dot(v0, vol, 2);
vol = sum(vol)/6;

Subject: Volume of a patch

From: Adam A

Date: 18 Aug, 2010 13:47:22

Message: 14 of 15

Hi Pinpress,

That's a nice piece of code, very elegant and works well for the meshes I tried it on. Both your method and the method by Luigi Giaccari (in one of the links up above) are definitely the best ways to calculate the volume as long as the normals are consistent.

The voxelisation method is much slower and will be less accurate - it's only really useful as a backup for cases where the normals are not consistent for whatever reason.

Adam

Subject: Volume of a patch

From: Chris Clark

Date: 18 Aug, 2010 18:31:05

Message: 15 of 15

Hi
Thanks for all the help.
I figured out how to plot a volume of voxels represented by a matrix of logicals. The code is below in case any one else needs it ever.

D = VoxelMatrix;
[x y z D] = subvolume(D, [nan nan nan nan nan nan]);
p = patch(isosurface(x,y,z,D, 0), 'FaceColor', 'red', 'EdgeColor', 'none');
isonormals(x,y,z,D,p);

"Adam A" <adamaitkenheadNOSPAM@NOSPAMhotmail.com> wrote in message <i4go9a$iud$1@fred.mathworks.com>...
> Hi Pinpress,
>
> That's a nice piece of code, very elegant and works well for the meshes I tried it on. Both your method and the method by Luigi Giaccari (in one of the links up above) are definitely the best ways to calculate the volume as long as the normals are consistent.
>
> The voxelisation method is much slower and will be less accurate - it's only really useful as a backup for cases where the normals are not consistent for whatever reason.
>
> Adam

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us