Exemple #1
0
        /* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
         * winding numbers on all edges so that regions marked "inside" the
         * polygon have a winding number of "value", and regions outside
         * have a winding number of 0.
         *
         * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
         * separate an interior region from an exterior one.
         */
        public static bool __gl_meshSetWindingNumber(GLUmesh mesh, int value_Renamed, bool keepOnlyBoundary)
        {
            GLUhalfEdge e, eNext;

            for (e = mesh.eHead.next; e != mesh.eHead; e = eNext)
            {
                eNext = e.next;
                if (e.Sym.Lface.inside != e.Lface.inside)
                {
                    /* This is a boundary edge (one side is interior, one is exterior). */
                    e.winding = (e.Lface.inside)?value_Renamed:-value_Renamed;
                }
                else
                {
                    /* Both regions are interior, or both are exterior. */
                    if (!keepOnlyBoundary)
                    {
                        e.winding = 0;
                    }
                    else
                    {
                        if (!Mesh.__gl_meshDelete(e))
                        {
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }
        public virtual void  gluTessBeginPolygon(System.Object data)
        {
            requireState(TessState.T_DORMANT);

            state                  = TessState.T_IN_POLYGON;
            cacheCount             = 0;
            flushCacheOnNextVertex = false;
            mesh = null;

            polygonData = data;
        }
        private void  makeDormant()
        {
            /* Return the tessellator to its original dormant state. */

            if (mesh != null)
            {
                Mesh.__gl_meshDeleteMesh(mesh);
            }
            state    = TessState.T_DORMANT;
            lastEdge = null;
            mesh     = null;
        }
Exemple #4
0
        /* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
        * which are not marked "inside" the polygon.  Since further mesh operations
        * on NULL faces are not allowed, the main purpose is to clean up the
        * mesh so that exterior loops are not represented in the data structure.
        */
        public static void __gl_meshDiscardExterior(GLUmesh mesh)
        {
            GLUface f, next;

            /*LINTED*/
            for (f = mesh.fHead.next; f != mesh.fHead; f = next)
            {
                /* Since f will be destroyed, save its next pointer. */
                next = f.next;
                if (!f.inside)
                {
                    Mesh.__gl_meshZapFace(f);
                }
            }
        }
Exemple #5
0
        /* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
         * which are not marked "inside" the polygon.  Since further mesh operations
         * on NULL faces are not allowed, the main purpose is to clean up the
         * mesh so that exterior loops are not represented in the data structure.
         */
        public static void  __gl_meshDiscardExterior(GLUmesh mesh)
        {
            GLUface f, next;

            /*LINTED*/
            for (f = mesh.fHead.next; f != mesh.fHead; f = next)
            {
                /* Since f will be destroyed, save its next pointer. */
                next = f.next;
                if (!f.inside)
                {
                    Mesh.__gl_meshZapFace(f);
                }
            }
        }
Exemple #6
0
        /* __gl_meshTessellateInterior( mesh ) tessellates each region of
         * the mesh which is marked "inside" the polygon.  Each such region
         * must be monotone.
         */
        public static bool __gl_meshTessellateInterior(GLUmesh mesh)
        {
            GLUface f, next;

            /*LINTED*/
            for (f = mesh.fHead.next; f != mesh.fHead; f = next)
            {
                /* Make sure we don''t try to tessellate the new triangles. */
                next = f.next;
                if (f.inside)
                {
                    if (!__gl_meshTessellateMonoRegion(f))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        private bool flushCache()
        {
            CachedVertex[] v = cache;

            mesh = Mesh.__gl_meshNewMesh();
            if (mesh == null)
            {
                return(false);
            }

            for (int i = 0; i < cacheCount; i++)
            {
                CachedVertex vertex = v[i];
                if (!addVertex(vertex.coords, vertex.data))
                {
                    return(false);
                }
            }
            cacheCount             = 0;
            flushCacheOnNextVertex = false;

            return(true);
        }
        public virtual void  gluTessEndPolygon()
        {
            GLUmesh mesh;

            try
            {
                requireState(TessState.T_IN_POLYGON);
                state = TessState.T_DORMANT;

                if (this.mesh == null)
                {
                    if (!flagBoundary)
                    {
                        /* Try some special code to make the easy cases go quickly
                         * (eg. convex polygons).  This code does NOT handle multiple contours,
                         * intersections, edge flags, and of course it does not generate
                         * an explicit mesh either.
                         */
                        if (Render.__gl_renderCache(this))
                        {
                            polygonData = null;
                            return;
                        }
                    }
                    if (!flushCache())
                    {
                        throw new System.SystemException();                         /* could've used a label*/
                    }
                }

                /* Determine the polygon normal and project vertices onto the plane
                 * of the polygon.
                 */
                Normal.__gl_projectPolygon(this);

                /* __gl_computeInterior( tess ) computes the planar arrangement specified
                 * by the given contours, and further subdivides this arrangement
                 * into regions.  Each region is marked "inside" if it belongs
                 * to the polygon, according to the rule given by windingRule.
                 * Each interior region is guaranteed be monotone.
                 */
                if (!Sweep.__gl_computeInterior(this))
                {
                    throw new System.SystemException();                     /* could've used a label */
                }

                mesh = this.mesh;
                if (!fatalError)
                {
                    bool rc = true;

                    /* If the user wants only the boundary contours, we throw away all edges
                     * except those which separate the interior from the exterior.
                     * Otherwise we tessellate all the regions marked "inside".
                     */
                    if (boundaryOnly)
                    {
                        rc = TessMono.__gl_meshSetWindingNumber(mesh, 1, true);
                    }
                    else
                    {
                        rc = TessMono.__gl_meshTessellateInterior(mesh);
                    }
                    if (!rc)
                    {
                        throw new System.SystemException();                         /* could've used a label */
                    }
                    Mesh.__gl_meshCheckMesh(mesh);

                    if (callBegin != NULL_CB || callEnd != NULL_CB || callVertex != NULL_CB || callEdgeFlag != NULL_CB || callBeginData != NULL_CB || callEndData != NULL_CB || callVertexData != NULL_CB || callEdgeFlagData != NULL_CB)
                    {
                        if (boundaryOnly)
                        {
                            Render.__gl_renderBoundary(this, mesh);                             /* output boundary contours */
                        }
                        else
                        {
                            Render.__gl_renderMesh(this, mesh);                             /* output strips and fans */
                        }
                    }
                    //                if (callMesh != NULL_CB) {
                    //
                    ///* Throw away the exterior faces, so that all faces are interior.
                    //                 * This way the user doesn't have to check the "inside" flag,
                    //                 * and we don't need to even reveal its existence.  It also leaves
                    //                 * the freedom for an implementation to not generate the exterior
                    //                 * faces in the first place.
                    //                 */
                    //                    TessMono.__gl_meshDiscardExterior(mesh);
                    //                    callMesh.mesh(mesh);		/* user wants the mesh itself */
                    //                    mesh = null;
                    //                    polygonData = null;
                    //                    return;
                    //                }
                }
                Mesh.__gl_meshDeleteMesh(mesh);
                polygonData = null;
                mesh        = null;
            }
            catch (System.Exception e)
            {
                SupportClass.WriteStackTrace(e, Console.Error);
                callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
            }
        }
Exemple #9
0
        /* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
        * winding numbers on all edges so that regions marked "inside" the
        * polygon have a winding number of "value", and regions outside
        * have a winding number of 0.
        *
        * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
        * separate an interior region from an exterior one.
        */
        public static bool __gl_meshSetWindingNumber(GLUmesh mesh, int value_Renamed, bool keepOnlyBoundary)
        {
            GLUhalfEdge e, eNext;

            for (e = mesh.eHead.next; e != mesh.eHead; e = eNext)
            {
                eNext = e.next;
                if (e.Sym.Lface.inside != e.Lface.inside)
                {

                    /* This is a boundary edge (one side is interior, one is exterior). */
                    e.winding = (e.Lface.inside)?value_Renamed:- value_Renamed;
                }
                else
                {

                    /* Both regions are interior, or both are exterior. */
                    if (!keepOnlyBoundary)
                    {
                        e.winding = 0;
                    }
                    else
                    {
                        if (!Mesh.__gl_meshDelete(e))
                            return false;
                    }
                }
            }
            return true;
        }
Exemple #10
0
        /* __gl_meshTessellateInterior( mesh ) tessellates each region of
        * the mesh which is marked "inside" the polygon.  Each such region
        * must be monotone.
        */
        public static bool __gl_meshTessellateInterior(GLUmesh mesh)
        {
            GLUface f, next;

            /*LINTED*/
            for (f = mesh.fHead.next; f != mesh.fHead; f = next)
            {
                /* Make sure we don''t try to tessellate the new triangles. */
                next = f.next;
                if (f.inside)
                {
                    if (!__gl_meshTessellateMonoRegion(f))
                        return false;
                }
            }

            return true;
        }
        private void makeDormant()
        {
            /* Return the tessellator to its original dormant state. */

            if (mesh != null)
            {
                Mesh.__gl_meshDeleteMesh(mesh);
            }
            state = TessState.T_DORMANT;
            lastEdge = null;
            mesh = null;
        }
        private bool flushCache()
        {
            CachedVertex[] v = cache;

            mesh = Mesh.__gl_meshNewMesh();
            if (mesh == null)
                return false;

            for (int i = 0; i < cacheCount; i++)
            {
                CachedVertex vertex = v[i];
                if (!addVertex(vertex.coords, vertex.data))
                    return false;
            }
            cacheCount = 0;
            flushCacheOnNextVertex = false;

            return true;
        }
        public virtual void gluTessEndPolygon()
        {
            GLUmesh mesh;

            try
            {
                requireState(TessState.T_IN_POLYGON);
                state = TessState.T_DORMANT;

                if (this.mesh == null)
                {
                    if (!flagBoundary)
                    {

                        /* Try some special code to make the easy cases go quickly
                        * (eg. convex polygons).  This code does NOT handle multiple contours,
                        * intersections, edge flags, and of course it does not generate
                        * an explicit mesh either.
                        */
                        if (Render.__gl_renderCache(this))
                        {
                            polygonData = null;
                            return ;
                        }
                    }
                    if (!flushCache())
                        throw new System.SystemException(); /* could've used a label*/
                }

                /* Determine the polygon normal and project vertices onto the plane
                * of the polygon.
                */
                Normal.__gl_projectPolygon(this);

                /* __gl_computeInterior( tess ) computes the planar arrangement specified
                * by the given contours, and further subdivides this arrangement
                * into regions.  Each region is marked "inside" if it belongs
                * to the polygon, according to the rule given by windingRule.
                * Each interior region is guaranteed be monotone.
                */
                if (!Sweep.__gl_computeInterior(this))
                {
                    throw new System.SystemException(); /* could've used a label */
                }

                mesh = this.mesh;
                if (!fatalError)
                {
                    bool rc = true;

                    /* If the user wants only the boundary contours, we throw away all edges
                    * except those which separate the interior from the exterior.
                    * Otherwise we tessellate all the regions marked "inside".
                    */
                    if (boundaryOnly)
                    {
                        rc = TessMono.__gl_meshSetWindingNumber(mesh, 1, true);
                    }
                    else
                    {
                        rc = TessMono.__gl_meshTessellateInterior(mesh);
                    }
                    if (!rc)
                        throw new System.SystemException(); /* could've used a label */

                    Mesh.__gl_meshCheckMesh(mesh);

                    if (callBegin != NULL_CB || callEnd != NULL_CB || callVertex != NULL_CB || callEdgeFlag != NULL_CB || callBeginData != NULL_CB || callEndData != NULL_CB || callVertexData != NULL_CB || callEdgeFlagData != NULL_CB)
                    {
                        if (boundaryOnly)
                        {
                            Render.__gl_renderBoundary(this, mesh); /* output boundary contours */
                        }
                        else
                        {
                            Render.__gl_renderMesh(this, mesh); /* output strips and fans */
                        }
                    }
                    //                if (callMesh != NULL_CB) {
                    //
                    ///* Throw away the exterior faces, so that all faces are interior.
                    //                 * This way the user doesn't have to check the "inside" flag,
                    //                 * and we don't need to even reveal its existence.  It also leaves
                    //                 * the freedom for an implementation to not generate the exterior
                    //                 * faces in the first place.
                    //                 */
                    //                    TessMono.__gl_meshDiscardExterior(mesh);
                    //                    callMesh.mesh(mesh);		/* user wants the mesh itself */
                    //                    mesh = null;
                    //                    polygonData = null;
                    //                    return;
                    //                }
                }
                Mesh.__gl_meshDeleteMesh(mesh);
                polygonData = null;
                mesh = null;
            }
            catch (System.Exception e)
            {
                SupportClass.WriteStackTrace(e, Console.Error);
                callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
            }
        }
        public virtual void gluTessBeginPolygon(System.Object data)
        {
            requireState(TessState.T_DORMANT);

            state = TessState.T_IN_POLYGON;
            cacheCount = 0;
            flushCacheOnNextVertex = false;
            mesh = null;

            polygonData = data;
        }