private void faceTableAdd(int i, int j, face f)
 {
     if (_faceTable[i, j] == null)
     {
         _faceTable[i, j] = new List <face>();
     }
     _faceTable[i, j].Add(f);
 }
 private void faceTableAdd(face f)
 {
     for (int i = 0; i < f.corner.Count(); i++)
     {
         int I = f.corner[i];
         int J = (i == f.corner.Count() - 1) ? f.corner[0] : f.corner[i + 1];
         faceTableAdd(I, J, f);
     }
 }
        private void halfEdgeAdd(face f)
        {
            var _o = orient.unknown;

            for (int i = 0; i < f.corner.Count(); i++)
            {
                int I = f.corner[i];
                int J = (i == f.corner.Count() - 1) ? f.corner[0] : f.corner[i + 1];
                if (_faceTable[I, J].Count == 2)
                {
                    if (_faceTable[I, J][0] == f)
                    {
                        if (__orientation[_faceTable[I, J][1].N] != orient.unknown)
                        {
                            _o = __orientation[_faceTable[I, J][1].N] == orient.positive ? orient.negative : orient.positive;
                        }
                    }
                    if (_faceTable[I, J][1] == f)
                    {
                        if (__orientation[_faceTable[I, J][0].N] != orient.unknown)
                        {
                            _o = __orientation[_faceTable[I, J][0].N] == orient.positive ? orient.negative : orient.positive;
                        }
                    }
                }
                else
                {
                    if (_faceTable[J, I] != null)
                    {
                        if (__orientation[_faceTable[J, I][0].N] != orient.unknown)
                        {
                            _o = __orientation[_faceTable[J, I][0].N];
                        }
                    }
                }
            }
            __orientation[f.N] = _o == orient.unknown ? orient.positive : _o;
            //register a halfedge
            if (f.corner.Count() == 3 && __orientation[f.N] == orient.positive)
            {
                var he1 = new halfedge(vertices[f.corner[0]]);
                var he2 = new halfedge(vertices[f.corner[1]]);
                var he3 = new halfedge(vertices[f.corner[2]]);
                halfedges.Add(he1);
                halfedges.Add(he2);
                halfedges.Add(he3);
                he1.prev        = he3; he1.next = he2; he1.owner = f;
                he2.prev        = he1; he2.next = he3; he2.owner = f;
                he3.prev        = he2; he3.next = he1; he3.owner = f;
                f.firsthalfedge = he1;
            }

            if (f.corner.Count() == 3 && __orientation[f.N] == orient.negative)
            {
                var he1 = new halfedge(vertices[f.corner[2]]);
                var he2 = new halfedge(vertices[f.corner[1]]);
                var he3 = new halfedge(vertices[f.corner[0]]);
                halfedges.Add(he1);
                halfedges.Add(he2);
                halfedges.Add(he3);
                he1.prev        = he3; he1.next = he2; he1.owner = f;
                he2.prev        = he1; he2.next = he3; he2.owner = f;
                he3.prev        = he2; he3.next = he1; he3.owner = f;
                f.firsthalfedge = he1;
            }

            if (f.corner.Count() == 4 && __orientation[f.N] == orient.positive)
            {
                var he1 = new halfedge(vertices[f.corner[0]]);
                var he2 = new halfedge(vertices[f.corner[1]]);
                var he3 = new halfedge(vertices[f.corner[2]]);
                var he4 = new halfedge(vertices[f.corner[3]]);
                halfedges.Add(he1);
                halfedges.Add(he2);
                halfedges.Add(he3);
                halfedges.Add(he4);
                he1.prev        = he4; he1.next = he2; he1.owner = f;
                he2.prev        = he1; he2.next = he3; he2.owner = f;
                he3.prev        = he2; he3.next = he4; he3.owner = f;
                he4.prev        = he3; he4.next = he1; he4.owner = f;
                f.firsthalfedge = he1;
            }

            if (f.corner.Count() == 4 && __orientation[f.N] == orient.negative)
            {
                var he1 = new halfedge(vertices[f.corner[3]]);
                var he2 = new halfedge(vertices[f.corner[2]]);
                var he3 = new halfedge(vertices[f.corner[1]]);
                var he4 = new halfedge(vertices[f.corner[0]]);
                halfedges.Add(he1);
                halfedges.Add(he2);
                halfedges.Add(he3);
                halfedges.Add(he4);
                he1.prev        = he4; he1.next = he2; he1.owner = f;
                he2.prev        = he1; he2.next = he3; he2.owner = f;
                he3.prev        = he2; he3.next = he4; he3.owner = f;
                he4.prev        = he3; he4.next = he1; he4.owner = f;
                f.firsthalfedge = he1;
            }

            //list up neighbors that are not oriented
            for (int i = 0; i < f.corner.Count(); i++)
            {
                int I = f.corner[i];
                int J = (i == f.corner.Count() - 1) ? f.corner[0] : f.corner[i + 1];
                if (_faceTable[I, J].Count == 2)
                {
                    if (_faceTable[I, J][0] == f)
                    {
                        if (__orientation[_faceTable[I, J][1].N] == orient.unknown)
                        {
                            halfEdgeAdd(_faceTable[I, J][1]);
                        }
                    }
                    if (_faceTable[I, J][1] == f)
                    {
                        if (__orientation[_faceTable[I, J][0].N] == orient.unknown)
                        {
                            halfEdgeAdd(_faceTable[I, J][0]);
                        }
                    }
                }
                else
                {
                    if (_faceTable[J, I] != null)
                    {
                        if (__orientation[_faceTable[J, I][0].N] == orient.unknown)
                        {
                            halfEdgeAdd(_faceTable[J, I][0]);
                        }
                    }
                }
            }
        }