Jeremy,
It is determining the volume and area using the geometry3Sharp library functions after repairing/closing, cutting, determining intersecting triangles, combining, then repairing/closing again.
This is part of a much larger solution, but I can share some additional interop functions used to transition between g3.DMesh3 and Revit API objects. With these, you can start with a Revit API solid or mesh and then call the MeshIntersect method.
public static g3.DMesh3 GetDMesh3(this Mesh mesh)
{
g3.DMesh3Builder meshBuilder = new g3.DMesh3Builder();
meshBuilder.Meshes.Add(new g3.DMesh3());
meshBuilder.SetActiveMesh(0);
meshBuilder.AppendMesh(mesh);
return meshBuilder.Meshes.First();
}
public static g3.DMesh3 GetDMesh3(this Solid solid)
{
g3.DMesh3Builder meshBuilder = new g3.DMesh3Builder();
meshBuilder.Meshes.Add(new g3.DMesh3());
meshBuilder.SetActiveMesh(0);
foreach(Face face in solid.Faces)
{
meshBuilder.AppendMesh(face.Triangulate());
}
return meshBuilder.Meshes.First();
}
public static void AppendMesh(this g3.DMesh3Builder meshBuilder, Mesh mesh)
{
for (int i = 0; i < mesh.NumTriangles; i++)
{
MeshTriangle mt = mesh.get_Triangle(i);
int v0 = meshBuilder.AppendVertex(mt.get_Vertex(0).X, mt.get_Vertex(0).Y, mt.get_Vertex(0).Z);
int v1 = meshBuilder.AppendVertex(mt.get_Vertex(1).X, mt.get_Vertex(1).Y, mt.get_Vertex(1).Z);
int v2 = meshBuilder.AppendVertex(mt.get_Vertex(2).X, mt.get_Vertex(2).Y, mt.get_Vertex(2).Z);
meshBuilder.AppendTriangle(v0, v1, v2);
}
}
public static IList<GeometryObject> GetRevitGeometry(this g3.DMesh3 dMesh)
{
TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
GetFaces(dMesh, builder);
builder.Build();
var result = builder.GetBuildResult();
return result.GetGeometricalObjects();
}
private static void GetFaces(g3.DMesh3 mesh, TessellatedShapeBuilder builder)
{
builder.OpenConnectedFaceSet(true);
foreach (var triangle in mesh.Triangles())
{
var va = mesh.GetVertex(triangle.a);
var vb = mesh.GetVertex(triangle.b);
var vc = mesh.GetVertex(triangle.c);
XYZ v0 = new XYZ(va.x, va.y, va.z);
XYZ v1 = new XYZ(vb.x, vb.y, vb.z);
XYZ v2 = new XYZ(vc.x, vc.y, vc.z);
TessellatedFace tesseFace = new TessellatedFace(new List<XYZ> { v0, v1, v2 }, ElementId.InvalidElementId);
if (builder.DoesFaceHaveEnoughLoopsAndVertices(tesseFace)) builder.AddFace(tesseFace);
}
builder.CloseConnectedFaceSet();
}