public Operation(IntersectionClassification[] classificationTable, bool subjectContributingParity, bool clipContributingParity, bool invertSubjectSides, bool invertClipSides)
 {
     m_classificationTable = classificationTable;
     m_sParityForContribution = subjectContributingParity;
     m_cParityForContribution = clipContributingParity;
     SubjectInvert = invertSubjectSides;
     ClipInvert = invertClipSides;
 }
        private static void InitializeOperations()
        {
            CheckClassificationIndices();

            IntersectionClassification[] table = new IntersectionClassification[16];

            table = new IntersectionClassification[16];
            InitClassificationTable(table);
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_CLIP]       = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_CLIP]       = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_LEFT_SUBJECT]     = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_LEFT_CLIP]     = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_RIGHT_SUBJECT]   = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_RIGHT_CLIP]   = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_CLIP]    = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_SUBJECT]    = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_CLIP]    = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_SUBJECT]    = IntersectionClassification.LOCAL_MINIMUM;

            m_operationIntersection = new Operation(table, true, true, false, false);

            table = new IntersectionClassification[16];
            InitClassificationTable(table);
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_CLIP]       = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_CLIP]       = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_LEFT_SUBJECT]     = IntersectionClassification.LEFT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_LEFT_CLIP]     = IntersectionClassification.LEFT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_RIGHT_SUBJECT]   = IntersectionClassification.RIGHT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_RIGHT_CLIP]   = IntersectionClassification.RIGHT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_CLIP]    = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_SUBJECT]    = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_CLIP]    = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_SUBJECT]    = IntersectionClassification.LOCAL_MAXIMUM;

            m_operationUnion = new Operation(table, false, false, false, false);

            table = new IntersectionClassification[16];
            InitClassificationTable(table);
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_CLIP]       = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_CLIP]       = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_LEFT_SUBJECT]     = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_LEFT_CLIP]     = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_RIGHT_SUBJECT]   = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_RIGHT_CLIP]   = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_CLIP]    = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_SUBJECT]    = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_CLIP]    = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_SUBJECT]    = IntersectionClassification.LOCAL_MINIMUM;

            m_operationDifference = new Operation(table, false, true, false, true);
        }
        private void PerformIntersection(int leftEdgeIndex, int rightEdgeIndex, ref Edge e1, ref Edge e2, ref Vector3 intersectionPosition, IntersectionClassification intersectionClassification)
        {
            Debug.Assert(intersectionClassification != IntersectionClassification.INVALID);
            switch (intersectionClassification)
            {
                case IntersectionClassification.LIKE_INTERSECTION:
                    Debug.Assert((e1.Contributing && e2.Contributing) || (!e1.Contributing && !e2.Contributing));
                    Debug.Assert((e1.OutputSide == Side.LEFT && e2.OutputSide == Side.RIGHT) || (e1.OutputSide == Side.RIGHT && e2.OutputSide == Side.LEFT));

                    Side swapSide = e1.OutputSide;
                    e1.OutputSide = e2.OutputSide;
                    e2.OutputSide = swapSide;

                    if (e1.Contributing)
                    {
                        if (e1.OutputSide == Side.RIGHT)
                        {
                            e1.AssociatedPolygon.Append(intersectionPosition);
                            e2.AssociatedPolygon.Prepend(intersectionPosition);
                        }
                        else
                        {
                            e1.AssociatedPolygon.Prepend(intersectionPosition);
                            e2.AssociatedPolygon.Append(intersectionPosition);
                        }
                    }
                    break;
                case IntersectionClassification.LEFT_E1_INTERMEDIATE:
                    e1.AssociatedPolygon.Append(intersectionPosition);
                    break;
                case IntersectionClassification.RIGHT_E1_INTERMEDIATE:
                    e1.AssociatedPolygon.Prepend(intersectionPosition);
                    break;
                case IntersectionClassification.LEFT_E2_INTERMEDIATE:
                    e2.AssociatedPolygon.Append(intersectionPosition);
                    break;
                case IntersectionClassification.RIGHT_E2_INTERMEDIATE:
                    e2.AssociatedPolygon.Prepend(intersectionPosition);
                    break;
                case IntersectionClassification.LOCAL_MINIMUM:
                    var newPoly = new PartialPolygon();
                    newPoly.Append(intersectionPosition);
                    e1.AssociatedPolygon = newPoly;
                    e2.AssociatedPolygon = newPoly;
                    break;
                case IntersectionClassification.LOCAL_MAXIMUM:
                    AddLocalMaximum(leftEdgeIndex, rightEdgeIndex, ref e1, ref e2, intersectionPosition);
                    break;
            }

            PartialPolygon swap = e1.AssociatedPolygon;
            e1.AssociatedPolygon = e2.AssociatedPolygon;
            e2.AssociatedPolygon = swap;

            if (intersectionClassification != IntersectionClassification.LIKE_INTERSECTION)
            {
                e1.Contributing = !e1.Contributing;
                e2.Contributing = !e2.Contributing;
            }

            m_activeEdgeList[leftEdgeIndex] = e2;
            m_activeEdgeList[rightEdgeIndex] = e1;
        }
 private static void InitClassificationTable(IntersectionClassification[] m_classificationTable)
 {
     for (int i = 0; i < 16; ++i)
     {
         m_classificationTable[i] = IntersectionClassification.INVALID;
     }
 }
        private static void InitializeOperations()
        {
            CheckClassificationIndices();

            IntersectionClassification[] table = new IntersectionClassification[16];

            table = new IntersectionClassification[16];
            InitClassificationTable(table);
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_CLIP] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_CLIP] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_LEFT_SUBJECT] = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_LEFT_CLIP] = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_RIGHT_SUBJECT] = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_RIGHT_CLIP] = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_CLIP] = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_SUBJECT] = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_CLIP] = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_SUBJECT] = IntersectionClassification.LOCAL_MINIMUM;

            m_operationIntersection = new Operation(table, true, true, false, false);

            table = new IntersectionClassification[16];
            InitClassificationTable(table);
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_CLIP] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_CLIP] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_LEFT_SUBJECT] = IntersectionClassification.LEFT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_LEFT_CLIP] = IntersectionClassification.LEFT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_RIGHT_SUBJECT] = IntersectionClassification.RIGHT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_RIGHT_CLIP] = IntersectionClassification.RIGHT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_CLIP] = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_SUBJECT] = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_CLIP] = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_SUBJECT] = IntersectionClassification.LOCAL_MAXIMUM;

            m_operationUnion = new Operation(table, false, false, false, false);

            table = new IntersectionClassification[16];
            InitClassificationTable(table);
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_CLIP] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_CLIP] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_SUBJECT] = IntersectionClassification.LIKE_INTERSECTION;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_LEFT_SUBJECT] = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_LEFT_CLIP] = IntersectionClassification.LEFT_E2_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_RIGHT_SUBJECT] = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_RIGHT_CLIP] = IntersectionClassification.RIGHT_E1_INTERMEDIATE;
            table[(int)ClassificationIndex.LEFT_SUBJECT_AND_RIGHT_CLIP] = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.LEFT_CLIP_AND_RIGHT_SUBJECT] = IntersectionClassification.LOCAL_MAXIMUM;
            table[(int)ClassificationIndex.RIGHT_SUBJECT_AND_LEFT_CLIP] = IntersectionClassification.LOCAL_MINIMUM;
            table[(int)ClassificationIndex.RIGHT_CLIP_AND_LEFT_SUBJECT] = IntersectionClassification.LOCAL_MINIMUM;

            m_operationDifference = new Operation(table, false, true, false, true);
        }