gradientspace / geometry3Sharp

C# library for 2D/3D geometric computation, mesh algorithms, and so on. Boost license.
http://www.gradientspace.com
Boost Software License 1.0
1.69k stars 380 forks source link

Example of mesh volume calculation #194

Closed bairog closed 1 year ago

bairog commented 1 year ago

Hello, @rms80. Could you provide a sample code to compute a mesh volume (using MeshMeasurements class or somehow else)? Even geometry3SharpDemos repo lacks this piece of code. Thank you.

nsmela commented 1 year ago

Here's the methods I used:

 public static double CalculateVolume(DMesh3 mesh) {
            double volume = 0f;

            if (mesh != null) {
                Point3D p1, p2, p3;
                foreach (var triangle in mesh.Triangles()) {
                    var v = new Vector3d(mesh.GetVertex(triangle.a));
                    p1 = new Point3D(v.x, v.y, v.z);

                    v = new Vector3d(mesh.GetVertex(triangle.b));
                    p2 = new Point3D(v.x, v.y, v.z);

                    v = new Vector3d(mesh.GetVertex(triangle.c));
                    p3 = new Point3D(v.x, v.y, v.z);

                    volume += SignedVolumeOfTriangle(p1, p2, p3);
                }

            }

            return volume / 1000;
        }

        public static string CalculateVolumeText(DMesh3 mesh) {
            var volume = CalculateVolume(mesh);
            return volume.ToString("0.00");
        }

        /// <summary>
        /// calculates volume of a triangle. signed so that negative volumes exist, easing the calculation
        /// </summary>
        private static double SignedVolumeOfTriangle(Point3D p1, Point3D p2, Point3D p3) {
            var v321 = p3.X * p2.Y * p1.Z;
            var v231 = p2.X * p3.Y * p1.Z;
            var v312 = p3.X * p1.Y * p2.Z;
            var v132 = p1.X * p3.Y * p2.Z;
            var v213 = p2.X * p1.Y * p3.Z;
            var v123 = p1.X * p2.Y * p3.Z;
            return (1.0f / 6.0f) * (-v321 + v231 + v312 - v132 - v213 + v123);
        }
    }
bairog commented 1 year ago

@nsmela Thank you, working like a charm.

nsmela commented 1 year ago

I've since found the proper way:

Mesh is a DMesh3 object

Vector2d volumeArea = MeshMeasurements.VolumeArea(Mesh, Mesh.TriangleIndices(), Mesh.GetVertex); volumeArea.x is the volume in microliters