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.71k stars 384 forks source link

MeshBoolean Intersection? #130

Open djohansing opened 4 years ago

djohansing commented 4 years ago

I am using the MeshBoolean function in the geometry3Sharp library. I am interested in the intersection, but it seems to return the union. Can you give me any insight as to how to obtain the intersection? Appreciate the help, thanks!

djohansing commented 4 years ago

FYI: I figured this out myself, posting here for others to use.

If anyone finds a more efficient method, please reply.

    public static (g3.DMesh3 resultMesh, double volume, double area) MeshIntersect(this g3.DMesh3 dMesh1, g3.DMesh3 dMesh2)
    {
        var ar1 = new gs.MeshAutoRepair(dMesh1);
        ar1.Apply();
        var ar2 = new gs.MeshAutoRepair(dMesh2);
        ar2.Apply();

        var meshMeshCut = new g3.MeshMeshCut() { Target = ar1.Mesh, CutMesh = ar2.Mesh };
        meshMeshCut.Compute();

        var h1 = meshMeshCut.Target.GetIntersectingTriangles(meshMeshCut.CutMesh);

        var meshMeshCut2 = new g3.MeshMeshCut() { Target = ar2.Mesh, CutMesh = ar1.Mesh };
        meshMeshCut2.Compute();

        var h2 = meshMeshCut2.Target.GetIntersectingTriangles(meshMeshCut2.CutMesh);

        var r1 = new gs.MeshAutoRepair(g3.MeshEditor.Combine(new g3.DMesh3[] { h1, h2 }));
        r1.Apply();

        var volArea = g3.MeshMeasurements.VolumeArea(r1.Mesh, r1.Mesh.TriangleIndices(), r1.Mesh.GetVertex);

        return (r1.Mesh, volArea.x, volArea.y);
    }

    private static g3.DMesh3 GetIntersectingTriangles(this g3.DMesh3 mesh, g3.DMesh3 cutMesh)
    {
        var hMesh = new g3.DMesh3(mesh);
        g3.DMeshAABBTree3 spatial2 = new g3.DMeshAABBTree3(cutMesh, true);
        spatial2.WindingNumber(g3.Vector3d.Zero);
        g3.SafeListBuilder<int> keepT1 = new g3.SafeListBuilder<int>();
        g3.gParallel.ForEach(hMesh.TriangleIndices(), (tid) => {
            g3.Vector3d v = hMesh.GetTriCentroid(tid);
            if (spatial2.WindingNumber(v) > 0.9)
                keepT1.SafeAdd(tid);
        });
        var keepT2 = keepT1.Result.ToDictionary(i => i, i => true);
        g3.MeshEditor.RemoveTriangles(hMesh, hMesh.TriangleIndices().Where(tid => !keepT2.ContainsKey(tid)).ToList());
        return hMesh;
    }
CBenghi commented 4 years ago

Hi @djohansing, I've got not idea if my solution is any better than this, but if you want to have a look here's the link: https://github.com/CBenghi/geometry3Sharp/commit/acb4c05061a6677a15099a8acd7701adc2cde588 Best, Claudio

djohansing commented 4 years ago

Very good ... I will test this out within my solution once an updated Nuget package is available. I am very interested if there are some speed improvements and will most likely do some bench-marking assuming the output is the same.