LibTessDotNet.Mesh.Connect C# (CSharp) Method

Connect() public method

Creates a new edge from eOrg->Dst to eDst->Org, and returns the corresponding half-edge eNew. If eOrg->Lface == eDst->Lface, this splits one loop into two, and the newly created loop is eNew->Lface. Otherwise, two disjoint loops are merged into one, and the loop eDst->Lface is destroyed. If (eOrg == eDst), the new face will have only two edges. If (eOrg->Lnext == eDst), the old face is reduced to a single edge. If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.
public Connect ( LibTessDotNet.MeshUtils.Edge eOrg, LibTessDotNet.MeshUtils.Edge eDst ) : LibTessDotNet.MeshUtils.Edge
eOrg LibTessDotNet.MeshUtils.Edge
eDst LibTessDotNet.MeshUtils.Edge
return LibTessDotNet.MeshUtils.Edge
        public MeshUtils.Edge Connect(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
        {
            var eNew = MeshUtils.MakeEdge(eOrg);
            var eNewSym = eNew._Sym;

            bool joiningLoops = false;
            if (eDst._Lface != eOrg._Lface)
            {
                // We are connecting two disjoint loops -- destroy eDst->Lface
                joiningLoops = true;
                MeshUtils.KillFace(eDst._Lface, eOrg._Lface);
            }

            // Connect the new edge appropriately
            MeshUtils.Splice(eNew, eOrg._Lnext);
            MeshUtils.Splice(eNewSym, eDst);

            // Set the vertex and face information
            eNew._Org = eOrg._Dst;
            eNewSym._Org = eDst._Org;
            eNew._Lface = eNewSym._Lface = eOrg._Lface;

            // Make sure the old face points to a valid half-edge
            eOrg._Lface._anEdge = eNewSym;

            if (!joiningLoops)
            {
                MeshUtils.MakeFace(eNew, eOrg._Lface);
            }

            return eNew;
        }

Usage Example

Exemplo n.º 1
0
        /// <summary>
        /// TessellateMonoRegion( face ) tessellates a monotone region
        /// (what else would it do??)  The region must consist of a single
        /// loop of half-edges (see mesh.h) oriented CCW.  "Monotone" in this
        /// case means that any vertical line intersects the interior of the
        /// region in a single interval.
        ///
        /// Tessellation consists of adding interior edges (actually pairs of
        /// half-edges), to split the region into non-overlapping triangles.
        ///
        /// The basic idea is explained in Preparata and Shamos (which I don't
        /// have handy right now), although their implementation is more
        /// complicated than this one.  The are two edge chains, an upper chain
        /// and a lower chain.  We process all vertices from both chains in order,
        /// from right to left.
        ///
        /// The algorithm ensures that the following invariant holds after each
        /// vertex is processed: the untessellated region consists of two
        /// chains, where one chain (say the upper) is a single edge, and
        /// the other chain is concave.  The left vertex of the single edge
        /// is always to the left of all vertices in the concave chain.
        ///
        /// Each step consists of adding the rightmost unprocessed vertex to one
        /// of the two chains, and forming a fan of triangles from the rightmost
        /// of two chain endpoints.  Determining whether we can add each triangle
        /// to the fan is a simple orientation test.  By making the fan as large
        /// as possible, we restore the invariant (check it yourself).
        /// </summary>
        private void TessellateMonoRegion(MeshUtils.Face face)
        {
            // All edges are oriented CCW around the boundary of the region.
            // First, find the half-edge whose origin vertex is rightmost.
            // Since the sweep goes from left to right, face->anEdge should
            // be close to the edge we want.
            var up = face._anEdge;

            Debug.Assert(up._Lnext != up && up._Lnext._Lnext != up);

            int dummy = 0;

            for (; Geom.VertLeq(up._Dst, up._Org); up = up._Lprev)
            {
                dummy += 1;
            }
            for (; Geom.VertLeq(up._Org, up._Dst); up = up._Lnext)
            {
                dummy += 1;
            }

            var lo = up._Lprev;

            while (up._Lnext != lo)
            {
                if (Geom.VertLeq(up._Dst, lo._Org))
                {
                    // up.Dst is on the left. It is safe to form triangles from lo.Org.
                    // The EdgeGoesLeft test guarantees progress even when some triangles
                    // are CW, given that the upper and lower chains are truly monotone.
                    while (lo._Lnext != up && (Geom.EdgeGoesLeft(lo._Lnext) ||
                                               Geom.EdgeSign(lo._Org, lo._Dst, lo._Lnext._Dst) <= 0.0f))
                    {
                        lo = _mesh.Connect(lo._Lnext, lo)._Sym;
                    }
                    lo = lo._Lprev;
                }
                else
                {
                    // lo.Org is on the left.  We can make CCW triangles from up.Dst.
                    while (lo._Lnext != up && (Geom.EdgeGoesRight(up._Lprev) ||
                                               Geom.EdgeSign(up._Dst, up._Org, up._Lprev._Org) >= 0.0f))
                    {
                        up = _mesh.Connect(up, up._Lprev)._Sym;
                    }
                    up = up._Lnext;
                }
            }

            // Now lo.Org == up.Dst == the leftmost vertex.  The remaining region
            // can be tessellated in a fan from this leftmost vertex.
            Debug.Assert(lo._Lnext != up);
            while (lo._Lnext._Lnext != up)
            {
                lo = _mesh.Connect(lo._Lnext, lo)._Sym;
            }
        }
All Usage Examples Of LibTessDotNet.Mesh::Connect