Example #1
0
        private void Initialize()
        {
            sweepline         = new OA_Sweepline();
            eventQueue        = new RBTreeSet <OA_EventPoint>(OA_EventPoint.Compare);
            outputSubdivision = new DCEL_Subdivision();

            foreach (DCEL_Subdivision inputSubdivision in inputSubdivisions)
            {
                foreach (DCEL_HalfEdge inputHalfEdge in inputSubdivision.HalfEdges.Keys)
                {
                    OA_EventPoint upper = new OA_EventPoint(inputHalfEdge.Origin.Position);
                    OA_EventPoint lower = new OA_EventPoint(inputHalfEdge.Destination.Position);

                    //We want to take only one of the twins from every pair of half edges.
                    if (upper.CompareTo(lower) > 0)
                    {
                        continue;
                    }

                    RBTreeSetNode <OA_EventPoint> upper_node = new RBTreeSetNode <OA_EventPoint>(upper);
                    RBTreeSetNode <OA_EventPoint> lower_node = new RBTreeSetNode <OA_EventPoint>(lower);

                    //If we didn't add the newly created event point, it already existed.
                    if (!eventQueue.Add(ref upper_node))
                    {
                        upper = upper_node.Key;
                    }
                    if (!eventQueue.Add(ref lower_node))
                    {
                        lower = lower_node.Key;
                    }

                    OA_Segment segment = new OA_Segment(sweepline);
                    segment.Source.Add(new OA_Source <DCEL_HalfEdge>(inputSubdivision, inputHalfEdge));
                    segment.Upper = upper;
                    segment.Lower = lower;
                    //***May be adding a duplicate if segment is in both subdivisions!
                    upper.UpperList.Add(segment);

                    if (!upper.Source.Any(OA_Source <DCEL_Vertex> .IsFrom(inputSubdivision)))
                    {
                        upper.Source.Add(new OA_Source <DCEL_Vertex>(inputSubdivision, inputHalfEdge.Origin));
                    }

                    if (!lower.Source.Any(OA_Source <DCEL_Vertex> .IsFrom(inputSubdivision)))
                    {
                        lower.Source.Add(new OA_Source <DCEL_Vertex>(inputSubdivision, inputHalfEdge.Destination));
                    }
                }
            }

            foreach (OA_EventPoint eventPoint in eventQueue.Keys)
            {
                //***Remove those duplicates here, joining their source lists.
                eventPoint.UpperList.RemoveDuplicates(OA_Segment.CompareEndpoints, OA_Segment.JoinSource);
            }
        }
Example #2
0
        /// <summary>
        /// Merge subdivisionA and subdivisionB into a single subdivision, destroying subdivisionA and subdivisionB in the process.
        /// </summary>
        public static DCEL_Subdivision Overlay(DCEL_Subdivision subdivisionA, DCEL_Subdivision subdivisionB)
        {
            OA_Algorithm algorithm = new OA_Algorithm(new[] { subdivisionA, subdivisionB });

            subdivisionA.WriteToFile("subdivisionA_pre_splitting.xml");
            subdivisionB.WriteToFile("subdivisionB_pre_splitting.xml");

            subdivisionA.WriteToFile_Faces("subdivisionA_pre_splitting_faces.xml");
            subdivisionB.WriteToFile_Faces("subdivisionB_pre_splitting_faces.xml");

            algorithm.phase = Phase.SplittingPhase;

            algorithm.Initialize();
            algorithm.Sweep();

            subdivisionA.WriteToFile("subdivisionA_post_splitting.xml");
            subdivisionB.WriteToFile("subdivisionB_post_splitting.xml");

            subdivisionA.WriteToFile_Faces("subdivisionA_post_splitting_faces.xml");
            subdivisionB.WriteToFile_Faces("subdivisionB_post_splitting_faces.xml");

            algorithm.phase = Phase.MergingPhase;

            algorithm.Initialize();
            algorithm.Sweep();

            algorithm.outputSubdivision.WriteToFile("outputSubdivision_post_merging.xml");

            algorithm.phase = Phase.FacingPhase;

            algorithm.CreateFaces();

            algorithm.outputSubdivision.WriteToFile("outputSubdivision_final.xml");
            algorithm.outputSubdivision.WriteToFile_Faces("outputSubdivision_final_faces.xml");

            //The inputSubdivisions have been destroyed, so clear them.
            foreach (DCEL_Subdivision inputSubdivision in algorithm.inputSubdivisions)
            {
                inputSubdivision.Clear();
            }

            return(algorithm.outputSubdivision);
        }
Example #3
0
        private void HandleIntersection_SplittingPhase(OA_EventPoint eventPoint, List <OA_Segment> upperList, List <OA_Segment> middleList, List <OA_Segment> lowerList)
        {
            //if (upperList.Count() + middleList.Count() + lowerList.Count() <= 1)
            if (middleList.Count == 0)
            {
                return;
            }

            //If there are any subdivisions which don't have a vertex at this location,
            //then we will create one momentarily. For the moment, set the
            //(key, value) = (subdivision, null).
            Dictionary <DCEL_Subdivision, DCEL_Vertex> vertexLookup = CreateSourceLookup(eventPoint);

            //Make all segments meet at a vertex here, within each subdivision.
            //HalfEdges associated with segments in the middleList will be transformed
            //into HalfEdges associated with segments in the upperList. (With the associated
            //segments transforming as well.)
            foreach (OA_Segment middle in middleList)
            {
                foreach (OA_Source <DCEL_HalfEdge> source in middle.Source)
                {
                    DCEL_Subdivision subdivision = source.Subdivision;
                    DCEL_HalfEdge    halfEdge    = source.Element;
                    DCEL_Vertex      vertex      = vertexLookup[subdivision];

                    //Create the vertex on-demand if it doesn't exist
                    if (vertex == null)
                    {
                        vertex = new DCEL_Vertex(eventPoint.Position);
                        vertexLookup[subdivision] = vertex;
                        subdivision.Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex));
                    }

                    SplitEdge(subdivision, halfEdge, vertex);

                    if (!eventPoint.Source.Any(OA_Source <DCEL_Vertex> .IsFrom(subdivision)))
                    {
                        eventPoint.Source.Add(new OA_Source <DCEL_Vertex>(subdivision, vertex));
                    }
                }
            }
        }
Example #4
0
        /// <summary>
        /// halfEdge should be Upper->Lower so that the persistent half edges become:
        ///  o halfEdge         (Upper->Lower) ==> (vertex->Lower)
        ///  o halfEdge.Twin    (Lower->Upper) ==> (Lower->vertex)
        /// And the two newly created half edges are (vertex->Upper) and (Upper->vertex).
        /// </summary>
        private static void SplitEdge(DCEL_Subdivision subdivision, DCEL_HalfEdge halfEdge, DCEL_Vertex vertex)
        {
            Debug.Assert(VecRat2.CompareReadingOrder(halfEdge.Origin.Position, halfEdge.Destination.Position) < 0);

            DCEL_HalfEdge e1 = halfEdge;
            DCEL_HalfEdge e2 = e1.Twin;

            DCEL_HalfEdge e1_prev = e1.Prev;
            DCEL_HalfEdge e2_next = e2.Next;

            DCEL_Vertex e1_origin = e1.Origin;

            DCEL_HalfEdge e1_top = new DCEL_HalfEdge();
            DCEL_HalfEdge e2_top = new DCEL_HalfEdge();

            DCEL_Helper.JoinTwin(e1_top, e2_top);
            e1_top.IncidentFace = e1.IncidentFace;
            e2_top.IncidentFace = e2.IncidentFace;

            DCEL_Helper.JoinIncidentEdge(vertex, e2_top);
            DCEL_Helper.JoinIncidentEdge(vertex, e1);
            DCEL_Helper.JoinIncidentEdge(e1_origin, e1_top);

            if (e2_next == e1)
            {
                DCEL_Helper.JoinNext(e2, e2_top);
                DCEL_Helper.JoinNext(e2_top, e1_top);
                DCEL_Helper.JoinNext(e1_top, e1);
            }
            else
            {
                DCEL_Helper.JoinPrevNext(e2, e2_top, e2_next);
                DCEL_Helper.JoinPrevNext(e1_prev, e1_top, e1);
            }

            if (subdivision != null)
            {
                subdivision.HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(e1_top));
                subdivision.HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(e2_top));
            }
        }
Example #5
0
 public static Func <OA_Source <DCEL_T>, bool> IsFrom(DCEL_Subdivision subdivision)
 {
     return(source => (source.Subdivision == subdivision));
 }
Example #6
0
 public OA_Source(DCEL_Subdivision subdivision, DCEL_T element)
 {
     Subdivision = subdivision;
     Element     = element;
 }