コード例 #1
0
    void splitSurface(Plane P)
    {
        List <HE_Vertex>   newVertices  = new List <HE_Vertex> ();
        List <HE_Face>     newFaces     = new List <HE_Face> ();
        List <HE_HalfEdge> newHalfEdges = new List <HE_HalfEdge> ();
        List <HE_Edge>     newEdges     = new List <HE_Edge> ();

        // get all split edges
        List <SplitEdge> splitEdges = retrieveSplitEdges(P);

        //check if the plane cuts the mesh at all, at least one point should be on the other side of the plane.
        //compared to the first point
        float[] sides = new float[vertices.Count];
        //bool cut=false;
        for (int i = 0; i < vertices.Count; i++)
        {
            HE_Vertex v = vertices [i];
            sides [i] = P.side(v);
            //if(sides[0]*sides[i]<=0f) cut=true;
        }

        //loop through all faces.
        for (int i = 0; i < faces.Count; i++)
        {
            HE_Face          face             = faces [i];
            HE_HalfEdge      halfEdge         = face.halfEdge;
            List <HE_Vertex> newFaceVertices1 = new List <HE_Vertex> ();
            List <HE_Vertex> newFaceVertices2 = new List <HE_Vertex> ();
            List <HE_Vertex> currentFace      = newFaceVertices1;
            //for each face, loop through all vertices and retain the vertices on the correct side. If the edge
            //is cut, insert the new point in the appropriate place.
            do
            {
                currentFace.Add(halfEdge.vert);
                for (int j = 0; j < splitEdges.Count; j++)              // loop through all split edges to check for the current edge.
                {
                    SplitEdge se = (SplitEdge)splitEdges [j];
                    if (halfEdge.edge == se.edge)
                    {
                        newFaceVertices1.Add(se.splitVertex);
                        newFaceVertices2.Add(se.splitVertex);
                        if (currentFace == newFaceVertices1)
                        {
                            currentFace = newFaceVertices2;
                        }
                        else
                        {
                            currentFace = newFaceVertices1;
                        }
                        break;
                    }
                }
                halfEdge = halfEdge.next;
            } while(halfEdge != face.halfEdge);

            //Create a new face form the vertices we retained,ignore degenerate faces with less than 3 vertices.
            //Add all face-related information to the data-structure.

            HE_Face newFace = new HE_Face();
            newFaces.Add(newFace);
            List <HE_HalfEdge> faceEdges = new List <HE_HalfEdge> ();
            for (int j = 0; j < newFaceVertices1.Count; j++)
            {
                HE_Vertex v = newFaceVertices1 [j];
                if (!newVertices.Contains(v))
                {
                    newVertices.Add(v);
                }
                HE_HalfEdge newHalfEdge = new HE_HalfEdge();
                faceEdges.Add(newHalfEdge);
                newHalfEdge.vert = v;

                v.halfEdge       = newHalfEdge;
                newHalfEdge.face = newFace;
                if (newFace.halfEdge == null)
                {
                    newFace.halfEdge = newHalfEdge;
                }
            }
            cycleHalfEdges(faceEdges, false);
            newHalfEdges.AddRange(faceEdges);
            if (newFaceVertices2.Count > 0)
            {
                newFace = new HE_Face();
                newFaces.Add(newFace);
                faceEdges = new List <HE_HalfEdge> ();
                for (int j = 0; j < newFaceVertices2.Count; j++)
                {
                    HE_Vertex v = newFaceVertices2 [j];
                    if (!newVertices.Contains(v))
                    {
                        newVertices.Add(v);
                    }
                    HE_HalfEdge newHalfEdge = new HE_HalfEdge();
                    faceEdges.Add(newHalfEdge);
                    newHalfEdge.vert = v;

                    v.halfEdge       = newHalfEdge;
                    newHalfEdge.face = newFace;
                    if (newFace.halfEdge == null)
                    {
                        newFace.halfEdge = newHalfEdge;
                    }
                }
                cycleHalfEdges(faceEdges, false);
                newHalfEdges.AddRange(faceEdges);

                //}//test
            }

            //Add missing information to the datastructure
            pairHalfEdges(newHalfEdges);
            createEdges(newHalfEdges, newEdges);
        }

        // update the mesh
        vertices  = newVertices;
        faces     = newFaces;
        halfEdges = newHalfEdges;
        edges     = newEdges;
        reindex();
    }
コード例 #2
0
    // Split the mesh in half, retain the part on the same side as the point "center".
    // Works only on a convex mesh !!!
    public void cutMesh(Plane P, PVector center)
    {
        float centerside = P.side(center);

        if (centerside != 0)          // if center is on the plane, we can't decide which part to keep, ignore.
        {
            List <HE_Vertex>   newVertices  = new List <HE_Vertex> ();
            List <HE_Face>     newFaces     = new List <HE_Face> ();
            List <HE_HalfEdge> newHalfEdges = new List <HE_HalfEdge> ();
            List <HE_Edge>     newEdges     = new List <HE_Edge> ();

            // get all split edges
            List <SplitEdge> splitEdges = retrieveSplitEdges(P);

            //check if the plane cuts the mesh at all, at least one point should be on the other side of the plane.
            //compared to the first point
            float[] sides = new float[vertices.Count];
            //bool cut = false;// add inok
            for (int i = 0; i < vertices.Count; i++)
            {
                HE_Vertex v = vertices [i];
                sides [i] = P.side(v);
                //if(sides[0]*sides[i]<=0f) cut=true;// add inok
            }
            //loop through all faces.
            for (int i = 0; i < faces.Count; i++)
            {
                HE_Face          face             = faces [i];
                HE_HalfEdge      halfEdge         = face.halfEdge;
                List <HE_Vertex> newFaceVertices1 = new List <HE_Vertex> ();              // vertices on the correct side.
                List <HE_Vertex> newFaceVertices2 = new List <HE_Vertex> ();              // vertices on the wrong side, not used right now.

                //for each face, loop through all vertices and retain the vertices on the correct side. If the edge
                //is cut, insert the new point in the appropriate place.
                do
                {
                    if (sides [halfEdge.vert.id] * centerside >= 0f)
                    {
                        newFaceVertices1.Add(halfEdge.vert);
                    }
                    if (sides [halfEdge.vert.id] * centerside <= 0f)
                    {
                        newFaceVertices2.Add(halfEdge.vert);
                    }

                    for (int j = 0; j < splitEdges.Count; j++)                    // loop through all split edges to check for the current edge.
                    {
                        SplitEdge se = splitEdges [j];
                        if (halfEdge.edge == se.edge)
                        {
                            newFaceVertices1.Add(se.splitVertex);
                            newFaceVertices2.Add(se.splitVertex);
                            break;
                        }
                    }
                    halfEdge = halfEdge.next;
                } while(halfEdge != face.halfEdge);

                //Create a new face form the vertices we retained,ignore degenerate faces with less than 3 vertices.
                //Add all face-related information to the data-structure.
                if (newFaceVertices1.Count > 2)
                {
                    HE_Face newFace = new HE_Face();
                    newFaces.Add(newFace);
                    List <HE_HalfEdge> faceEdges = new List <HE_HalfEdge> ();
                    for (int j = 0; j < newFaceVertices1.Count; j++)
                    {
                        HE_Vertex v = newFaceVertices1 [j];
                        if (!newVertices.Contains(v))
                        {
                            newVertices.Add(v);
                        }
                        HE_HalfEdge newHalfEdge = new HE_HalfEdge();
                        faceEdges.Add(newHalfEdge);
                        newHalfEdge.vert = v;

                        v.halfEdge       = newHalfEdge;
                        newHalfEdge.face = newFace;
                        if (newFace.halfEdge == null)
                        {
                            newFace.halfEdge = newHalfEdge;
                        }
                    }
                    cycleHalfEdges(faceEdges, false);
                    newHalfEdges.AddRange(faceEdges);
                }
            }

            //Add missing information to the datastructure
            int n = newHalfEdges.Count;
            pairHalfEdges(newHalfEdges);
            createEdges(newHalfEdges, newEdges);

            //Cutting the mesh not only cuts the faces, it also creates one new planar face looping through all new cutpoints(in a convex mesh).
            //This hole in the mesh is identified by unpaired halfedges remaining after the pairibg operation.
            //This part needs to rethought to extend to concave meshes!!!
            List <HE_HalfEdge> unpairedEdges = new List <HE_HalfEdge> ();
            for (int i = 0; i < n; i++)
            {
                HE_HalfEdge he = newHalfEdges [i];
                if (he.pair == null)
                {
                    unpairedEdges.Add(he);
                }
            }
            if (unpairedEdges.Count > 0)
            {
                //Create a closed loop out of the collection of unpaired halfedges and associate a new face with this.
                //Easy to explain with a drawing, beyond my skill with words.
                HE_Face            cutFace   = new HE_Face();
                List <HE_HalfEdge> faceEdges = new List <HE_HalfEdge> ();
                HE_HalfEdge        he        = unpairedEdges [0];
                HE_HalfEdge        hen       = he;
                do
                {
                    HE_HalfEdge _hen = he.next;
                    HE_HalfEdge _hep = he.next.pair;
                    if (_hep != null)                    //add inok
                    {
                        hen = he.next.pair.next;
                        while (!unpairedEdges.Contains(hen))
                        {
                            hen = hen.pair.next;
                        }
                    }
                    else
                    {
                        hen = hen.next;
                        Debug.LogWarning("LogWarning: null");
                    }
                    HE_HalfEdge newhe = new HE_HalfEdge();
                    faceEdges.Add(newhe);
                    if (cutFace.halfEdge == null)
                    {
                        cutFace.halfEdge = newhe;
                    }
                    newhe.vert = hen.vert;
                    newhe.pair = he;
                    he.pair    = newhe;
                    HE_Edge e = new HE_Edge();
                    e.halfEdge = newhe;
                    he.edge    = e;
                    newhe.edge = e;
                    newEdges.Add(e);
                    newhe.face = cutFace;
                    he         = hen;
                } while(hen != unpairedEdges[0]);

                cycleHalfEdges(faceEdges, true);
                newHalfEdges.AddRange(faceEdges);
                newFaces.Add(cutFace);
            }

            // update the mesh
            vertices  = newVertices;
            faces     = newFaces;
            halfEdges = newHalfEdges;

            edges = newEdges;
            reindex();
        }
    }