示例#1
0
        // Pivot an edge clockwise around its implicit near vertex.
        //
        // \         /          \         /
        //  o-------o            o-------o
        //  |       |            |       |
        //  2   N   |            2   N   |
        //  |       |            |       |
        //  B       V      -->   B<--E---V
        // / \     / \          / \       \
        //    1   E   \            1       \
        //     \ v     \ /          \       \ /
        //      A       o            A       o
        //      |   P   |            |   P   |
        //      0       |            0       |
        //      |       |            |       |
        //      o-------o            o-------o
        //     /         \          /         \
        //
        // E:  edge passed in as parameter
        // V:  vertex to pivot E around clockwise
        // A:  old vertex that E is originally pointing at
        // B:  new vertex that E will now point at
        // P:  previous face on the counter-clockwise side of E
        // N:  next face on the clockwise side of E
        // 0:  outer edge 0 points at A, inner edge 0 points away from A
        // 1:  outer edge 1 points at B, inner edge 1 points at A, at N before pivot, at P after pivot
        // 2:  outer edge 2 points away from B
        // Note:  inner edges point downward, outer edges point upward

        private void PivotVertexEdgeForwardUnchecked(int edgeIndex, int twinEdgeIndex, int outerEdgeIndex1, int innerEdgeIndex1)
        {
            var innerEdgeIndex0 = edgeData[twinEdgeIndex].vNext;
            var outerEdgeIndex0 = edgeData[innerEdgeIndex0].twin;
            var outerEdgeIndex2 = edgeData[outerEdgeIndex1].fNext;

            var prevFaceIndex  = edgeData[edgeIndex].face;
            var nextFaceIndex  = edgeData[twinEdgeIndex].face;
            var oldVertexIndex = edgeData[edgeIndex].vertex;
            var newVertexIndex = edgeData[outerEdgeIndex1].vertex;

            // The edge was pointing at the old vertex, will now point at the new vertex.
            edgeData[edgeIndex].vertex = newVertexIndex;

            // The second inner edge was pointing at the next face, will now point at the previous face.
            edgeData[innerEdgeIndex1].face = prevFaceIndex;

            // Remove twin edge from old vertex linked list by skipping over it.
            edgeData[outerEdgeIndex1].vNext = innerEdgeIndex0;

            // Insert twin edge into new vertex linked list.
            edgeData[outerEdgeIndex2].vNext = twinEdgeIndex;
            edgeData[twinEdgeIndex].vNext   = innerEdgeIndex1;

            // Remove second outer edge from next face linked list by skipping over it.
            edgeData[edgeIndex].fNext = outerEdgeIndex2;

            // Insert second outer edge into the previous face linked list.
            edgeData[outerEdgeIndex0].fNext = outerEdgeIndex1;
            edgeData[outerEdgeIndex1].fNext = twinEdgeIndex;

            // Reroot the vertex and face that just lost edges with edges guaranteed to still belong.
            vertexFirstEdgeIndices[oldVertexIndex] = outerEdgeIndex1;
            faceFirstEdgeIndices[nextFaceIndex]    = edgeIndex;

            // Adjust neighbor counts.
            vertexNeighborCounts[oldVertexIndex] -= 1;
            vertexNeighborCounts[newVertexIndex] += 1;
            faceNeighborCounts[nextFaceIndex]    -= 1;         // Dropping below 0 is undefined behavior; it better not ever happen.
            faceNeighborCounts[prevFaceIndex]    += 1;         // Surpassing 32767 is undefined behavior; it better not ever happen.

            // Adjust edge wrap information, coallescing multiple edges together as appropriate.
            edgeData[edgeIndex].wrap       = EdgeWrapUtility.ModifyTargetVertEdgeRelations(edgeData[edgeIndex].wrap, edgeData[outerEdgeIndex1].wrap);       // Edge's target vertex changed, according to Inner Edge 1.
            edgeData[twinEdgeIndex].wrap   = EdgeWrapUtility.ModifySourceVertEdgeRelations(edgeData[twinEdgeIndex].wrap, edgeData[innerEdgeIndex1].wrap);   // Twin Edge's source vertex changed, according to Outer Edge 1.
            edgeData[innerEdgeIndex1].wrap = EdgeWrapUtility.ModifyTargetFaceEdgeRelations(edgeData[innerEdgeIndex1].wrap, edgeData[edgeIndex].wrap);       // Inner Edge 1's target face changed, according to Twin Edge.
            edgeData[outerEdgeIndex1].wrap = EdgeWrapUtility.ModifySourceFaceEdgeRelations(edgeData[outerEdgeIndex1].wrap, edgeData[twinEdgeIndex].wrap);   // Outer Edge 1's source face changed, according to Edge.
        }