public halfedge(vertex _P)
 {
     P = _P;
     if (_P.hf_begin == null)
     {
         _P.hf_begin = this;
     }
 }
 public void Clear()
 {
     vertices.Clear();
     faces.Clear();
     halfedges.Clear();
     innerVertices.Clear();
     outerVertices.Clear();
     boundaryStart = null;
 }
        private void Construct(Mesh val)
        {
            int _nVertices = val.Vertices.Count;
            int _nFaces    = val.Faces.Count;

            __orientation   = new orient[_nFaces];
            _faceTable      = new List <face> [_nVertices, _nVertices];
            __halfedgeTable = new halfedge[_nVertices, _nVertices];

            for (int i = 0; i < __orientation.Count(); i++)
            {
                __orientation[i] = orient.unknown;
            }

            for (int i = 0; i < _nVertices; i++)
            {
                var _v = new vertex(i);
                vertices.Add(_v);
            }

            for (int i = 0; i < _nFaces; i++)
            {
                var f  = val.Faces[i];
                var _f = f.IsQuad ? new face(i, f.A, f.B, f.C, f.D) : new face(i, f.A, f.B, f.C);
                faces.Add(_f);
                faceTableAdd(_f);
            }
            //Recursive
            halfEdgeAdd(faces[0]);
            //find pairs
            foreach (var h in halfedges)
            {
                int i = h.P.N;
                int j = h.next.P.N;
                if (__halfedgeTable[i, j] != null)
                {
                    throw new ArgumentOutOfRangeException(";)");
                }
                __halfedgeTable[i, j] = h;
            }
            foreach (var h in halfedges)
            {
                int i = h.P.N;
                int j = h.next.P.N;
                //if boundary edge...
                if (__halfedgeTable[j, i] == null)
                {
                    h.pair = null;
                }
                else
                {
                    h.pair = __halfedgeTable[j, i];
                }
            }
            //post process to find boundary vertices
            foreach (var v in vertices)
            {
                var h = v.hf_begin;
                v.hf_end = h;
                do
                {
                    if (h.prev.isNaked)
                    {
                        v.hf_end = h.prev;
                        while (!h.isNaked)
                        {
                            h = h.pair.next;
                        }
                        v.hf_begin = h;
                        if (this.boundaryStart == null)
                        {
                            this.boundaryStart = v;
                        }
                        break;
                    }
                    h = h.prev.pair;
                } while (h != v.hf_begin);
            }

            //post process to create stars
            foreach (var v in vertices)
            {
                var h = v.hf_begin;
                v.star.Clear();
                do
                {
                    v.star.Add(h);
                    if (h.prev.isNaked)
                    {
                        break;
                    }
                    h = h.prev.pair;
                } while (h != v.hf_begin);
            }
            //post process to create onering
            foreach (var v in vertices)
            {
                var h = v.hf_begin;
                v.onering.Clear();
                do
                {
                    do
                    {
                        h = h.next;
                        v.onering.Add(h);
                    } while (h.next.next.P != v);
                    if (h.next.isNaked)
                    {
                        break;
                    }
                    h = h.next.pair;
                } while (h != v.hf_begin);
            }
            //post process to split the vertices into inner and outer.
            innerVertices.Clear();
            outerVertices.Clear();
            foreach (var v in vertices)
            {
                if (v.hf_begin.isNaked)
                {
                    outerVertices.Add(v);
                }
                else
                {
                    innerVertices.Add(v);
                }
            }
        }