Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boolean operations #5

Open
AlastairShipman1 opened this issue Nov 8, 2022 · 1 comment
Open

Boolean operations #5

AlastairShipman1 opened this issue Nov 8, 2022 · 1 comment

Comments

@AlastairShipman1
Copy link

AlastairShipman1 commented Nov 8, 2022

Hi there! I'm working with your CGAL wrapper (fantastic resource- thanks!), and I'm having some issues with the boolean operations. I think I might just be defining the issue wrong, but was hoping to ask your advice?

I'm trying to find the unique volumes of a set of gameobjects. In order to do this I take the union of all of them, then one by one I intersect the other gameobjects with each other, then finish by taking the difference between the union and the intersected components.

However, for some reason I need to translate the intersections by a small amount to make the DIFFERENCE code work? I wonder if I'm doing something wrong, or there's an issue with the underlying algorithm?

Any help would be really appreciated!


public void PerformVolumetricBooleanOperations(GameObject[] inputGos)
    {
        // in this function we find the union of all the gameobject volumes.
        // we then find the volume that is unique to those volumes.

       
        var boolean = MeshProcessingBoolean<EEK>.Instance;

        // we also need to convert all the gameobjects to cgal polyhedra.
        var polyhedra = new Polyhedron3<EEK>[inputGos.Length];
        for (int i = 0; i < inputGos.Length; i++)
        {
            polyhedra[i] = ConvertGoToPolyhedron(inputGos[i]);
        }


        // now, let's produce a union of all the polyhedra.
        var unionPoly = new Polyhedron3<EEK>();
        for (int i = 0; i < polyhedra.Length; i++)
        {
            if (!boolean.Op(POLYHEDRA_BOOLEAN.UNION, unionPoly, polyhedra[i], out unionPoly))
            {
                Debug.Log("BooleanOperation has failed");// this is probably because one mesh completely encompasses/equals another.
            }
        }
     

        // now we can produce the bits which are unique to each gameobject.
        // to do this, we take the union of all the overlaps between every pairwise combination of gameobjects.
        // once we have this, we can take the difference between this and the union object we calculated above.
        var intersectionsUnion = new Polyhedron3<EEK>();
        for (int i = 0; i < polyhedra.Length; i++)
        {
            var tempPoly = new Polyhedron3<EEK>();
            for (int ii = i + 1; ii < polyhedra.Length; ii++)
            {
                if (boolean.Op(POLYHEDRA_BOOLEAN.INTERSECT, polyhedra[i], polyhedra[ii], out tempPoly))
                {
                    boolean.Op(POLYHEDRA_BOOLEAN.UNION, intersectionsUnion, tempPoly, out intersectionsUnion);
                }
            }
        }
        // there is a bit of an issue with taking the difference between union and intersections. i think it might be because there's too perfect an overlap?. this seems to solve it, but i don't like it.
        intersectionsUnion.Translate(new Vector3d(0.0000001));


        // as a check, you can uncomment the below, and you should see gameobjects appear that are the union, and the union of intersections
        //unionPoly.ToUnityMesh("union of all gameobjects", new Material(Shader.Find("Diffuse")), false);
        //intersectionsUnion.ToUnityMesh("union of all intersections", new Material(Shader.Find("Diffuse")), false);

        var intersectionsUnionInversion = new Polyhedron3<EEK>();
        boolean.Op(POLYHEDRA_BOOLEAN.DIFFERENCE, unionPoly, intersectionsUnion, out intersectionsUnionInversion);
        intersectionsUnionInversion.ToUnityMesh("All unique volumes", new Material(Shader.Find("Diffuse")), false);
    }



    Polyhedron3<EEK> ConvertGoToPolyhedron(GameObject go)
    {
        // this takes a unity gameobject, and turns it into an EEK polyhedron (middle accuracy, middle speed).
        // to convert back, just call .toUnityMesh() on the polyhedron itself.
        Vector3[] unityMeshPoints = go.GetComponent<MeshFilter>().mesh.vertices;
        Point3d[] cgalMeshPoints = new Point3d[unityMeshPoints.Length];
        for (int i = 0; i < unityMeshPoints.Length; i++)
        {
            cgalMeshPoints[i] = unityMeshPoints[i].ToCGALPoint3d();
        }
        var polyhedron = new Polyhedron3<EEK>(cgalMeshPoints, go.GetComponent<MeshFilter>().mesh.triangles);
        polyhedron.Translate(new Point3d(go.transform.position.x, go.transform.position.y, go.transform.position.z));

        return polyhedron;
    }
@ankofl
Copy link

ankofl commented Jul 3, 2024

Project is dead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants