I have a question regarding computation of volume of an irregular shape. I have looked around Mathematica -StackExchange but I could not find a solution which suits me the best. Problem Description: I have the coordinates of the nodes on the surface of my body , which looks like this (image from Abaqus)
In the end I want to compute the Volume of the body. I strated of with ConvexHull and DelaunyMesh to compute my volume. But this was overestimating the volume and the hull lokked like this
After looking around (a lot) on stackexchange, I used the code from Simon Wood.
DataIn = AA[[All, {2, 3, 4}]]
points = DeleteDuplicates[DataIn]
pts, tetrahedra} = TetGenDelaunay[points]
csr[{aa_, bb_, cc_, dd_}] := With[{a = aa - dd, b = bb - dd, c = cc - dd}, Norm[a.a Cross[b, c] + b.b Cross[c, a] + c.c Cross[a, b]]/(2 Norm[a.Cross[b, c]])]
radii = csr[pts[[#]]] & /@ tetrahedra
alphashape[rmax_] := Pick[tetrahedra, radii, r_ /; r < rmax]
faces[tetras_] := Flatten[tetras /. {a_, b_, c_, d_} :> {{a, b, c}, {a, b, d}, {a, c, d}, {b, c, d}}, 1]
externalfaces[faces_] := Cases[Tally[Sort /@ faces], {face_, 1} :> face]
polys = externalfaces@faces@alphashape[0.5];
Gr = Graphics3D[GraphicsComplex[pts, Polygon@polys], Axes -> True, BoxRatios -> Automatic , Boxed -> True];
I played around a bit with the alphashape rmax value to get a decent image as below
Once I got this fit, I believed it was a cake walk to obtain volume, but I was too optimistic.
I used BoundaryDiscretizeGraphics@Show@DiscretizeGraphics[Gr]
to generate a boundary discretization, from which I thought I could create a boundaryregion mesh and get the volume. The DiscretizeGraphics[Gr]
seemed to work, but not BoundaryDiscretizeGraphics
. It returned the following without an error -
I was able to use RegionMesh
directly on DiscretizeGraphics[Gr]
, but it created 6 surfaces with 2D elements and returned TotalSurfaceArea of 6.3
. I expect the volume to be around 1.2
. It would be great if someone could help me out here.
Unlike the image below, I have solids wich are not symmetric about any axis. All the surfaces have the Periodic Wave (Like the Top and Bottom Surface of this problem). Is there an effecient way to compute the volume of such non-convex solids.
I have uploaded the coordinates data file here and here.
Thank You!
Edit 1
I had also used a form of shoelace method to compute the volume (I took this code from one of the post here, I lost the reference unfortunately)
Disc = DiscretizeGraphics[Gr]
Total@With[{coords = MeshCoordinates[Disc]}, MeshCells[Disc, 2] /. Polygon[{a_, b_, c_}] :-> coords[[a]].Cross[coords[[b]], coords[[c]]]]/6
This returned a value 0.0256571
Based on @george2079's suggestion for a similar method here , I obtained the same value but with a nagative sign. So I suppose I have to relook on how I compute the polys
Edit 2 / A cubersome solution
Just for information, the solid has a big Void on the inside like in the image below
I tried importing the entire (~close to 100000 elements) mesh in to mathematica and fill the void with additional mesh, but didn't succed. So I went back to ABAQUS, extracted the elements and nodes on the Surface, renumbered both elements and nodes to start with 1 , and then used this
mesh = ToBoundaryMesh[ToElementMesh["Coordinates" -> NodeCoords,
"MeshElements" -> {HexahedronElement[ElementCon]}]]
This generated a Quad boundary mesh with 2 boundary surfaces
rd = MeshRegion[ ToElementMesh[mesh, "RegionHoles" -> None]]
gave me a tet mesh and filled the inner region.
Volume@rd
gave me a value of 1.09503
, which seems quite reasonable. I need to repeat this for a cuboid of known volume and check if the method gives the right value. The tedious job for me here is to reorder/renumber my nodes and elements. If I could bypass this, it would save a lot of time for me.
The unordered nodes/elements are here and the ordered ones are here