Volumes and moments of inertia of meshes in 3D
When Mathematica gives correct surface area and volume of zero, what you have is 2-manifold embedded in 3D space, not a solid. It is like the difference between a Sphere
and Ball
.
Area[Sphere[]]
4 π
Volume[Sphere[]]
0
Area[Ball[]]
∞
Volume[Ball[]]
(4 π)/3
Area[RegionBoundary[Ball[]]]
4 π
Update
box =
MeshRegion[
{{1., -3., -2.}, {1., -3., 2.}, {-1., -3., 2.}, {-1., -3., -2.},
{1., 3., -2.}, {-1., 3., -2.}, {-1., 3., 2.}, {1., 3., 2.}},
{Polygon[
{{1, 3, 4}, {5, 7, 8}, {1, 8, 2}, {2, 7, 3}, {3, 6, 4}, {5, 4, 6},
{3, 1, 2}, {7, 5, 6}, {8, 1, 5}, {7, 2, 8}, {6, 3, 7}, {4, 5, 1}}]}]
RegionDimension @ box
2
This confirms you have a hollow box; a solid brick would give 3.
2nd Update
You can generate a brick from a box with DelaunayMesh
.
brick = DelaunayMesh @ MeshCoordinates[box]
RegionDimension @ brick
3
Volume[brick]
48
MomentOfInertia[brick] // Chop
{{208., 0, 0}, {0, 80., 0}, {0, 0, 160.}}
If the mesh is a triangle mesh, the "Stokes theorem" can be applied in the following way:
M = Import["https://filebin.ca/3TcNMJskChjW/one_two_three_cuboid.obj"];
With[{triangles = Partition[MeshCoordinates[M][[Flatten[MeshCells[M, 2][[All, 1]]]]], 3]},
Total[Det /@ triangles]/6.
]
(* 48. *)
But the easiest way will be to transform your mesh into a BoundaryMeshRegion
.
B = BoundaryMeshRegion[MeshCoordinates[M], MeshCells[M, 2]];
Volume[B]
MomentOfInertia[B]
(* 48. *)
(* {{208., 3.74847*10^-6, -3.57628*10^-6}, {3.74847*10^-6,80., -6.49028*10^-6}, {-3.57628*10^-6, -6.49028*10^-6, 160.}} *)
You can import OBJ files directly as BoundaryMeshRegion's
In[5]:= RegionDimension@Import["https://filebin.ca/3TcNMJskChjW/one_two_three_cuboid.obj",
"BoundaryMeshRegion"]
Out[5]= 3
This is documented on ref/format/OBJ.