TriangleNet.Mesh.Flip C# (CSharp) Method

Flip() private method

Transform two triangles to two different triangles by flipping an edge counterclockwise within a quadrilateral.
Imagine the original triangles, abc and bad, oriented so that the shared edge ab lies in a horizontal plane, with the vertex b on the left and the vertex a on the right. The vertex c lies below the edge, and the vertex d lies above the edge. The 'flipedge' handle holds the edge ab of triangle abc, and is directed left, from vertex a to vertex b. The triangles abc and bad are deleted and replaced by the triangles cdb and dca. The triangles that represent abc and bad are NOT deallocated; they are reused for dca and cdb, respectively. Hence, any handles that may have held the original triangles are still valid, although not directed as they were before. Upon completion of this routine, the 'flipedge' handle holds the edge dc of triangle dca, and is directed down, from vertex d to vertex c. (Hence, the two triangles have rotated counterclockwise.) WARNING: This transformation is geometrically valid only if the quadrilateral adbc is convex. Furthermore, this transformation is valid only if there is not a subsegment between the triangles abc and bad. This routine does not check either of these preconditions, and it is the responsibility of the calling routine to ensure that they are met. If they are not, the streets shall be filled with wailing and gnashing of teeth. Terminology A "local transformation" replaces a small set of triangles with another set of triangles. This may or may not involve inserting or deleting a vertex. The term "casing" is used to describe the set of triangles that are attached to the triangles being transformed, but are not transformed themselves. Think of the casing as a fixed hollow structure inside which all the action happens. A "casing" is only defined relative to a single transformation; each occurrence of a transformation will involve a different casing.
private Flip ( TriangleNet.Data.Otri &flipedge ) : void
flipedge TriangleNet.Data.Otri Handle to the edge that will be flipped.
return void
        internal void Flip(ref Otri flipedge)
        {
            Otri botleft = default(Otri), botright = default(Otri);
            Otri topleft = default(Otri), topright = default(Otri);
            Otri top = default(Otri);
            Otri botlcasing = default(Otri), botrcasing = default(Otri);
            Otri toplcasing = default(Otri), toprcasing = default(Otri);
            Osub botlsubseg = default(Osub), botrsubseg = default(Osub);
            Osub toplsubseg = default(Osub), toprsubseg = default(Osub);
            Vertex leftvertex, rightvertex, botvertex;
            Vertex farvertex;

            // Identify the vertices of the quadrilateral.
            rightvertex = flipedge.Org();
            leftvertex = flipedge.Dest();
            botvertex = flipedge.Apex();
            flipedge.Sym(ref top);

            // SELF CHECK

            //if (top.triangle == dummytri)
            //{
            //    logger.Error("Attempt to flip on boundary.", "Mesh.Flip()");
            //    flipedge.LnextSelf();
            //    return;
            //}

            //if (checksegments)
            //{
            //    flipedge.SegPivot(ref toplsubseg);
            //    if (toplsubseg.ss != dummysub)
            //    {
            //        logger.Error("Attempt to flip a segment.", "Mesh.Flip()");
            //        flipedge.LnextSelf();
            //        return;
            //    }
            //}

            farvertex = top.Apex();

            // Identify the casing of the quadrilateral.
            top.Lprev(ref topleft);
            topleft.Sym(ref toplcasing);
            top.Lnext(ref topright);
            topright.Sym(ref toprcasing);
            flipedge.Lnext(ref botleft);
            botleft.Sym(ref botlcasing);
            flipedge.Lprev(ref botright);
            botright.Sym(ref botrcasing);
            // Rotate the quadrilateral one-quarter turn counterclockwise.
            topleft.Bond(ref botlcasing);
            botleft.Bond(ref botrcasing);
            botright.Bond(ref toprcasing);
            topright.Bond(ref toplcasing);

            if (checksegments)
            {
                // Check for subsegments and rebond them to the quadrilateral.
                topleft.SegPivot(ref toplsubseg);
                botleft.SegPivot(ref botlsubseg);
                botright.SegPivot(ref botrsubseg);
                topright.SegPivot(ref toprsubseg);

                if (toplsubseg.seg == Mesh.dummysub)
                {
                    topright.SegDissolve();
                }
                else
                {
                    topright.SegBond(ref toplsubseg);
                }

                if (botlsubseg.seg == Mesh.dummysub)
                {
                    topleft.SegDissolve();
                }
                else
                {
                    topleft.SegBond(ref botlsubseg);
                }

                if (botrsubseg.seg == Mesh.dummysub)
                {
                    botleft.SegDissolve();
                }
                else
                {
                    botleft.SegBond(ref botrsubseg);
                }

                if (toprsubseg.seg == Mesh.dummysub)
                {
                    botright.SegDissolve();
                }
                else
                {
                    botright.SegBond(ref toprsubseg);
                }
            }

            // New vertex assignments for the rotated quadrilateral.
            flipedge.SetOrg(farvertex);
            flipedge.SetDest(botvertex);
            flipedge.SetApex(rightvertex);
            top.SetOrg(botvertex);
            top.SetDest(farvertex);
            top.SetApex(leftvertex);
        }