Esempio n. 1
0
        private bool JustBeforeLocMin(TEdge Edge)
        {
            TEdge e = Edge;

            if (!IsHorizontal(e))
            {
                return(this.SharedVertWithNextIsBot(e));
            }
            while (IsHorizontal(e.Next))
            {
                e = e.Next;
            }
            return(e.Next.Top.Y < e.Bot.Y);
        }
Esempio n. 2
0
        private bool JustBeforeLocMin(TEdge Edge)
        {
            TEdge tEdge = Edge;

            if (ClipperBase.IsHorizontal(tEdge))
            {
                while (ClipperBase.IsHorizontal(tEdge.Next))
                {
                    tEdge = tEdge.Next;
                }
                return(tEdge.Next.Top.Y < tEdge.Bot.Y);
            }
            return(this.SharedVertWithNextIsBot(tEdge));
        }
Esempio n. 3
0
 private bool MoreAbove(TEdge Edge)
 {
     if (IsHorizontal(Edge))
     {
         Edge = this.GetLastHorz(Edge);
         return(Edge.Next.Top.Y < Edge.Top.Y);
     }
     if (IsHorizontal(Edge.Next))
     {
         Edge = this.GetLastHorz(Edge.Next);
         return(Edge.Next.Top.Y < Edge.Top.Y);
     }
     return(Edge.Next.Top.Y < Edge.Top.Y);
 }
Esempio n. 4
0
 private bool AllHorizontal(TEdge Edge)
 {
     if (!ClipperBase.IsHorizontal(Edge))
     {
         return(false);
     }
     for (TEdge next = Edge.Next; next != Edge; next = next.Next)
     {
         if (!ClipperBase.IsHorizontal(next))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 5
0
 private bool AllHorizontal(TEdge Edge)
 {
     if (!IsHorizontal(Edge))
     {
         return(false);
     }
     for (TEdge edge = Edge.Next; edge != Edge; edge = edge.Next)
     {
         if (!IsHorizontal(edge))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 6
0
 private void InitEdge2(TEdge e, PolyType polyType)
 {
     if (e.Curr.Y >= e.Next.Curr.Y)
     {
         e.Bot = e.Curr;
         e.Top = e.Next.Curr;
     }
     else
     {
         e.Top = e.Curr;
         e.Bot = e.Next.Curr;
     }
     this.SetDx(e);
     e.PolyTyp = polyType;
 }
Esempio n. 7
0
        private bool MoreBelow(TEdge Edge)
        {
            TEdge e = Edge;

            if (IsHorizontal(e))
            {
                while (IsHorizontal(e.Next))
                {
                    e = e.Next;
                }
                return(e.Next.Bot.Y > e.Bot.Y);
            }
            if (!IsHorizontal(e.Next))
            {
                return(e.Bot == e.Next.Top);
            }
            while (IsHorizontal(e.Next))
            {
                e = e.Next;
            }
            return(e.Next.Bot.Y > e.Bot.Y);
        }
Esempio n. 8
0
        private bool MoreBelow(TEdge Edge)
        {
            TEdge tEdge = Edge;

            if (ClipperBase.IsHorizontal(tEdge))
            {
                while (ClipperBase.IsHorizontal(tEdge.Next))
                {
                    tEdge = tEdge.Next;
                }
                return(tEdge.Next.Bot.Y > tEdge.Bot.Y);
            }
            if (ClipperBase.IsHorizontal(tEdge.Next))
            {
                while (ClipperBase.IsHorizontal(tEdge.Next))
                {
                    tEdge = tEdge.Next;
                }
                return(tEdge.Next.Bot.Y > tEdge.Bot.Y);
            }
            return(tEdge.Bot == tEdge.Next.Top);
        }
Esempio n. 9
0
        private void AscendToMax(ref TEdge E, bool Appending, bool IsClosed)
        {
            if (E.OutIdx == -2)
            {
                E = E.Next;
                if (!this.MoreAbove(E.Prev))
                {
                    return;
                }
            }
            if ((IsHorizontal(E) && Appending) && (E.Bot != E.Prev.Bot))
            {
                this.ReverseHorizontal(E);
            }
            TEdge next = E;

            while ((E.Next.OutIdx != -2) && ((E.Next.Top.Y != E.Top.Y) || IsHorizontal(E.Next)))
            {
                E.NextInLML = E.Next;
                E           = E.Next;
                if (IsHorizontal(E) && (E.Bot.X != E.Prev.Top.X))
                {
                    this.ReverseHorizontal(E);
                }
            }
            if (!Appending)
            {
                if (next.OutIdx == -2)
                {
                    next = next.Next;
                }
                if (next != E.Next)
                {
                    this.DoMinimaLML(null, next, IsClosed);
                }
            }
            E = E.Next;
        }
Esempio n. 10
0
        private void AscendToMax(ref TEdge E, bool Appending, bool IsClosed)
        {
            if (E.OutIdx == -2)
            {
                E = E.Next;
                if (!this.MoreAbove(E.Prev))
                {
                    return;
                }
            }
            if (ClipperBase.IsHorizontal(E) && Appending && E.Bot != E.Prev.Bot)
            {
                this.ReverseHorizontal(E);
            }
            TEdge tEdge = E;

            while (E.Next.OutIdx != -2 && (E.Next.Top.Y != E.Top.Y || ClipperBase.IsHorizontal(E.Next)))
            {
                E.NextInLML = E.Next;
                E           = E.Next;
                if (ClipperBase.IsHorizontal(E) && E.Bot.X != E.Prev.Top.X)
                {
                    this.ReverseHorizontal(E);
                }
            }
            if (!Appending)
            {
                if (tEdge.OutIdx == -2)
                {
                    tEdge = tEdge.Next;
                }
                if (tEdge != E.Next)
                {
                    this.DoMinimaLML(null, tEdge, IsClosed);
                }
            }
            E = E.Next;
        }
Esempio n. 11
0
		//------------------------------------------------------------------------------
		
		private void UpdateEdgeIntoAEL(ref TEdge e)
		{
			if (e.NextInLML == null)
				throw new ClipperException("UpdateEdgeIntoAEL: invalid call");
			TEdge AelPrev = e.PrevInAEL;
			TEdge AelNext = e.NextInAEL;
			e.NextInLML.OutIdx = e.OutIdx;
			if (AelPrev != null)
				AelPrev.NextInAEL = e.NextInLML;
			else m_ActiveEdges = e.NextInLML;
			if (AelNext != null)
				AelNext.PrevInAEL = e.NextInLML;
			e.NextInLML.Side = e.Side;
			e.NextInLML.WindDelta = e.WindDelta;
			e.NextInLML.WindCnt = e.WindCnt;
			e.NextInLML.WindCnt2 = e.WindCnt2;
			e = e.NextInLML;
			e.Curr = e.Bot;
			e.PrevInAEL = AelPrev;
			e.NextInAEL = AelNext;
			if (!IsHorizontal(e)) InsertScanbeam(e.Top.Y);
		}
Esempio n. 12
0
		//------------------------------------------------------------------------------
		
		private OutPt AddOutPt(TEdge e, IntPoint pt)
		{
			bool ToFront = (e.Side == EdgeSide.esLeft);
			if(  e.OutIdx < 0 )
			{
				OutRec outRec = CreateOutRec();
				outRec.IsOpen = (e.WindDelta == 0);
				OutPt newOp = new OutPt();
				outRec.Pts = newOp;
				newOp.Idx = outRec.Idx;
				newOp.Pt = pt;
				newOp.Next = newOp;
				newOp.Prev = newOp;
				if (!outRec.IsOpen)
					SetHoleState(e, outRec);
				#if use_xyz
				if (pt == e.Bot)
					newOp.Pt = e.Bot;
				else if (pt == e.Top)
					newOp.Pt = e.Top;
				else
					SetZ(ref newOp.Pt, e);
				#endif
				e.OutIdx = outRec.Idx; //nb: do this after SetZ !
				return newOp;
			} else
			{
				OutRec outRec = m_PolyOuts[e.OutIdx];
				//OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'
				OutPt op = outRec.Pts;
				if (ToFront && pt == op.Pt) return op;
				else if (!ToFront && pt == op.Prev.Pt) return op.Prev;
				
				OutPt newOp = new OutPt();
				newOp.Idx = outRec.Idx;
				newOp.Pt = pt;
				newOp.Next = op;
				newOp.Prev = op.Prev;
				newOp.Prev.Next = newOp;
				op.Prev = newOp;
				if (ToFront) outRec.Pts = newOp;
				#if use_xyz
				if (pt == e.Bot)
					newOp.Pt = e.Bot;
				else if (pt == e.Top)
					newOp.Pt = e.Top;
				else
					SetZ(ref newOp.Pt, e);
				#endif
				return newOp;
			}
		}
Esempio n. 13
0
		//------------------------------------------------------------------------------
		
		private void AppendPolygon(TEdge e1, TEdge e2)
		{
			//get the start and ends of both output polygons ...
			OutRec outRec1 = m_PolyOuts[e1.OutIdx];
			OutRec outRec2 = m_PolyOuts[e2.OutIdx];
			
			OutRec holeStateRec;
			if (Param1RightOfParam2(outRec1, outRec2)) 
				holeStateRec = outRec2;
			else if (Param1RightOfParam2(outRec2, outRec1))
				holeStateRec = outRec1;
			else
				holeStateRec = GetLowermostRec(outRec1, outRec2);
			
			OutPt p1_lft = outRec1.Pts;
			OutPt p1_rt = p1_lft.Prev;
			OutPt p2_lft = outRec2.Pts;
			OutPt p2_rt = p2_lft.Prev;
			
			EdgeSide side;
			//join e2 poly onto e1 poly and delete pointers to e2 ...
			if(  e1.Side == EdgeSide.esLeft )
			{
				if (e2.Side == EdgeSide.esLeft)
				{
					//z y x a b c
					ReversePolyPtLinks(p2_lft);
					p2_lft.Next = p1_lft;
					p1_lft.Prev = p2_lft;
					p1_rt.Next = p2_rt;
					p2_rt.Prev = p1_rt;
					outRec1.Pts = p2_rt;
				} else
				{
					//x y z a b c
					p2_rt.Next = p1_lft;
					p1_lft.Prev = p2_rt;
					p2_lft.Prev = p1_rt;
					p1_rt.Next = p2_lft;
					outRec1.Pts = p2_lft;
				}
				side = EdgeSide.esLeft;
			} else
			{
				if (e2.Side == EdgeSide.esRight)
				{
					//a b c z y x
					ReversePolyPtLinks( p2_lft );
					p1_rt.Next = p2_rt;
					p2_rt.Prev = p1_rt;
					p2_lft.Next = p1_lft;
					p1_lft.Prev = p2_lft;
				} else
				{
					//a b c x y z
					p1_rt.Next = p2_lft;
					p2_lft.Prev = p1_rt;
					p1_lft.Prev = p2_rt;
					p2_rt.Next = p1_lft;
				}
				side = EdgeSide.esRight;
			}
			
			outRec1.BottomPt = null; 
			if (holeStateRec == outRec2)
			{
				if (outRec2.FirstLeft != outRec1)
					outRec1.FirstLeft = outRec2.FirstLeft;
				outRec1.IsHole = outRec2.IsHole;
			}
			outRec2.Pts = null;
			outRec2.BottomPt = null;
			
			outRec2.FirstLeft = outRec1;
			
			int OKIdx = e1.OutIdx;
			int ObsoleteIdx = e2.OutIdx;
			
			e1.OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly
			e2.OutIdx = Unassigned;
			
			TEdge e = m_ActiveEdges;
			while( e != null )
			{
				if( e.OutIdx == ObsoleteIdx )
				{
					e.OutIdx = OKIdx;
					e.Side = side;
					break;
				}
				e = e.NextInAEL;
			}
			outRec2.Idx = outRec1.Idx;
		}
Esempio n. 14
0
		//------------------------------------------------------------------------------
		
		private void InitEdge2(TEdge e, PolyType polyType)
		{
			if (e.Curr.Y >= e.Next.Curr.Y)
			{
				e.Bot = e.Curr;
				e.Top = e.Next.Curr;
			}
			else
			{
				e.Top = e.Curr;
				e.Bot = e.Next.Curr;
			}
			SetDx(e);
			e.PolyTyp = polyType;
		}
Esempio n. 15
0
        public bool AddPath(List <IntPoint> pg, PolyType polyType, bool Closed)
        {
            if (!Closed)
            {
                throw new ClipperException("AddPath: Open paths have been disabled.");
            }
            int  num  = pg.Count - 1;
            bool flag = num > 0 && (Closed || pg[0] == pg[num]);

            while (num > 0 && pg[num] == pg[0])
            {
                num--;
            }
            while (num > 0 && pg[num] == pg[num - 1])
            {
                num--;
            }
            if ((Closed && num < 2) || (!Closed && num < 1))
            {
                return(false);
            }
            List <TEdge> list = new List <TEdge>(num + 1);

            for (int i = 0; i <= num; i++)
            {
                list.Add(new TEdge());
            }
            try
            {
                list[1].Curr = pg[1];
                this.RangeTest(pg[0], ref this.m_UseFullRange);
                this.RangeTest(pg[num], ref this.m_UseFullRange);
                this.InitEdge(list[0], list[1], list[num], pg[0]);
                this.InitEdge(list[num], list[0], list[num - 1], pg[num]);
                for (int j = num - 1; j >= 1; j--)
                {
                    this.RangeTest(pg[j], ref this.m_UseFullRange);
                    this.InitEdge(list[j], list[j + 1], list[j - 1], pg[j]);
                }
            }
            catch
            {
                bool result = false;
                return(result);
            }
            TEdge tEdge = list[0];

            if (!flag)
            {
                tEdge.Prev.OutIdx = -2;
            }
            TEdge tEdge2 = tEdge;
            TEdge tEdge3 = tEdge;

            while (true)
            {
                if (tEdge2.Curr == tEdge2.Next.Curr)
                {
                    if (tEdge2 == tEdge2.Next)
                    {
                        break;
                    }
                    if (tEdge2 == tEdge)
                    {
                        tEdge = tEdge2.Next;
                    }
                    tEdge2 = this.RemoveEdge(tEdge2);
                    tEdge3 = tEdge2;
                }
                else
                {
                    if (tEdge2.Prev == tEdge2.Next)
                    {
                        break;
                    }
                    if ((flag || (tEdge2.Prev.OutIdx != -2 && tEdge2.OutIdx != -2 && tEdge2.Next.OutIdx != -2)) && ClipperBase.SlopesEqual(tEdge2.Prev.Curr, tEdge2.Curr, tEdge2.Next.Curr, this.m_UseFullRange) && Closed && (!this.PreserveCollinear || !this.Pt2IsBetweenPt1AndPt3(tEdge2.Prev.Curr, tEdge2.Curr, tEdge2.Next.Curr)))
                    {
                        if (tEdge2 == tEdge)
                        {
                            tEdge = tEdge2.Next;
                        }
                        tEdge2 = this.RemoveEdge(tEdge2);
                        tEdge2 = tEdge2.Prev;
                        tEdge3 = tEdge2;
                    }
                    else
                    {
                        tEdge2 = tEdge2.Next;
                        if (tEdge2 == tEdge3)
                        {
                            break;
                        }
                    }
                }
            }
            if ((!Closed && tEdge2 == tEdge2.Next) || (Closed && tEdge2.Prev == tEdge2.Next))
            {
                return(false);
            }
            this.m_edges.Add(list);
            if (!Closed)
            {
                this.m_HasOpenPaths = true;
            }
            TEdge tEdge4 = tEdge;

            tEdge2 = tEdge;
            do
            {
                this.InitEdge2(tEdge2, polyType);
                if (tEdge2.Top.Y < tEdge4.Top.Y)
                {
                    tEdge4 = tEdge2;
                }
                tEdge2 = tEdge2.Next;
            }while (tEdge2 != tEdge);
            if (this.AllHorizontal(tEdge2))
            {
                if (flag)
                {
                    tEdge2.Prev.OutIdx = -2;
                }
                this.AscendToMax(ref tEdge2, false, false);
                return(true);
            }
            tEdge2 = tEdge.Prev;
            if (tEdge2.Prev == tEdge2.Next)
            {
                tEdge4 = tEdge2.Next;
            }
            else if (!flag && tEdge2.Top.Y == tEdge4.Top.Y)
            {
                if ((ClipperBase.IsHorizontal(tEdge2) || ClipperBase.IsHorizontal(tEdge2.Next)) && tEdge2.Next.Bot.Y == tEdge4.Top.Y)
                {
                    tEdge4 = tEdge2.Next;
                }
                else if (this.SharedVertWithPrevAtTop(tEdge2))
                {
                    tEdge4 = tEdge2;
                }
                else if (tEdge2.Top == tEdge2.Prev.Top)
                {
                    tEdge4 = tEdge2.Prev;
                }
                else
                {
                    tEdge4 = tEdge2.Next;
                }
            }
            else
            {
                tEdge2 = tEdge4;
                while (ClipperBase.IsHorizontal(tEdge4) || tEdge4.Top == tEdge4.Next.Top || tEdge4.Top == tEdge4.Next.Bot)
                {
                    tEdge4 = tEdge4.Next;
                    if (tEdge4 == tEdge2)
                    {
                        while (ClipperBase.IsHorizontal(tEdge4) || !this.SharedVertWithPrevAtTop(tEdge4))
                        {
                            tEdge4 = tEdge4.Next;
                        }
                        break;
                    }
                }
            }
            tEdge2 = tEdge4;
            do
            {
                tEdge2 = this.AddBoundsToLML(tEdge2, Closed);
            }while (tEdge2 != tEdge4);
            return(true);
        }
Esempio n. 16
0
		//------------------------------------------------------------------------------
		
		private bool IsMaxima(TEdge e, double Y)
		{
			return (e != null && e.Top.Y == Y && e.NextInLML == null);
		}
Esempio n. 17
0
		//------------------------------------------------------------------------------
		
		internal static bool SlopesEqual(TEdge e1, TEdge e2, bool UseFullRange)
		{
			if (UseFullRange)
				return Int128.Int128Mul(e1.Delta.Y, e2.Delta.X) ==
					Int128.Int128Mul(e1.Delta.X, e2.Delta.Y);
			else return (cInt)(e1.Delta.Y) * (e2.Delta.X) ==
				(cInt)(e1.Delta.X) * (e2.Delta.Y);
		}
Esempio n. 18
0
		//------------------------------------------------------------------------------
		
		private TEdge GetNextInAEL(TEdge e, Direction Direction)
		{
			return Direction == Direction.dLeftToRight ? e.NextInAEL: e.PrevInAEL;
		}
Esempio n. 19
0
		//------------------------------------------------------------------------------
		
		private bool IsMinima(TEdge e)
		{
			return e != null && (e.Prev.NextInLML != e) && (e.Next.NextInLML != e);
		}
Esempio n. 20
0
		//------------------------------------------------------------------------------
		
		private void ProcessHorizontal(TEdge horzEdge, bool isTopOfScanbeam)
		{
			Direction dir;
			cInt horzLeft, horzRight;
			
			GetHorzDirection(horzEdge, out dir, out horzLeft, out horzRight);
			
			TEdge eLastHorz = horzEdge, eMaxPair = null;
			while (eLastHorz.NextInLML != null && IsHorizontal(eLastHorz.NextInLML)) 
				eLastHorz = eLastHorz.NextInLML;
			if (eLastHorz.NextInLML == null)
				eMaxPair = GetMaximaPair(eLastHorz);
			
			for (;;)
			{
				bool IsLastHorz = (horzEdge == eLastHorz);
				TEdge e = GetNextInAEL(horzEdge, dir);
				while(e != null)
				{
					//Break if we've got to the end of an intermediate horizontal edge ...
					//nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal.
					if (e.Curr.X == horzEdge.Top.X && horzEdge.NextInLML != null && 
					    e.Dx < horzEdge.NextInLML.Dx) break;
					
					TEdge eNext = GetNextInAEL(e, dir); //saves eNext for later
					
					if ((dir == Direction.dLeftToRight && e.Curr.X <= horzRight) ||
					    (dir == Direction.dRightToLeft && e.Curr.X >= horzLeft))
					{
						//so far we're still in range of the horizontal Edge  but make sure
						//we're at the last of consec. horizontals when matching with eMaxPair
						if(e == eMaxPair && IsLastHorz)
						{
							if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0) 
								PrepareHorzJoins(horzEdge, isTopOfScanbeam);
							if (dir == Direction.dLeftToRight)
								IntersectEdges(horzEdge, e, e.Top);
							else
								IntersectEdges(e, horzEdge, e.Top);
							if (eMaxPair.OutIdx >= 0) throw 
								new ClipperException("ProcessHorizontal error");
							return;
						}
						else if(dir == Direction.dLeftToRight)
						{
							IntPoint Pt = new IntPoint(e.Curr.X, horzEdge.Curr.Y);
							IntersectEdges(horzEdge, e, Pt, true);
						}
						else
						{
							IntPoint Pt = new IntPoint(e.Curr.X, horzEdge.Curr.Y);
							IntersectEdges(e, horzEdge, Pt, true);
						}
						SwapPositionsInAEL(horzEdge, e);
					}
					else if ((dir == Direction.dLeftToRight && e.Curr.X >= horzRight) ||
					         (dir == Direction.dRightToLeft && e.Curr.X <= horzLeft)) break;
					e = eNext;
				} //end while
				
				if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0)
					PrepareHorzJoins(horzEdge, isTopOfScanbeam);
				
				if (horzEdge.NextInLML != null && IsHorizontal(horzEdge.NextInLML))
				{
					UpdateEdgeIntoAEL(ref horzEdge);
					if (horzEdge.OutIdx >= 0) AddOutPt(horzEdge, horzEdge.Bot);
					GetHorzDirection(horzEdge, out dir, out horzLeft, out horzRight);
				} else
					break;
			} //end for (;;)
			
			if(horzEdge.NextInLML != null)
			{
				if(horzEdge.OutIdx >= 0)
				{
					OutPt op1 = AddOutPt( horzEdge, horzEdge.Top);
					UpdateEdgeIntoAEL(ref horzEdge);
					if (horzEdge.WindDelta == 0) return;
					//nb: HorzEdge is no longer horizontal here
					TEdge ePrev = horzEdge.PrevInAEL;
					TEdge eNext = horzEdge.NextInAEL;
					if (ePrev != null && ePrev.Curr.X == horzEdge.Bot.X &&
					    ePrev.Curr.Y == horzEdge.Bot.Y && ePrev.WindDelta != 0 &&
					    (ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y &&
					 SlopesEqual(horzEdge, ePrev, m_UseFullRange)))
					{
						OutPt op2 = AddOutPt(ePrev, horzEdge.Bot);
						AddJoin(op1, op2, horzEdge.Top);
					}
					else if (eNext != null && eNext.Curr.X == horzEdge.Bot.X &&
					         eNext.Curr.Y == horzEdge.Bot.Y && eNext.WindDelta != 0 &&
					         eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y &&
					         SlopesEqual(horzEdge, eNext, m_UseFullRange))
					{
						OutPt op2 = AddOutPt(eNext, horzEdge.Bot);
						AddJoin(op1, op2, horzEdge.Top);
					}
				}
				else
					UpdateEdgeIntoAEL(ref horzEdge); 
			}
			else if (eMaxPair != null)
			{
				if (eMaxPair.OutIdx >= 0)
				{
					if (dir == Direction.dLeftToRight)
						IntersectEdges(horzEdge, eMaxPair, horzEdge.Top); 
					else
						IntersectEdges(eMaxPair, horzEdge, horzEdge.Top);
					if (eMaxPair.OutIdx >= 0) throw 
						new ClipperException("ProcessHorizontal error");
				} else
				{
					DeleteFromAEL(horzEdge);
					DeleteFromAEL(eMaxPair);
				}
			} else
			{
				if (horzEdge.OutIdx >= 0) AddOutPt(horzEdge, horzEdge.Top);
				DeleteFromAEL(horzEdge);
			}
		}
Esempio n. 21
0
		//------------------------------------------------------------------------
		
		void PrepareHorzJoins(TEdge horzEdge, bool isTopOfScanbeam)
		{
			//get the last Op for this horizontal edge
			//the point may be anywhere along the horizontal ...
			OutPt outPt = m_PolyOuts[horzEdge.OutIdx].Pts;
			if (horzEdge.Side != EdgeSide.esLeft) outPt = outPt.Prev;
			
			//First, match up overlapping horizontal edges (eg when one polygon's
			//intermediate horz edge overlaps an intermediate horz edge of another, or
			//when one polygon sits on top of another) ...
			for (int i = 0; i < m_GhostJoins.Count; ++i)
			{
				Join j = m_GhostJoins[i];
				if (HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, horzEdge.Bot, horzEdge.Top))
					AddJoin(j.OutPt1, outPt, j.OffPt);
			}
			//Also, since horizontal edges at the top of one SB are often removed from
			//the AEL before we process the horizontal edges at the bottom of the next,
			//we need to create 'ghost' Join records of 'contrubuting' horizontals that
			//we can compare with horizontals at the bottom of the next SB.
			if (isTopOfScanbeam) 
				if (outPt.Pt == horzEdge.Top)
					AddGhostJoin(outPt, horzEdge.Bot); 
			else
				AddGhostJoin(outPt, horzEdge.Top);
		}
Esempio n. 22
0
		//------------------------------------------------------------------------------
		
		void GetHorzDirection(TEdge HorzEdge, out Direction Dir, out cInt Left, out cInt Right)
		{
			if (HorzEdge.Bot.X < HorzEdge.Top.X)
			{
				Left = HorzEdge.Bot.X;
				Right = HorzEdge.Top.X;
				Dir = Direction.dLeftToRight;
			} else
			{
				Left = HorzEdge.Top.X;
				Right = HorzEdge.Bot.X;
				Dir = Direction.dRightToLeft;
			}
		}
Esempio n. 23
0
		//------------------------------------------------------------------------------
		
		private void DoMaxima(TEdge e)
		{
			TEdge eMaxPair = GetMaximaPair(e);
			if (eMaxPair == null)
			{
				if (e.OutIdx >= 0)
					AddOutPt(e, e.Top);
				DeleteFromAEL(e);
				return;
			}
			
			TEdge eNext = e.NextInAEL;
			while(eNext != null && eNext != eMaxPair)
			{
				IntersectEdges(e, eNext, e.Top, true);
				SwapPositionsInAEL(e, eNext);
				eNext = e.NextInAEL;
			}
			
			if(e.OutIdx == Unassigned && eMaxPair.OutIdx == Unassigned)
			{
				DeleteFromAEL(e);
				DeleteFromAEL(eMaxPair);
			}
			else if( e.OutIdx >= 0 && eMaxPair.OutIdx >= 0 )
			{
				IntersectEdges( e, eMaxPair, e.Top);
			}
			#if use_lines
			else if (e.WindDelta == 0)
			{
				if (e.OutIdx >= 0) 
				{
					AddOutPt(e, e.Top);
					e.OutIdx = Unassigned;
				}
				DeleteFromAEL(e);
				
				if (eMaxPair.OutIdx >= 0)
				{
					AddOutPt(eMaxPair, e.Top);
					eMaxPair.OutIdx = Unassigned;
				}
				DeleteFromAEL(eMaxPair);
			} 
			#endif
			else throw new ClipperException("DoMaxima error");
		}
Esempio n. 24
0
		//------------------------------------------------------------------------------
		
		private bool IsIntermediate(TEdge e, double Y)
		{
			return (e.Top.Y == Y && e.NextInLML != null);
		}
Esempio n. 25
0
		//------------------------------------------------------------------------------
		
		internal static bool IsHorizontal(TEdge e)
		{
			return e.Delta.Y == 0;
		}
Esempio n. 26
0
		//------------------------------------------------------------------------------
		
		private TEdge GetMaximaPair(TEdge e)
		{
			TEdge result = null;
			if ((e.Next.Top == e.Top) && e.Next.NextInLML == null)
				result = e.Next;
			else if ((e.Prev.Top == e.Top) && e.Prev.NextInLML == null)
				result = e.Prev;
			if (result != null && (result.OutIdx == Skip ||
			                       (result.NextInAEL == result.PrevInAEL && !IsHorizontal(result))))
				return null;
			return result;
		}
Esempio n. 27
0
		//------------------------------------------------------------------------------
		
		private void InitEdge(TEdge e, TEdge eNext,
		                      TEdge ePrev, IntPoint pt)
		{
			e.Next = eNext;
			e.Prev = ePrev;
			e.Curr = pt;
			e.OutIdx = Unassigned;
		}
Esempio n. 28
0
		//------------------------------------------------------------------------------
		
		private void DeleteFromAEL(TEdge e)
		{
			TEdge AelPrev = e.PrevInAEL;
			TEdge AelNext = e.NextInAEL;
			if (AelPrev == null && AelNext == null && (e != m_ActiveEdges))
				return; //already deleted
			if (AelPrev != null)
				AelPrev.NextInAEL = AelNext;
			else m_ActiveEdges = AelNext;
			if (AelNext != null)
				AelNext.PrevInAEL = AelPrev;
			e.NextInAEL = null;
			e.PrevInAEL = null;
		}
Esempio n. 29
0
		//------------------------------------------------------------------------------
		
		TEdge RemoveEdge(TEdge e)
		{
			//removes e from double_linked_list (but without removing from memory)
			e.Prev.Next = e.Next;
			e.Next.Prev = e.Prev;
			TEdge result = e.Next;
			e.Prev = null; //flag as removed (see ClipperBase.Clear)
			return result;
		}
Esempio n. 30
0
		//------------------------------------------------------------------------------
		
		private void IntersectEdges(TEdge e1, TEdge e2, IntPoint pt, bool protect = false)
		{
			//e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before
			//e2 in AEL except when e1 is being inserted at the intersection point ...
			
			bool e1stops = !protect && e1.NextInLML == null &&
				e1.Top.X == pt.X && e1.Top.Y == pt.Y;
			bool e2stops = !protect && e2.NextInLML == null &&
				e2.Top.X == pt.X && e2.Top.Y == pt.Y;
			bool e1Contributing = (e1.OutIdx >= 0);
			bool e2Contributing = (e2.OutIdx >= 0);
			
			#if use_lines
			//if either edge is on an OPEN path ...
			if (e1.WindDelta == 0 || e2.WindDelta == 0)
			{
				//ignore subject-subject open path intersections UNLESS they
				//are both open paths, AND they are both 'contributing maximas' ...
				if (e1.WindDelta == 0 && e2.WindDelta == 0)
				{
					if ((e1stops || e2stops) && e1Contributing && e2Contributing)
						AddLocalMaxPoly(e1, e2, pt);
				}
				//if intersecting a subj line with a subj poly ...
				else if (e1.PolyTyp == e2.PolyTyp && 
				         e1.WindDelta != e2.WindDelta && m_ClipType == ClipType.ctUnion)
				{
					if (e1.WindDelta == 0)
					{
						if (e2Contributing)
						{
							AddOutPt(e1, pt);
							if (e1Contributing) e1.OutIdx = Unassigned;
						}
					}
					else
					{
						if (e1Contributing)
						{
							AddOutPt(e2, pt);
							if (e2Contributing) e2.OutIdx = Unassigned;
						}
					}
				}
				else if (e1.PolyTyp != e2.PolyTyp)
				{
					if ((e1.WindDelta == 0) && Math.Abs(e2.WindCnt) == 1 && 
					    (m_ClipType != ClipType.ctUnion || e2.WindCnt2 == 0))
					{
						AddOutPt(e1, pt);
						if (e1Contributing) e1.OutIdx = Unassigned;
					}
					else if ((e2.WindDelta == 0) && (Math.Abs(e1.WindCnt) == 1) && 
					         (m_ClipType != ClipType.ctUnion || e1.WindCnt2 == 0))
					{
						AddOutPt(e2, pt);
						if (e2Contributing) e2.OutIdx = Unassigned;
					}
				}
				
				if (e1stops)
					if (e1.OutIdx < 0) DeleteFromAEL(e1);
				else throw new ClipperException("Error intersecting polylines");
				if (e2stops) 
					if (e2.OutIdx < 0) DeleteFromAEL(e2);
				else throw new ClipperException("Error intersecting polylines");
				return;
			}
			#endif
			
			//update winding counts...
			//assumes that e1 will be to the Right of e2 ABOVE the intersection
			if (e1.PolyTyp == e2.PolyTyp)
			{
				if (IsEvenOddFillType(e1))
				{
					int oldE1WindCnt = e1.WindCnt;
					e1.WindCnt = e2.WindCnt;
					e2.WindCnt = oldE1WindCnt;
				}
				else
				{
					if (e1.WindCnt + e2.WindDelta == 0) e1.WindCnt = -e1.WindCnt;
					else e1.WindCnt += e2.WindDelta;
					if (e2.WindCnt - e1.WindDelta == 0) e2.WindCnt = -e2.WindCnt;
					else e2.WindCnt -= e1.WindDelta;
				}
			}
			else
			{
				if (!IsEvenOddFillType(e2)) e1.WindCnt2 += e2.WindDelta;
				else e1.WindCnt2 = (e1.WindCnt2 == 0) ? 1 : 0;
				if (!IsEvenOddFillType(e1)) e2.WindCnt2 -= e1.WindDelta;
				else e2.WindCnt2 = (e2.WindCnt2 == 0) ? 1 : 0;
			}
			
			PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
			if (e1.PolyTyp == PolyType.ptSubject)
			{
				e1FillType = m_SubjFillType;
				e1FillType2 = m_ClipFillType;
			}
			else
			{
				e1FillType = m_ClipFillType;
				e1FillType2 = m_SubjFillType;
			}
			if (e2.PolyTyp == PolyType.ptSubject)
			{
				e2FillType = m_SubjFillType;
				e2FillType2 = m_ClipFillType;
			}
			else
			{
				e2FillType = m_ClipFillType;
				e2FillType2 = m_SubjFillType;
			}
			
			int e1Wc, e2Wc;
			switch (e1FillType)
			{
			case PolyFillType.pftPositive: e1Wc = e1.WindCnt; break;
			case PolyFillType.pftNegative: e1Wc = -e1.WindCnt; break;
			default: e1Wc = Math.Abs(e1.WindCnt); break;
			}
			switch (e2FillType)
			{
			case PolyFillType.pftPositive: e2Wc = e2.WindCnt; break;
			case PolyFillType.pftNegative: e2Wc = -e2.WindCnt; break;
			default: e2Wc = Math.Abs(e2.WindCnt); break;
			}
			
			if (e1Contributing && e2Contributing)
			{
				if ( e1stops || e2stops || 
				    (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
				    (e1.PolyTyp != e2.PolyTyp && m_ClipType != ClipType.ctXor))
					AddLocalMaxPoly(e1, e2, pt);
				else
				{
					AddOutPt(e1, pt);
					AddOutPt(e2, pt);
					SwapSides(e1, e2);
					SwapPolyIndexes(e1, e2);
				}
			}
			else if (e1Contributing)
			{
				if (e2Wc == 0 || e2Wc == 1)
				{
					AddOutPt(e1, pt);
					SwapSides(e1, e2);
					SwapPolyIndexes(e1, e2);
				}
				
			}
			else if (e2Contributing)
			{
				if (e1Wc == 0 || e1Wc == 1)
				{
					AddOutPt(e2, pt);
					SwapSides(e1, e2);
					SwapPolyIndexes(e1, e2);
				}
			}
			else if ( (e1Wc == 0 || e1Wc == 1) && 
			         (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops )
			{
				//neither edge is currently contributing ...
				cInt e1Wc2, e2Wc2;
				switch (e1FillType2)
				{
				case PolyFillType.pftPositive: e1Wc2 = e1.WindCnt2; break;
				case PolyFillType.pftNegative: e1Wc2 = -e1.WindCnt2; break;
				default: e1Wc2 = Math.Abs(e1.WindCnt2); break;
				}
				switch (e2FillType2)
				{
				case PolyFillType.pftPositive: e2Wc2 = e2.WindCnt2; break;
				case PolyFillType.pftNegative: e2Wc2 = -e2.WindCnt2; break;
				default: e2Wc2 = Math.Abs(e2.WindCnt2); break;
				}
				
				if (e1.PolyTyp != e2.PolyTyp)
					AddLocalMinPoly(e1, e2, pt);
				else if (e1Wc == 1 && e2Wc == 1)
					switch (m_ClipType)
				{
					case ClipType.ctIntersection:
					if (e1Wc2 > 0 && e2Wc2 > 0)
						AddLocalMinPoly(e1, e2, pt);
					break;
					case ClipType.ctUnion:
					if (e1Wc2 <= 0 && e2Wc2 <= 0)
						AddLocalMinPoly(e1, e2, pt);
					break;
					case ClipType.ctDifference:
					if (((e1.PolyTyp == PolyType.ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
					    ((e1.PolyTyp == PolyType.ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
						AddLocalMinPoly(e1, e2, pt);
					break;
					case ClipType.ctXor:
					AddLocalMinPoly(e1, e2, pt);
					break;
				}
				else 
					SwapSides(e1, e2);
			}
			
			if ((e1stops != e2stops) &&
			    ((e1stops && (e1.OutIdx >= 0)) || (e2stops && (e2.OutIdx >= 0))))
			{
				SwapSides(e1, e2);
				SwapPolyIndexes(e1, e2);
			}
			
			//finally, delete any non-contributing maxima edges  ...
			if (e1stops) DeleteFromAEL(e1);
			if (e2stops) DeleteFromAEL(e2);
		}
Esempio n. 31
0
		//------------------------------------------------------------------------------
		
		private static void SwapSides(TEdge edge1, TEdge edge2)
		{
			EdgeSide side = edge1.Side;
			edge1.Side = edge2.Side;
			edge2.Side = side;
		}
Esempio n. 32
0
		//------------------------------------------------------------------------------
		
		private static void SwapPolyIndexes(TEdge edge1, TEdge edge2)
		{
			int outIdx = edge1.OutIdx;
			edge1.OutIdx = edge2.OutIdx;
			edge2.OutIdx = outIdx;
		}
Esempio n. 33
0
		//------------------------------------------------------------------------------
		
		private void SetHoleState(TEdge e, OutRec outRec)
		{
			bool isHole = false;
			TEdge e2 = e.PrevInAEL;
			while (e2 != null)
			{
				if (e2.OutIdx >= 0)
				{
					isHole = !isHole;
					if (outRec.FirstLeft == null)
						outRec.FirstLeft = m_PolyOuts[e2.OutIdx];
				}
				e2 = e2.PrevInAEL;
			}
			if (isHole) outRec.IsHole = true;
		}
Esempio n. 34
0
		//------------------------------------------------------------------------------
		
		private OutPt AddLocalMinPoly(TEdge e1, TEdge e2, IntPoint pt)
		{
			OutPt result;
			TEdge e, prevE;
			if (IsHorizontal(e2) || (e1.Dx > e2.Dx))
			{
				result = AddOutPt(e1, pt);
				e2.OutIdx = e1.OutIdx;
				e1.Side = EdgeSide.esLeft;
				e2.Side = EdgeSide.esRight;
				e = e1;
				if (e.PrevInAEL == e2)
					prevE = e2.PrevInAEL; 
				else
					prevE = e.PrevInAEL;
			}
			else
			{
				result = AddOutPt(e2, pt);
				e1.OutIdx = e2.OutIdx;
				e1.Side = EdgeSide.esRight;
				e2.Side = EdgeSide.esLeft;
				e = e2;
				if (e.PrevInAEL == e1)
					prevE = e1.PrevInAEL;
				else
					prevE = e.PrevInAEL;
			}
			
			if (prevE != null && prevE.OutIdx >= 0 &&
			    (TopX(prevE, pt.Y) == TopX(e, pt.Y)) &&
			    SlopesEqual(e, prevE, m_UseFullRange) &&
			    (e.WindDelta != 0) && (prevE.WindDelta != 0))
			{
				OutPt outPt = AddOutPt(prevE, pt);
				AddJoin(result, outPt, e.Top);
			}
			return result;
		}
Esempio n. 35
0
        public IntRect GetBounds()
        {
            IntRect     result      = default(IntRect);
            LocalMinima localMinima = this.m_MinimaList;

            if (localMinima == null)
            {
                return(result);
            }
            result.left   = localMinima.LeftBound.Bot.X;
            result.top    = localMinima.LeftBound.Bot.Y;
            result.right  = localMinima.LeftBound.Bot.X;
            result.bottom = localMinima.LeftBound.Bot.Y;
            while (localMinima != null)
            {
                if (localMinima.LeftBound.Bot.Y > result.bottom)
                {
                    result.bottom = localMinima.LeftBound.Bot.Y;
                }
                TEdge tEdge = localMinima.LeftBound;
                while (true)
                {
                    TEdge tEdge2 = tEdge;
                    while (tEdge.NextInLML != null)
                    {
                        if (tEdge.Bot.X < result.left)
                        {
                            result.left = tEdge.Bot.X;
                        }
                        if (tEdge.Bot.X > result.right)
                        {
                            result.right = tEdge.Bot.X;
                        }
                        tEdge = tEdge.NextInLML;
                    }
                    if (tEdge.Bot.X < result.left)
                    {
                        result.left = tEdge.Bot.X;
                    }
                    if (tEdge.Bot.X > result.right)
                    {
                        result.right = tEdge.Bot.X;
                    }
                    if (tEdge.Top.X < result.left)
                    {
                        result.left = tEdge.Top.X;
                    }
                    if (tEdge.Top.X > result.right)
                    {
                        result.right = tEdge.Top.X;
                    }
                    if (tEdge.Top.Y < result.top)
                    {
                        result.top = tEdge.Top.Y;
                    }
                    if (tEdge2 != localMinima.LeftBound)
                    {
                        break;
                    }
                    tEdge = localMinima.RightBound;
                }
                localMinima = localMinima.Next;
            }
            return(result);
        }
Esempio n. 36
0
		//------------------------------------------------------------------------------
		
		private bool IntersectPoint(TEdge edge1, TEdge edge2, out IntPoint ip)
		{
			ip = new IntPoint();
			double b1, b2;
			//nb: with very large coordinate values, it's possible for SlopesEqual() to 
			//return false but for the edge.Dx value be equal due to double precision rounding.
			if (SlopesEqual(edge1, edge2, m_UseFullRange) || edge1.Dx == edge2.Dx)
			{
				if (edge2.Bot.Y > edge1.Bot.Y)
					ip.Y = edge2.Bot.Y;
				else
					ip.Y = edge1.Bot.Y;
				return false;
			}
			else if (edge1.Delta.X == 0)
			{
				ip.X = edge1.Bot.X;
				if (IsHorizontal(edge2))
				{
					ip.Y = edge2.Bot.Y;
				}
				else
				{
					b2 = edge2.Bot.Y - (edge2.Bot.X / edge2.Dx);
					ip.Y = Round(ip.X / edge2.Dx + b2);
				}
			}
			else if (edge2.Delta.X == 0)
			{
				ip.X = edge2.Bot.X;
				if (IsHorizontal(edge1))
				{
					ip.Y = edge1.Bot.Y;
				}
				else
				{
					b1 = edge1.Bot.Y - (edge1.Bot.X / edge1.Dx);
					ip.Y = Round(ip.X / edge1.Dx + b1);
				}
			}
			else
			{
				b1 = edge1.Bot.X - edge1.Bot.Y * edge1.Dx;
				b2 = edge2.Bot.X - edge2.Bot.Y * edge2.Dx;
				double q = (b2 - b1) / (edge1.Dx - edge2.Dx);
				ip.Y = Round(q);
				if (Math.Abs(edge1.Dx) < Math.Abs(edge2.Dx))
					ip.X = Round(edge1.Dx * q + b1);
				else
					ip.X = Round(edge2.Dx * q + b2);
			}
			
			if (ip.Y < edge1.Top.Y || ip.Y < edge2.Top.Y)
			{
				if (edge1.Top.Y > edge2.Top.Y)
				{
					ip.Y = edge1.Top.Y;
					ip.X = TopX(edge2, edge1.Top.Y);
					return ip.X < edge1.Top.X;
				}
				else
				{
					ip.Y = edge2.Top.Y;
					ip.X = TopX(edge1, edge2.Top.Y);
					return ip.X > edge2.Top.X;
				}
			}
			else
				return true;
		}
Esempio n. 37
0
		//------------------------------------------------------------------------------
		
		private bool ProcessIntersections(cInt botY, cInt topY)
		{
			if( m_ActiveEdges == null ) return true;
			try {
				BuildIntersectList(botY, topY);
				if ( m_IntersectNodes == null) return true;
				if (m_IntersectNodes.Next == null || FixupIntersectionOrder()) 
					ProcessIntersectList();
				else 
					return false;
			}
			catch {
				m_SortedEdges = null;
				DisposeIntersectNodes();
				throw new ClipperException("ProcessIntersections error");
			}
			m_SortedEdges = null;
			return true;
		}
Esempio n. 38
0
		//------------------------------------------------------------------------------
		
		private void DeleteFromSEL(TEdge e)
		{
			TEdge SelPrev = e.PrevInSEL;
			TEdge SelNext = e.NextInSEL;
			if (SelPrev == null && SelNext == null && (e != m_SortedEdges))
				return; //already deleted
			if (SelPrev != null)
				SelPrev.NextInSEL = SelNext;
			else m_SortedEdges = SelNext;
			if (SelNext != null)
				SelNext.PrevInSEL = SelPrev;
			e.NextInSEL = null;
			e.PrevInSEL = null;
		}
Esempio n. 39
0
 internal static bool IsHorizontal(TEdge e)
 {
     return(e.Delta.Y == 0L);
 }
Esempio n. 40
0
		//------------------------------------------------------------------------------
		
		private void BuildIntersectList(cInt botY, cInt topY)
		{
			if ( m_ActiveEdges == null ) return;
			
			//prepare for sorting ...
			TEdge e = m_ActiveEdges;
			m_SortedEdges = e;
			while( e != null )
			{
				e.PrevInSEL = e.PrevInAEL;
				e.NextInSEL = e.NextInAEL;
				e.Curr.X = TopX( e, topY );
				e = e.NextInAEL;
			}
			
			//bubblesort ...
			bool isModified = true;
			while( isModified && m_SortedEdges != null )
			{
				isModified = false;
				e = m_SortedEdges;
				while( e.NextInSEL != null )
				{
					TEdge eNext = e.NextInSEL;
					IntPoint pt;
					if (e.Curr.X > eNext.Curr.X)
					{
						if (!IntersectPoint(e, eNext, out pt) && e.Curr.X > eNext.Curr.X +1)
							throw new ClipperException("Intersection error");
						if (pt.Y > botY)
						{
							pt.Y = botY;
							if (Math.Abs(e.Dx) > Math.Abs(eNext.Dx))
								pt.X = TopX(eNext, botY); else
								pt.X = TopX(e, botY);
						}
						InsertIntersectNode(e, eNext, pt);
						SwapPositionsInSEL(e, eNext);
						isModified = true;
					}
					else
						e = eNext;
				}
				if( e.PrevInSEL != null ) e.PrevInSEL.NextInSEL = null;
				else break;
			}
			m_SortedEdges = null;
		}
Esempio n. 41
0
		//------------------------------------------------------------------------------
		
		private static cInt TopX(TEdge edge, cInt currentY)
		{
			if (currentY == edge.Top.Y)
				return edge.Top.X;
			return edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y));
		}
Esempio n. 42
0
		//------------------------------------------------------------------------------
		
		private void InsertIntersectNode(TEdge e1, TEdge e2, IntPoint pt)
		{
			IntersectNode newNode = new IntersectNode();
			newNode.Edge1 = e1;
			newNode.Edge2 = e2;
			newNode.Pt = pt;
			newNode.Next = null;
			if (m_IntersectNodes == null) m_IntersectNodes = newNode;
			else if (newNode.Pt.Y > m_IntersectNodes.Pt.Y)
			{
				newNode.Next = m_IntersectNodes;
				m_IntersectNodes = newNode;
			}
			else
			{
				IntersectNode iNode = m_IntersectNodes;
				while (iNode.Next != null && newNode.Pt.Y < iNode.Next.Pt.Y)
					iNode = iNode.Next;
				newNode.Next = iNode.Next;
				iNode.Next = newNode;
			}
		}
Esempio n. 43
0
        public bool AddPath(List <IntPoint> pg, PolyType polyType, bool Closed)
        {
            if (!Closed)
            {
                throw new ClipperException("AddPath: Open paths have been disabled.");
            }
            int  num  = pg.Count - 1;
            bool flag = (num > 0) && (Closed || (pg[0] == pg[num]));

            while ((num > 0) && (pg[num] == pg[0]))
            {
                num--;
            }
            while ((num > 0) && (pg[num] == pg[num - 1]))
            {
                num--;
            }
            if ((Closed && (num < 2)) || (!Closed && (num < 1)))
            {
                return(false);
            }
            List <TEdge> item = new List <TEdge>(num + 1);

            for (int i = 0; i <= num; i++)
            {
                item.Add(new TEdge());
            }
            try
            {
                item[1].Curr = pg[1];
                this.RangeTest(pg[0], ref this.m_UseFullRange);
                this.RangeTest(pg[num], ref this.m_UseFullRange);
                this.InitEdge(item[0], item[1], item[num], pg[0]);
                this.InitEdge(item[num], item[0], item[num - 1], pg[num]);
                for (int j = num - 1; j >= 1; j--)
                {
                    this.RangeTest(pg[j], ref this.m_UseFullRange);
                    this.InitEdge(item[j], item[j + 1], item[j - 1], pg[j]);
                }
            }
            catch
            {
                return(false);
            }
            TEdge next = item[0];

            if (!flag)
            {
                next.Prev.OutIdx = -2;
            }
            TEdge e     = next;
            TEdge edge3 = next;

Label_01E7:
            while (e.Curr == e.Next.Curr)
            {
                if (e == e.Next)
                {
                    goto Label_0342;
                }
                if (e == next)
                {
                    next = e.Next;
                }
                e     = this.RemoveEdge(e);
                edge3 = e;
            }
            if (e.Prev != e.Next)
            {
                if ((flag || (((e.Prev.OutIdx != -2) && (e.OutIdx != -2)) && (e.Next.OutIdx != -2))) && ((SlopesEqual(e.Prev.Curr, e.Curr, e.Next.Curr, this.m_UseFullRange) && Closed) && (!this.PreserveCollinear || !this.Pt2IsBetweenPt1AndPt3(e.Prev.Curr, e.Curr, e.Next.Curr))))
                {
                    if (e == next)
                    {
                        next = e.Next;
                    }
                    e     = this.RemoveEdge(e).Prev;
                    edge3 = e;
                    goto Label_01E7;
                }
                e = e.Next;
                if (e != edge3)
                {
                    goto Label_01E7;
                }
            }
Label_0342:
            if ((!Closed && (e == e.Next)) || (Closed && (e.Prev == e.Next)))
            {
                return(false);
            }
            this.m_edges.Add(item);
            if (!Closed)
            {
                this.m_HasOpenPaths = true;
            }
            TEdge prev = next;

            e = next;
            do
            {
                this.InitEdge2(e, polyType);
                if (e.Top.Y < prev.Top.Y)
                {
                    prev = e;
                }
                e = e.Next;
            }while (e != next);
            if (this.AllHorizontal(e))
            {
                if (flag)
                {
                    e.Prev.OutIdx = -2;
                }
                this.AscendToMax(ref e, false, false);
                return(true);
            }
            e = next.Prev;
            if (e.Prev == e.Next)
            {
                prev = e.Next;
            }
            else if (!flag && (e.Top.Y == prev.Top.Y))
            {
                if ((IsHorizontal(e) || IsHorizontal(e.Next)) && (e.Next.Bot.Y == prev.Top.Y))
                {
                    prev = e.Next;
                }
                else if (this.SharedVertWithPrevAtTop(e))
                {
                    prev = e;
                }
                else if (e.Top == e.Prev.Top)
                {
                    prev = e.Prev;
                }
                else
                {
                    prev = e.Next;
                }
            }
            else
            {
                e = prev;
                while ((IsHorizontal(prev) || (prev.Top == prev.Next.Top)) || (prev.Top == prev.Next.Bot))
                {
                    prev = prev.Next;
                    if (prev == e)
                    {
                        while (IsHorizontal(prev) || !this.SharedVertWithPrevAtTop(prev))
                        {
                            prev = prev.Next;
                        }
                        break;
                    }
                }
            }
            e = prev;
            do
            {
                e = this.AddBoundsToLML(e, Closed);
            }while (e != prev);
            return(true);
        }
Esempio n. 44
0
		//------------------------------------------------------------------------------
		
		
		private void AddLocalMaxPoly(TEdge e1, TEdge e2, IntPoint pt)
		{
			AddOutPt(e1, pt);
			if (e1.OutIdx == e2.OutIdx)
			{
				e1.OutIdx = Unassigned;
				e2.OutIdx = Unassigned;
			}
			else if (e1.OutIdx < e2.OutIdx) 
				AppendPolygon(e1, e2);
			else 
				AppendPolygon(e2, e1);
		}