protected int auxiliaryNextEdgeId(int prevEdgeId, int curEdgeId,
                                          VPFPrimitiveData.PrimitiveInfo[] edgeInfoArray)
        {
            // Note: an edge which has the same face for both its left and right faces is known to be an "auxiliary edge".
            // Using auxiliary edges is a solution to defining a face (polygon) with holes. The face becomes a single loop,
            // with an auxiliary edge joining each inner and outer loop. The auxiliary edge is traversed twice; one upon
            // entering the inner ring, then  again upon exit.

            VPFPrimitiveData.EdgeInfo prevInfo = getEdgeInfo(edgeInfoArray, prevEdgeId);
            VPFPrimitiveData.EdgeInfo curInfo  = getEdgeInfo(edgeInfoArray, curEdgeId);

            // Previous edge is adjacent to starting node.
            if (curInfo.getStartNode() == prevInfo.getStartNode() || curInfo.getStartNode() == prevInfo.getEndNode())
            {
                return((curInfo.getRightEdge() != curEdgeId) ? curInfo.getRightEdge() : curInfo.getLeftEdge());
            }
            // Previous edge is adjacent to ending node.
            else if (curInfo.getEndNode() == prevInfo.getStartNode() || curInfo.getEndNode() == prevInfo.getEndNode())
            {
                return((curInfo.getLeftEdge() != curEdgeId) ? curInfo.getLeftEdge() : curInfo.getRightEdge());
            }
            // Edges are not actually adjacent. This should never happen, but we check anyway.
            else
            {
                return(-1);
            }
        }
        protected bool auxiliaryMustReverseCoordinates(int prevEdgeId, int curEdgeId,
                                                       VPFPrimitiveData.PrimitiveInfo[] edgeInfoArray)
        {
            VPFPrimitiveData.EdgeInfo prevInfo = getEdgeInfo(edgeInfoArray, prevEdgeId);
            VPFPrimitiveData.EdgeInfo curInfo  = getEdgeInfo(edgeInfoArray, curEdgeId);

            return(curInfo.getEndNode() == prevInfo.getStartNode() || curInfo.getEndNode() == prevInfo.getEndNode());
        }
        protected Orientation getOrientation(int faceId, int edgeId, VPFPrimitiveData.PrimitiveInfo[] edgeInfo)
        {
            VPFPrimitiveData.EdgeInfo thisInfo = getEdgeInfo(edgeInfo, edgeId);
            bool matchLeft  = thisInfo.getLeftFace() == faceId;
            bool matchRight = thisInfo.getRightFace() == faceId;

            if (matchLeft && matchRight) // Auxiliary edge has the same face on both sides.
            {
                return(Orientation.LEFT_AND_RIGHT);
            }
            else if (matchLeft)
            {
                return(Orientation.LEFT);
            }
            else if (matchRight)
            {
                return(Orientation.RIGHT);
            }

            return(null);
        }