Пример #1
0
 public void Clear()
 {
     Vertices.Clear();
     HalfEdges.Clear();
     Faces.Clear();
     UnboundedFace = null;
 }
Пример #2
0
 public DCEL_Subdivision()
 {
     ID            = NextID++;
     Vertices      = new RBTreeSet <DCEL_Vertex>(DCEL_Element.Compare);
     HalfEdges     = new RBTreeSet <DCEL_HalfEdge>(DCEL_Element.Compare);
     Faces         = new RBTreeSet <DCEL_Face>(DCEL_Element.Compare);
     UnboundedFace = new DCEL_Face();
 }
Пример #3
0
        /// <summary>
        /// Create a subdivision from a single segment (u, v).
        /// </summary>
        public DCEL_Subdivision(VecRat2 u, VecRat2 v)
            : this()
        {
            if (u == v)
            {
                throw new Exception("Tried to create a DCELSubdivision with a segment of length 0.");
            }

            DCEL_Vertex   vertex_u    = new DCEL_Vertex(u);
            DCEL_Vertex   vertex_v    = new DCEL_Vertex(v);
            DCEL_HalfEdge halfedge_uv = new DCEL_HalfEdge();
            DCEL_HalfEdge halfedge_vu = new DCEL_HalfEdge();
            DCEL_Face     face        = new DCEL_Face();

            vertex_u.IncidentEdge = halfedge_uv;
            vertex_v.IncidentEdge = halfedge_vu;

            halfedge_uv.Origin       = vertex_u;
            halfedge_uv.Twin         = halfedge_vu;
            halfedge_uv.IncidentFace = face;
            halfedge_uv.Prev         = halfedge_vu;
            halfedge_uv.Next         = halfedge_vu;

            halfedge_vu.Origin       = vertex_v;
            halfedge_vu.Twin         = halfedge_uv;
            halfedge_vu.IncidentFace = face;
            halfedge_vu.Prev         = halfedge_uv;
            halfedge_vu.Next         = halfedge_uv;

            face.InnerComponents.AddLast(halfedge_uv);

            Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex_u));
            Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex_u));
            HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(halfedge_uv));
            HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(halfedge_vu));
            Faces.Add(new RBTreeSetNode <DCEL_Face>(face));

            UnboundedFace = face;
        }
Пример #4
0
        private void CreateFaces()
        {
            RBTreeMap <DCEL_HalfEdge, HalfEdgeData> halfEdgesData = new RBTreeMap <DCEL_HalfEdge, HalfEdgeData>(DCEL_Element.Compare);

            foreach (DCEL_HalfEdge halfEdge in outputSubdivision.HalfEdges.Keys)
            {
                halfEdgesData.Add(new RBTreeMapNode <DCEL_HalfEdge, HalfEdgeData>(halfEdge, new HalfEdgeData()));
            }

            RBTreeMap <DCEL_HalfEdge, CycleData> cyclesData = new RBTreeMap <DCEL_HalfEdge, CycleData>(DCEL_Element.Compare);

            List <bool> visited = outputSubdivision.HalfEdges.Keys.Select(e => false).ToList();

            DCEL_Face unboundedFace = new DCEL_Face();

            outputSubdivision.UnboundedFace = unboundedFace;
            outputSubdivision.Faces.Add(new RBTreeSetNode <DCEL_Face>(unboundedFace));

            foreach (var halfEdgeNode in halfEdgesData.Nodes)
            {
                DCEL_HalfEdge halfEdge = halfEdgeNode.Key;
                if (halfEdgeNode.Value.Visited)
                {
                    continue;
                }

                DCEL_HalfEdge cycle = halfEdge.CycleNext.Min((a, b) => a.Origin.CompareTo(b.Origin));
                {
                    cycle = cycle.CycleNext.Where(e => e.Origin == cycle.Origin).Max(AngleComparisonUpperList_HalfEdge(cycle.Origin.Position));
                }

                CycleType cycleType = GetCycleType(cycle);

                if (cycleType == CycleType.Interior)
                {
                    DCEL_Face interiorFace = new DCEL_Face();
                    outputSubdivision.Faces.Add(new RBTreeSetNode <DCEL_Face>(interiorFace));

                    interiorFace.OuterComponent = cycle;
                    foreach (DCEL_HalfEdge cycleHalfEdge in cycle.CycleNext)
                    {
                        cycleHalfEdge.IncidentFace = interiorFace;
                    }
                }

                cyclesData.Add(new RBTreeMapNode <DCEL_HalfEdge, CycleData>(cycle, new CycleData(cycleType)));

                foreach (DCEL_HalfEdge cycleHalfEdge in halfEdge.CycleNext)
                {
                    HalfEdgeData data = halfEdgesData[cycleHalfEdge].Value;
                    data.Cycle = cycle;
                }
            }

            foreach (var cycleNode in cyclesData.Nodes)
            {
                if (cycleNode.Value.CycleType == CycleType.Interior)
                {
                    continue;
                }

                DCEL_HalfEdge cycle = cycleNode.Key;

                DCEL_HalfEdge leftPick = leftPicksMap[cycle.Origin].Value;
                if (leftPick == null)
                {
                    unboundedFace.InnerComponents.AddLast(cycle);
                    foreach (DCEL_HalfEdge cycleHalfEdge in cycle.CycleNext)
                    {
                        cycleHalfEdge.IncidentFace = unboundedFace;
                    }
                    continue;
                }

                DCEL_HalfEdge leftPickCycle     = halfEdgesData[leftPick].Value.Cycle;
                CycleType     leftPickCycleType = cyclesData[leftPickCycle].Value.CycleType;

                //if (leftPickCycleType == CycleType.Interior)
                //{
                //    leftPickCycle.IncidentFace.InnerComponents.AddLast(cycle);
                //    foreach (DCEL_HalfEdge cycleHalfEdge in cycle.CycleNext)
                //        cycleHalfEdge.IncidentFace = leftPickCycle.IncidentFace;
                //}

                cyclesData[leftPickCycle].Value.Children.Add(cycle);
                cycleNode.Value.IsRoot = false;
            }



            foreach (var cycleChildrenNode in cyclesData.Nodes)
            {
                if (!cycleChildrenNode.Value.IsRoot)
                {
                    continue;
                }

                DCEL_HalfEdge parentCycle     = cycleChildrenNode.Key;
                CycleType     parentCycleType = cyclesData[parentCycle].Value.CycleType;

                DCEL_Face face = parentCycle.IncidentFace;

                List <DCEL_HalfEdge> childCycles = cycleChildrenNode.Value.Children;

                Stack <DCEL_HalfEdge> unattachedCycles = new Stack <DCEL_HalfEdge>();
                foreach (DCEL_HalfEdge childCycle in childCycles)
                {
                    unattachedCycles.Push(childCycle);
                }

                while (!unattachedCycles.IsEmpty())
                {
                    DCEL_HalfEdge exteriorCycle = unattachedCycles.Pop();
                    face.InnerComponents.AddLast(exteriorCycle);
                    foreach (DCEL_HalfEdge exteriorCycleHalfEdge in exteriorCycle.CycleNext)
                    {
                        exteriorCycleHalfEdge.IncidentFace = face;
                    }
                    foreach (DCEL_HalfEdge child in cyclesData[exteriorCycle].Value.Children)
                    {
                        unattachedCycles.Push(child);
                    }
                }
            }
        }