예제 #1
0
    // Reacreate a unity mesh with vertices, triangles, and normals.
    // TODO: IT NOW ASSUMES A FACE IS A TRIANGLE
    // TODO: FAN TRIANGULATION? Can we assume that all generated faces will be simple convex??
    public Mesh GetMesh()
    {
        Mesh           meshRes       = new Mesh();
        List <int>     meshTriangles = new List <int>();
        List <Vector3> meshVertices  = new List <Vector3>();
        List <Vector3> meshNormals   = new List <Vector3>();
        // Foreach face. Walk it and save the vertex and normal data toghether with triangle indices.
        int triIdx = 0;

        foreach (HEFace face in faces)
        {
            // Each face has a normal and an index into halfEdges
            // Get the face halfedges
            List <short> faceHalfEdges = HalfEdge.FaceHalfEdges(face, halfEdges);
            if (faceHalfEdges.Count != 3)
            {
                Debug.Assert(faceHalfEdges.Count == 3);
            }
            foreach (short i in faceHalfEdges)
            {
                meshVertices.Add(vertices[halfEdges[i].verIndex].v);
                meshNormals.Add(face.normal);
                meshTriangles.Add(triIdx);
                triIdx++;
            }
        }

        meshRes.vertices  = meshVertices.ToArray();
        meshRes.triangles = meshTriangles.ToArray();
        meshRes.normals   = meshNormals.ToArray();
        return(meshRes);
    }
예제 #2
0
    public void Triangulate()
    {
        // Update each face to contain three vertices. Adds new faces when necessary.
        int origFaceCount = faces.Count;

        for (int i = 0; i < origFaceCount; i++)
        {
            List <short> faceEdges = HalfEdge.FaceHalfEdges(faces[i], halfEdges);
            if (faceEdges.Count == 3)
            {
                // Already a triangle
                continue;
            }

            // There are two cases, 4 or 5 vertices, for 4 vertices we can just do it over the diagonal
            if (faceEdges.Count == 4)
            {
                List <short> onPlaneIdx = GetConfigEdges(faces[i], PlaneConfig.On);
                SplitFace(faces[i], halfEdges[onPlaneIdx[0]], halfEdges[halfEdges[halfEdges[onPlaneIdx[0]].nextIndex].nextIndex]);
            }
            else if (faceEdges.Count == 5)
            {
                // Algorithm;
                // Get the two vertices on the plane
                List <short> onPlaneIdx    = GetConfigEdges(faces[i], PlaneConfig.On);
                List <short> leftPlaneIdx  = GetConfigEdges(faces[i], PlaneConfig.Left);
                List <short> rightPlaneIdx = GetConfigEdges(faces[i], PlaneConfig.Right);
                // Either there are two on the left side or on the right side.  (Always 2 On)
                // This will be the left place idx face. We need to create two new half-edges between the on edges
                // Lets say we have l1-l2-o1-r1-o2  then the right triangle is o1-r1-o2
                // Should make a function that takes a face and two vertices (half edges rather) and splits it in two
                List <short> onEdgesIndices = GetConfigEdges(faces[i], PlaneConfig.On);

                SplitFace(faces[i], halfEdges[onEdgesIndices[0]], halfEdges[onEdgesIndices[1]]);
                // TODO: Make a verify function that verifies the half-edge data structure...
                // Check that the new faces are atleast the right size..
                List <short> f1 = HalfEdge.FaceHalfEdges(faces[i], halfEdges);
                List <short> f2 = HalfEdge.FaceHalfEdges(faces[faces.Count - 1], halfEdges);
                // One of the new faces have 4 vertices, so we need to triangulate it / split into two
                if (f1.Count == 4)
                {
                    SplitFace(faces[i], halfEdges[faces[i].heIndex], halfEdges[halfEdges[halfEdges[faces[i].heIndex].nextIndex].nextIndex]);
                }
                else
                {
                    int idx = faces.Count - 1;
                    SplitFace(faces[idx], halfEdges[faces[idx].heIndex], halfEdges[halfEdges[halfEdges[faces[idx].heIndex].nextIndex].nextIndex]);
                }
            }
            else
            {
                // Don't go here...
                // shouldn't be possible
            }
        }
    }
예제 #3
0
    // Return indices of HalfEdges with vertices that have the given config
    List <short> GetConfigEdges(HEFace face, PlaneConfig config)
    {
        List <short> he  = HalfEdge.FaceHalfEdges(face, halfEdges);
        List <short> res = new List <short>();

        foreach (short s in he)
        {
            if (vertices[halfEdges[s].verIndex].config == config)
            {
                res.Add(s);
            }
        }
        return(res);
    }
예제 #4
0
    private string PrintFaceConfig(HEFace face)
    {
        List <short> he   = HalfEdge.FaceHalfEdges(face, halfEdges);
        string       res  = "";
        string       res1 = "face idx: ";

        foreach (short s in he)
        {
            res  += " " + vertices[halfEdges[s].verIndex].config.ToString() + "(" + s + "," + halfEdges[s].nextIndex + ")" + " ";
            res1 += s + ": " + halfEdges[s].faceIndex + ".   ";
        }
        res1 += ".  with face pointing at = " + faces[halfEdges[he[0]].faceIndex].heIndex;
        return(res + "\n" + res1);
    }
예제 #5
0
    private List <short> GetOnVertices(HEFace face)
    {
        List <short> res = new List <short>();
        List <short> he  = HalfEdge.FaceHalfEdges(face, halfEdges);

        foreach (short s in he)
        {
            if (vertices[halfEdges[s].verIndex].config == PlaneConfig.On)
            {
                res.Add(halfEdges[s].verIndex);
            }
        }
        return(res);
    }
예제 #6
0
    private PlaneConfig GetFaceConfig(HEFace face)
    {
        // If any vertex is left / right the whole face is it
        List <short> heIdx = HalfEdge.FaceHalfEdges(face, halfEdges);

        foreach (short s in heIdx)
        {
            if (vertices[halfEdges[s].verIndex].config == PlaneConfig.Left)
            {
                return(PlaneConfig.Left);
            }
            else if (vertices[halfEdges[s].verIndex].config == PlaneConfig.Right)
            {
                return(PlaneConfig.Right);
            }
        }
        return(PlaneConfig.On);
    }