Example #1
0
    //associate each pair of halfedges to a physical edge.
    void createEdges(List <HE_HalfEdge> halfEdges, List <HE_Edge> target)
    {
        int n = halfEdges.Count;

        for (int i = 0; i < n; i++)
        {
            HE_HalfEdge he = halfEdges [i];
            for (int j = 0; j < n; j++)
            {
                if (i != j)
                {
                    HE_HalfEdge he2 = halfEdges [j];
                    if (he.pair == he2)
                    {
                        HE_Edge e = new HE_Edge();
                        e.halfEdge = he;
                        target.Add(e);
                        he.edge  = e;
                        he2.edge = e;
                        break;
                    }
                }
            }
        }
    }
Example #2
0
    //go through all the halfedges and find matching pairs
    void pairHalfEdges(List <HE_HalfEdge> halfEdges)
    {
        int n = halfEdges.Count;

        for (int i = 0; i < n; i++)
        {
            HE_HalfEdge he = halfEdges [i];
            if (he.pair == null)
            {
                for (int j = 0; j < n; j++)
                {
                    if (i != j)
                    {
                        HE_HalfEdge he2 = halfEdges [j];
                        if ((he2.pair == null) && (he.vert == he2.next.vert) && (he2.vert == he.next.vert))
                        {
                            he.pair  = he2;
                            he2.pair = he;
                            break;
                        }
                    }
                }
            }
        }
    }
Example #3
0
        /// <summary>
        /// Calculates the midpoint of the specifiec edge.
        /// </summary>
        /// <returns>The point.</returns>
        /// <param name="edge">Edge.</param>
        public static Point3d MidPoint(HE_Edge edge)
        {
            HE_HalfEdge halfEdge = edge.HalfEdge;
            Point3d     a        = halfEdge.Vertex;
            Point3d     b        = halfEdge.Twin.Vertex;

            return((a + b) / 2);
        }
Example #4
0
    // get clone
    public HE_Mesh get()
    {
        HE_Mesh result = new HE_Mesh();

        reindex();

        for (int i = 0; i < vertices.Count; i++)
        {
            result.vertices.Add((vertices [i]).getClone());
        }

        for (int i = 0; i < faces.Count; i++)
        {
            result.faces.Add(new HE_Face());
        }
        for (int i = 0; i < halfEdges.Count; i++)
        {
            result.halfEdges.Add(new HE_HalfEdge());
        }
        for (int i = 0; i < edges.Count; i++)
        {
            result.edges.Add(new HE_Edge());
        }
        //
        for (int i = 0; i < vertices.Count; i++)
        {
            HE_Vertex sv = vertices [i];
            HE_Vertex tv = result.vertices [i];
            tv.halfEdge = result.halfEdges [sv.halfEdge.id];
        }
        for (int i = 0; i < faces.Count; i++)
        {
            HE_Face sf = faces [i];
            HE_Face tf = result.faces [i];
            tf.id       = i;
            tf.halfEdge = result.halfEdges [sf.halfEdge.id];
        }
        for (int i = 0; i < edges.Count; i++)
        {
            HE_Edge se = edges [i];
            HE_Edge te = result.edges [i];
            te.halfEdge = result.halfEdges [se.halfEdge.id];
            te.id       = i;
        }
        for (int i = 0; i < halfEdges.Count; i++)
        {
            HE_HalfEdge she = halfEdges [i];
            HE_HalfEdge the = result.halfEdges [i];
            the.pair = result.halfEdges [she.pair.id];
            the.next = result.halfEdges [she.next.id];
            the.prev = result.halfEdges [she.prev.id];
            the.vert = result.vertices [she.vert.id];
            the.face = result.faces [she.face.id];
            the.edge = result.edges [she.edge.id];
            the.id   = i;
        }
        return(result);
    }
Example #5
0
    HE_Mesh getDual()
    {
        HE_Mesh result = new HE_Mesh();

        reindex();
        for (int i = 0; i < faces.Count; i++)
        {
            HE_Face     f          = faces [i];
            HE_HalfEdge he         = f.halfEdge;
            PVector     faceCenter = new PVector();
            int         n          = 0;
            do
            {
                faceCenter.add(he.vert);
                he = he.next;
                n++;
            } while(he != f.halfEdge);

            faceCenter.div(n);
            result.vertices.Add(new HE_Vertex(faceCenter.x, faceCenter.y, faceCenter.z, i));
        }
        //for(int i=0;i<vertices.Count;i++){
        //HE_Vertex v=getVertex(i);
        foreach (HE_Vertex v in vertices)
        {
            HE_HalfEdge        he            = v.halfEdge;
            HE_Face            f             = he.face;
            List <HE_HalfEdge> faceHalfEdges = new List <HE_HalfEdge> ();
            HE_Face            nf            = new HE_Face();
            result.faces.Add(nf);
            do
            {
                HE_HalfEdge hen = new HE_HalfEdge();
                faceHalfEdges.Add(hen);
                hen.face = nf;
                hen.vert = result.vertices [f.id];
                if (hen.vert.halfEdge == null)
                {
                    hen.vert.halfEdge = hen;
                }
                if (nf.halfEdge == null)
                {
                    nf.halfEdge = hen;
                }
                he = he.pair.next;
                f  = he.face;
            } while(he != v.halfEdge);

            cycleHalfEdges(faceHalfEdges, false);
            result.halfEdges.AddRange(faceHalfEdges);
        }
        result.pairHalfEdges(result.halfEdges);
        result.createEdges(result.halfEdges, result.edges);
        result.reindex();
        return(result);
    }
Example #6
0
        /// <summary>
        /// Computes the cotangent of the angle opposite to a halfedge.
        /// </summary>
        /// <returns>The cotan.</returns>
        /// <param name="hE">H e.</param>
        public static double Cotan(HE_HalfEdge hE)
        {
            if (hE.onBoundary)
            {
                return(0.0);
            }

            Vector3d u = Vector(hE.Prev);
            Vector3d v = -Vector(hE.Next);

            return(u.Dot(v) / u.Cross(v).Length);
        }
Example #7
0
    public void buildMesh(float[][] simpleVertices, int[][] simpleFaces)
    {
        /*
         * vertices = new List<HE_Vertex>();
         * faces=new List<HE_Face>();
         * halfEdges=new List<HE_HalfEdge>();
         * edges=new List<HE_Edge>();
         */
        vertices.Clear();
        faces.Clear();
        halfEdges.Clear();
        edges.Clear();

        //Add all input vertices to the mesh, the original index of the vertex is stored as an id.
        for (int i = 0; i < simpleVertices.Length; i++)
        {
            vertices.Add(new HE_Vertex(simpleVertices [i] [0], simpleVertices [i] [1], simpleVertices [i] [2], i));
        }

        //Create a loop of halfedges for each face. We assume the vertices are given in a consistent order.
        // To extend this for a non-ordered list, sort the vertices of the input vertices here.
        HE_HalfEdge he;

        for (int i = 0; i < simpleFaces.Length; i++)
        {
            List <HE_HalfEdge> faceEdges = new List <HE_HalfEdge> ();
            HE_Face            hef       = new HE_Face();
            faces.Add(hef);
            //TODO: sort face vertices here
            for (int j = 0; j < simpleFaces[i].Length; j++)
            {
                he = new HE_HalfEdge();
                faceEdges.Add(he);
                he.face = hef;
                if (hef.halfEdge == null)
                {
                    hef.halfEdge = he;
                }
                he.vert = vertices [simpleFaces [i] [j]];
                if (he.vert.halfEdge == null)
                {
                    he.vert.halfEdge = he;
                }
            }
            cycleHalfEdges(faceEdges, false);
            halfEdges.AddRange(faceEdges);
        }
        //associate each halfedge with its pair (belonging to adjacent face)
        pairHalfEdges(halfEdges);
        //associate each pair of halfedges to a physical edge
        createEdges(halfEdges, edges);
        reindex();
    }
Example #8
0
        /// <summary>
        /// Compute the centroid of the specified face
        /// </summary>
        /// <returns>The centroid.</returns>
        /// <param name="face">Face.</param>
        public static Point3d Centroid(HE_Face face)
        {
            HE_HalfEdge hE = face.HalfEdge;
            Point3d     a  = hE.Vertex;
            Point3d     b  = hE.Next.Vertex;
            Point3d     c  = hE.Prev.Vertex;

            if (face.isBoundaryLoop())
            {
                return((a + b) / 2);
            }

            return((a + b + c) / 3);
        }
Example #9
0
        /// <summary>
        /// Computes the signed angle (in radians) between the faces adjacent to the specified half-edge.
        /// </summary>
        /// <returns>The angle (in radians) between faces.</returns>
        /// <param name="hE">H e.</param>
        public static double DihedralAngle(HE_HalfEdge hE)
        {
            if (hE.onBoundary || hE.Twin.onBoundary)
            {
                return(0.0);
            }

            Vector3d n1 = FaceNormal(hE.Face);
            Vector3d n2 = FaceNormal(hE.Twin.Face);
            Vector3d w  = Vector(hE).Unit();

            double cosTheta = n1.Dot(n2);
            double sinTheta = n1.Cross(n2).Dot(w);

            return(Math.Atan2(sinTheta, cosTheta));
        }
Example #10
0
        /// <summary>
        /// Compute the circumcenter the specified face.
        /// </summary>
        /// <returns>The circumcenter.</returns>
        /// <param name="face">Face.</param>
        public static Point3d Circumcenter(HE_Face face)
        {
            HE_HalfEdge hE = face.HalfEdge;

            Point3d a = hE.Vertex;
            Point3d b = hE.Next.Vertex;
            Point3d c = hE.Prev.Vertex;

            if (face.isBoundaryLoop())
            {
                return((a + b) / 2);
            }

            Vector3d ac = c - a;
            Vector3d ab = b - a;
            Vector3d w  = ab.Cross(ac);

            Vector3d u = (w.Cross(ab)) * ac.Length2;
            Vector3d v = (ac.Cross(w)) * ab.Length2;

            Point3d x = (u + v) / (2 * w.Length2);

            return(x + a);
        }
Example #11
0
 /// <summary>
 /// Calculate the vector of a specified half-edge.
 /// </summary>
 /// <returns>The half-edge vector.</returns>
 /// <param name="halfEdge">Half edge.</param>
 public static Vector3d Vector(HE_HalfEdge halfEdge) => halfEdge.Vertex - halfEdge.Next.Vertex;
Example #12
0
    // draw as a triangular mesh.
    public Triangle3D draw()
    {
        Triangle3D triangle3d = new Triangle3D();

        for (int i = 0; i < faces.Count; i++)
        {
            HE_Face     face     = faces [i];
            HE_HalfEdge halfEdge = face.halfEdge;
            HE_Vertex   midFace  = new HE_Vertex(0, 0, 0, 0);
            int         c        = 0;
            do
            {
                HE_Vertex v = halfEdge.vert;
                midFace.x += v.x;
                midFace.y += v.y;
                midFace.z += v.z;
                halfEdge   = halfEdge.next;
                c++;
            } while(halfEdge != face.halfEdge);
            midFace.x /= c;
            midFace.y /= c;
            midFace.z /= c;
            halfEdge   = face.halfEdge;

            HE_Vertex vv;
            do
            {
                HE_Vertex v0 = halfEdge.vert;
                HE_Vertex v1 = halfEdge.next.vert;

                triangle3d.vertices.Add(midFace);
                triangle3d.vertices.Add(v1);
                triangle3d.vertices.Add(v0);

                halfEdge = halfEdge.next;
            } while(halfEdge != face.halfEdge);

            //beginShape(TRIANGLE_STRIP);

            /*
             * GL.Begin(GL.TRIANGLE_STRIP);
             * HE_Vertex vv;
             * do{
             *      vv=halfEdge.vert;
             *      GL.Vertex3(vv.x,vv.y,vv.z);
             *      GL.Vertex3(midFace.x,midFace.y,midFace.z);
             *      halfEdge= halfEdge.next;
             * }
             * while(halfEdge!=face.halfEdge);
             * vv=halfEdge.vert;
             * GL.Vertex3(vv.x,vv.y,vv.z);
             * //endShape();
             * GL.End();
             */

            /*
             * HE_Vertex vv;
             * do{
             *      vv=halfEdge.vert;
             *      //GL.Vertex3(vv.x,vv.y,vv.z);
             *      //GL.Vertex3(midFace.x,midFace.y,midFace.z);
             *      triangle3d.vertices.Add(vv);
             *      triangle3d.vertices.Add(midFace);
             *
             *      halfEdge= halfEdge.next;
             * }
             * while(halfEdge!=face.halfEdge);
             * vv=halfEdge.vert;
             *
             * //GL.Vertex3(vv.x,vv.y,vv.z);
             * triangle3d.vertices.Add(vv);
             */
        }

        return(triangle3d);
    }
Example #13
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();
    }
Example #14
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();
        }
    }
Example #15
0
        /// <summary>
        /// Compute the intersection between a mesh face perimeter and a ray tangent to the face.
        /// </summary>
        /// <param name="ray">The tangent ray.</param>
        /// <param name="Face">The mesh face.</param>
        /// <param name="result">The resulting intersection point.</param>
        /// <param name="halfEdge">The half-edge on where the intersection lies.</param>
        /// <returns></returns>
        public static ISRayFacePerimeter RayFacePerimeter(Ray ray, HE_Face Face, out Point3d result, out HE_HalfEdge halfEdge)
        {
            Vector3d faceNormal = HE_MeshGeometry.FaceNormal(Face);
            Vector3d biNormal   = Vector3d.CrossProduct(ray.Direction, faceNormal);

            Plane perpPlane = new Plane(ray.Origin, ray.Direction, faceNormal, biNormal);

            List <HE_Vertex> vertices = Face.adjacentVertices();

            Point3d temp = new Point3d();

            Line line = new Line(vertices[0], vertices[1]);

            if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point)
            {
                result = null; halfEdge = null; return(ISRayFacePerimeter.Point);
            }                                                                                                                                   // No intersection found
            if (temp != ray.Origin && temp != null)
            {
                result = temp; halfEdge = null; return(ISRayFacePerimeter.Point);
            }                                                                                                            // Intersection found

            line = new Line(vertices[1], vertices[2]);
            if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point)
            {
                result = null; halfEdge = null; return(ISRayFacePerimeter.NoIntersection);
            }                                                                                                                                            // No intersection found
            if (temp != ray.Origin && temp != null)
            {
                result = temp; halfEdge = null; return(ISRayFacePerimeter.Point);
            }                                                                                                            // Intersection found

            line = new Line(vertices[2], vertices[0]);
            if (LinePlane(line, perpPlane, out temp) != ISLinePlane.Point)
            {
                result = null; halfEdge = null; return(ISRayFacePerimeter.NoIntersection);
            }
            if (temp != ray.Origin && temp != null)
            {
                result = temp; halfEdge = null; return(ISRayFacePerimeter.Point);
            }
            else
            {
                result = null; halfEdge = null; return(ISRayFacePerimeter.Error);
            }
        }