mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Updated Clipper to 6.2.7
This commit is contained in:
		
							parent
							
								
									357f10732a
								
							
						
					
					
						commit
						e6c022a61c
					
				
					 2 changed files with 198 additions and 111 deletions
				
			
		|  | @ -1,10 +1,10 @@ | |||
| /*******************************************************************************
 | ||||
| *                                                                              * | ||||
| * Author    :  Angus Johnson                                                   * | ||||
| * Version   :  6.2.1                                                           * | ||||
| * Date      :  31 October 2014                                                 * | ||||
| * Version   :  6.2.7                                                           * | ||||
| * Date      :  17 January 2015                                                 * | ||||
| * Website   :  http://www.angusj.com                                           *
 | ||||
| * Copyright :  Angus Johnson 2010-2014                                         * | ||||
| * Copyright :  Angus Johnson 2010-2015                                         * | ||||
| *                                                                              * | ||||
| * License:                                                                     * | ||||
| * Use, modification & distribution is subject to Boost Software License Ver 1. * | ||||
|  | @ -381,13 +381,6 @@ Int128 Int128Mul (long64 lhs, long64 rhs) | |||
| // Miscellaneous global functions
 | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| void Swap(cInt& val1, cInt& val2) | ||||
| { | ||||
|   cInt tmp = val1; | ||||
|   val1 = val2; | ||||
|   val2 = tmp; | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| bool Orientation(const Path &poly) | ||||
| { | ||||
|     return Area(poly) >= 0; | ||||
|  | @ -758,9 +751,9 @@ inline void ReverseHorizontal(TEdge &e) | |||
|   //swap horizontal edges' Top and Bottom x's so they follow the natural
 | ||||
|   //progression of the bounds - ie so their xbots will align with the
 | ||||
|   //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
 | ||||
|   Swap(e.Top.X, e.Bot.X); | ||||
|   std::swap(e.Top.X, e.Bot.X); | ||||
| #ifdef use_xyz   | ||||
|   Swap(e.Top.Z, e.Bot.Z); | ||||
|   std::swap(e.Top.Z, e.Bot.Z); | ||||
| #endif | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
|  | @ -866,8 +859,8 @@ bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, | |||
| 
 | ||||
| bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b) | ||||
| { | ||||
|   if (seg1a > seg1b) Swap(seg1a, seg1b); | ||||
|   if (seg2a > seg2b) Swap(seg2a, seg2b); | ||||
|   if (seg1a > seg1b) std::swap(seg1a, seg1b); | ||||
|   if (seg2a > seg2b) std::swap(seg2a, seg2b); | ||||
|   return (seg1a < seg2b) && (seg2a < seg1b); | ||||
| } | ||||
| 
 | ||||
|  | @ -1000,11 +993,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) | |||
|       //unless a Skip edge is encountered when that becomes the top divide
 | ||||
|       Horz = Result; | ||||
|       while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev; | ||||
|       if (Horz->Prev->Top.X == Result->Next->Top.X)  | ||||
|       { | ||||
|         if (!NextIsForward) Result = Horz->Prev; | ||||
|       } | ||||
|       else if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev; | ||||
|       if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev; | ||||
|     } | ||||
|     while (E != Result)  | ||||
|     { | ||||
|  | @ -1024,11 +1013,8 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) | |||
|     { | ||||
|       Horz = Result; | ||||
|       while (IsHorizontal(*Horz->Next)) Horz = Horz->Next; | ||||
|       if (Horz->Next->Top.X == Result->Prev->Top.X)  | ||||
|       { | ||||
|         if (!NextIsForward) Result = Horz->Next; | ||||
|       } | ||||
|       else if (Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next; | ||||
|       if (Horz->Next->Top.X == Result->Prev->Top.X || | ||||
|           Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next; | ||||
|     } | ||||
| 
 | ||||
|     while (E != Result) | ||||
|  | @ -1155,17 +1141,17 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) | |||
|       return false; | ||||
|     } | ||||
|     E->Prev->OutIdx = Skip; | ||||
|     if (E->Prev->Bot.X < E->Prev->Top.X) ReverseHorizontal(*E->Prev); | ||||
|     MinimaList::value_type locMin; | ||||
|     locMin.Y = E->Bot.Y; | ||||
|     locMin.LeftBound = 0; | ||||
|     locMin.RightBound = E; | ||||
|     locMin.RightBound->Side = esRight; | ||||
|     locMin.RightBound->WindDelta = 0; | ||||
|     while (E->Next->OutIdx != Skip) | ||||
|     for (;;) | ||||
|     { | ||||
|       E->NextInLML = E->Next; | ||||
|       if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E); | ||||
|       if (E->Next->OutIdx == Skip) break; | ||||
|       E->NextInLML = E->Next; | ||||
|       E = E->Next; | ||||
|     } | ||||
|     m_MinimaList.push_back(locMin); | ||||
|  | @ -1371,6 +1357,7 @@ void Clipper::Reset() | |||
| { | ||||
|   ClipperBase::Reset(); | ||||
|   m_Scanbeam = ScanbeamList(); | ||||
|   m_Maxima = MaximaList(); | ||||
|   m_ActiveEdges = 0; | ||||
|   m_SortedEdges = 0; | ||||
|   for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm) | ||||
|  | @ -1378,12 +1365,24 @@ void Clipper::Reset() | |||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType) | ||||
| { | ||||
|     return Execute(clipType, solution, fillType, fillType); | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType) | ||||
| { | ||||
|     return Execute(clipType, polytree, fillType, fillType); | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| bool Clipper::Execute(ClipType clipType, Paths &solution, | ||||
|     PolyFillType subjFillType, PolyFillType clipFillType) | ||||
| { | ||||
|   if( m_ExecuteLocked ) return false; | ||||
|   if (m_HasOpenPaths) | ||||
|     throw clipperException("Error: PolyTree struct is need for open path clipping."); | ||||
|     throw clipperException("Error: PolyTree struct is needed for open path clipping."); | ||||
|   m_ExecuteLocked = true; | ||||
|   solution.resize(0); | ||||
|   m_SubjFillType = subjFillType; | ||||
|  | @ -1439,9 +1438,9 @@ bool Clipper::ExecuteInternal() | |||
|     cInt botY = PopScanbeam(); | ||||
|     do { | ||||
|       InsertLocalMinimaIntoAEL(botY); | ||||
|       ClearGhostJoins(); | ||||
|       ProcessHorizontals(false); | ||||
|       if (m_Scanbeam.empty()) break; | ||||
|       ProcessHorizontals(); | ||||
| 	  ClearGhostJoins(); | ||||
| 	  if (m_Scanbeam.empty()) break; | ||||
|       cInt topY = PopScanbeam(); | ||||
|       succeeded = ProcessIntersections(topY); | ||||
|       if (!succeeded) break; | ||||
|  | @ -1486,17 +1485,16 @@ bool Clipper::ExecuteInternal() | |||
| 
 | ||||
| void Clipper::InsertScanbeam(const cInt Y) | ||||
| { | ||||
|   //if (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) return;// avoid duplicates.
 | ||||
|   m_Scanbeam.push(Y); | ||||
|     m_Scanbeam.push(Y); | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| cInt Clipper::PopScanbeam() | ||||
| { | ||||
|   const cInt Y = m_Scanbeam.top(); | ||||
|   m_Scanbeam.pop(); | ||||
|   while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
 | ||||
|   return Y; | ||||
|     const cInt Y = m_Scanbeam.top(); | ||||
|     m_Scanbeam.pop(); | ||||
|     while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
 | ||||
|     return Y; | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  | @ -2356,7 +2354,6 @@ OutRec* Clipper::CreateOutRec() | |||
| 
 | ||||
| OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) | ||||
| { | ||||
|   bool ToFront = (e->Side == esLeft); | ||||
|   if(  e->OutIdx < 0 ) | ||||
|   { | ||||
|     OutRec *outRec = CreateOutRec(); | ||||
|  | @ -2377,7 +2374,8 @@ OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) | |||
|     //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; | ||||
| 	bool ToFront = (e->Side == esLeft); | ||||
| 	if (ToFront && (pt == op->Pt)) return op; | ||||
|     else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev; | ||||
| 
 | ||||
|     OutPt* newOp = new OutPt; | ||||
|  | @ -2393,13 +2391,23 @@ OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt) | |||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| void Clipper::ProcessHorizontals(bool IsTopOfScanbeam) | ||||
| OutPt* Clipper::GetLastOutPt(TEdge *e) | ||||
| { | ||||
| 	OutRec *outRec = m_PolyOuts[e->OutIdx]; | ||||
| 	if (e->Side == esLeft) | ||||
| 		return outRec->Pts; | ||||
| 	else | ||||
| 		return outRec->Pts->Prev; | ||||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| void Clipper::ProcessHorizontals() | ||||
| { | ||||
|   TEdge* horzEdge = m_SortedEdges; | ||||
|   while(horzEdge) | ||||
|   { | ||||
|     DeleteFromSEL(horzEdge); | ||||
|     ProcessHorizontal(horzEdge, IsTopOfScanbeam); | ||||
|     ProcessHorizontal(horzEdge); | ||||
|     horzEdge = m_SortedEdges; | ||||
|   } | ||||
| } | ||||
|  | @ -2564,7 +2572,7 @@ void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right) | |||
| * the AEL. These 'promoted' edges may in turn intersect [%] with other HEs.    * | ||||
| *******************************************************************************/ | ||||
| 
 | ||||
| void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) | ||||
| void Clipper::ProcessHorizontal(TEdge *horzEdge) | ||||
| { | ||||
|   Direction dir; | ||||
|   cInt horzLeft, horzRight; | ||||
|  | @ -2577,50 +2585,100 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) | |||
|   if (!eLastHorz->NextInLML) | ||||
|     eMaxPair = GetMaximaPair(eLastHorz); | ||||
| 
 | ||||
|   for (;;) | ||||
|   MaximaList::const_iterator maxIt; | ||||
|   MaximaList::const_reverse_iterator maxRit; | ||||
|   if (m_Maxima.size() > 0) | ||||
|   { | ||||
|       //get the first maxima in range (X) ...
 | ||||
|       if (dir == dLeftToRight) | ||||
|       { | ||||
|           maxIt = m_Maxima.begin(); | ||||
|           while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) maxIt++; | ||||
|           if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X) | ||||
|               maxIt = m_Maxima.end(); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|           maxRit = m_Maxima.rbegin(); | ||||
|           while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) maxRit++; | ||||
|           if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X) | ||||
|               maxRit = m_Maxima.rend(); | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
|   OutPt* op1 = 0; | ||||
| 
 | ||||
|   for (;;) //loop through consec. horizontal edges
 | ||||
|   { | ||||
| 		   | ||||
|     bool IsLastHorz = (horzEdge == eLastHorz); | ||||
|     TEdge* e = GetNextInAEL(horzEdge, dir); | ||||
|     while(e) | ||||
|     { | ||||
|       //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 &&  | ||||
|         e->Dx < horzEdge->NextInLML->Dx) break; | ||||
| 
 | ||||
|       TEdge* eNext = GetNextInAEL(e, dir); //saves eNext for later
 | ||||
|         //this code block inserts extra coords into horizontal edges (in output
 | ||||
|         //polygons) whereever maxima touch these horizontal edges. This helps
 | ||||
|         //'simplifying' polygons (ie if the Simplify property is set).
 | ||||
|         if (m_Maxima.size() > 0) | ||||
|         { | ||||
|             if (dir == dLeftToRight) | ||||
|             { | ||||
|                 while (maxIt != m_Maxima.end() && *maxIt < e->Curr.X)  | ||||
|                 { | ||||
|                     if (horzEdge->OutIdx >= 0) | ||||
|                         AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y)); | ||||
|                     maxIt++; | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 while (maxRit != m_Maxima.rend() && *maxRit > e->Curr.X) | ||||
|                 { | ||||
|                     if (horzEdge->OutIdx >= 0) | ||||
|                         AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y)); | ||||
|                     maxRit++; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|       if ((dir == dLeftToRight && e->Curr.X <= horzRight) || | ||||
|         (dir == dRightToLeft && e->Curr.X >= horzLeft)) | ||||
|       { | ||||
|         //so far we're still in range of the horizontal Edge  but make sure
 | ||||
|         if ((dir == dLeftToRight && e->Curr.X > horzRight) || | ||||
| 			(dir == dRightToLeft && e->Curr.X < horzLeft)) break; | ||||
| 
 | ||||
| 		//Also 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 &&  | ||||
| 			e->Dx < horzEdge->NextInLML->Dx) break; | ||||
| 
 | ||||
| 		if (horzEdge->OutIdx >= 0)  //note: may be done multiple times
 | ||||
| 		{ | ||||
|             op1 = AddOutPt(horzEdge, e->Curr); | ||||
| 			TEdge* eNextHorz = m_SortedEdges; | ||||
| 			while (eNextHorz) | ||||
| 			{ | ||||
| 				if (eNextHorz->OutIdx >= 0 && | ||||
| 					HorzSegmentsOverlap(horzEdge->Bot.X, | ||||
| 					horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) | ||||
| 				{ | ||||
|                     OutPt* op2 = GetLastOutPt(eNextHorz); | ||||
|                     AddJoin(op2, op1, eNextHorz->Top); | ||||
| 				} | ||||
| 				eNextHorz = eNextHorz->NextInSEL; | ||||
| 			} | ||||
| 			AddGhostJoin(op1, horzEdge->Bot); //also may be done multiple times
 | ||||
| 		} | ||||
| 		 | ||||
| 		//OK, 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) | ||||
|           { | ||||
|             OutPt* op1 = AddOutPt(horzEdge, horzEdge->Top); | ||||
|             TEdge* eNextHorz = m_SortedEdges; | ||||
|             while (eNextHorz) | ||||
|             { | ||||
|               if (eNextHorz->OutIdx >= 0 && | ||||
|                 HorzSegmentsOverlap(horzEdge->Bot.X, | ||||
|                 horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) | ||||
|               { | ||||
|                 OutPt* op2 = AddOutPt(eNextHorz, eNextHorz->Bot); | ||||
|                 AddJoin(op2, op1, eNextHorz->Top); | ||||
|               } | ||||
|               eNextHorz = eNextHorz->NextInSEL; | ||||
|             } | ||||
|             AddGhostJoin(op1, horzEdge->Bot); | ||||
|             AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top); | ||||
|           } | ||||
|           DeleteFromAEL(horzEdge); | ||||
|           DeleteFromAEL(eMaxPair); | ||||
|           return; | ||||
|         } | ||||
|         else if(dir == dLeftToRight) | ||||
|          | ||||
| 		if(dir == dLeftToRight) | ||||
|         { | ||||
|           IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); | ||||
|           IntersectEdges(horzEdge, e, Pt); | ||||
|  | @ -2630,28 +2688,43 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam) | |||
|           IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y); | ||||
|           IntersectEdges( e, horzEdge, Pt); | ||||
|         } | ||||
|         TEdge* eNext = GetNextInAEL(e, dir); | ||||
|         SwapPositionsInAEL( horzEdge, e ); | ||||
|       } | ||||
|       else if( (dir == dLeftToRight && e->Curr.X >= horzRight) || | ||||
|        (dir == dRightToLeft && e->Curr.X <= horzLeft) ) break; | ||||
|       e = eNext; | ||||
|     } //end while
 | ||||
|         e = eNext; | ||||
|     } //end while(e)
 | ||||
| 
 | ||||
| 	//Break out of loop if HorzEdge.NextInLML is not also horizontal ...
 | ||||
| 	if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break; | ||||
| 
 | ||||
| 	UpdateEdgeIntoAEL(horzEdge); | ||||
|     if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot); | ||||
|     GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); | ||||
| 
 | ||||
|     if (horzEdge->NextInLML && IsHorizontal(*horzEdge->NextInLML)) | ||||
|     { | ||||
|       UpdateEdgeIntoAEL(horzEdge); | ||||
|       if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot); | ||||
|       GetHorzDirection(*horzEdge, dir, horzLeft, horzRight); | ||||
|     } else | ||||
|       break; | ||||
|   } //end for (;;)
 | ||||
| 
 | ||||
|   if(horzEdge->NextInLML) | ||||
|   if (horzEdge->OutIdx >= 0 && !op1) | ||||
|   { | ||||
|       op1 = GetLastOutPt(horzEdge); | ||||
|       TEdge* eNextHorz = m_SortedEdges; | ||||
|       while (eNextHorz) | ||||
|       { | ||||
|           if (eNextHorz->OutIdx >= 0 && | ||||
|               HorzSegmentsOverlap(horzEdge->Bot.X, | ||||
|               horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X)) | ||||
|           { | ||||
|               OutPt* op2 = GetLastOutPt(eNextHorz); | ||||
|               AddJoin(op2, op1, eNextHorz->Top); | ||||
|           } | ||||
|           eNextHorz = eNextHorz->NextInSEL; | ||||
|       } | ||||
|       AddGhostJoin(op1, horzEdge->Top); | ||||
|   } | ||||
| 
 | ||||
|   if (horzEdge->NextInLML) | ||||
|   { | ||||
|     if(horzEdge->OutIdx >= 0) | ||||
|     { | ||||
|       OutPt* op1 = AddOutPt( horzEdge, horzEdge->Top); | ||||
|       if (isTopOfScanbeam) AddGhostJoin(op1, horzEdge->Bot); | ||||
|       op1 = AddOutPt( horzEdge, horzEdge->Top); | ||||
|       UpdateEdgeIntoAEL(horzEdge); | ||||
|       if (horzEdge->WindDelta == 0) return; | ||||
|       //nb: HorzEdge is no longer horizontal here
 | ||||
|  | @ -2906,6 +2979,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) | |||
| 
 | ||||
|     if(IsMaximaEdge) | ||||
|     { | ||||
|       if (m_StrictSimple) m_Maxima.push_back(e->Top.X); | ||||
|       TEdge* ePrev = e->PrevInAEL; | ||||
|       DoMaxima(e); | ||||
|       if( !ePrev ) e = m_ActiveEdges; | ||||
|  | @ -2927,6 +3001,8 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) | |||
|         e->Curr.Y = topY; | ||||
|       } | ||||
| 
 | ||||
|       //When StrictlySimple and 'e' is being touched by another edge, then
 | ||||
|       //make sure both edges have a vertex here ...
 | ||||
|       if (m_StrictSimple) | ||||
|       {   | ||||
|         TEdge* ePrev = e->PrevInAEL; | ||||
|  | @ -2948,7 +3024,9 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) | |||
|   } | ||||
| 
 | ||||
|   //3. Process horizontals at the Top of the scanbeam ...
 | ||||
|   ProcessHorizontals(true); | ||||
|   m_Maxima.sort(); | ||||
|   ProcessHorizontals(); | ||||
|   m_Maxima.clear(); | ||||
| 
 | ||||
|   //4. Promote intermediate vertices ...
 | ||||
|   e = m_ActiveEdges; | ||||
|  | @ -2995,6 +3073,7 @@ void Clipper::FixupOutPolygon(OutRec &outrec) | |||
|   OutPt *lastOK = 0; | ||||
|   outrec.BottomPt = 0; | ||||
|   OutPt *pp = outrec.Pts; | ||||
|   bool preserveCol = m_PreserveCollinear || m_StrictSimple; | ||||
| 
 | ||||
|   for (;;) | ||||
|   { | ||||
|  | @ -3008,8 +3087,7 @@ void Clipper::FixupOutPolygon(OutRec &outrec) | |||
|     //test for duplicate points and collinear edges ...
 | ||||
|     if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) ||  | ||||
|       (SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) && | ||||
|       (!m_PreserveCollinear ||  | ||||
|       !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) | ||||
|       (!preserveCol || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt)))) | ||||
|     { | ||||
|       lastOK = 0; | ||||
|       OutPt *tmp = pp; | ||||
|  | @ -3309,7 +3387,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) | |||
|   OutPt *op2 = j->OutPt2, *op2b; | ||||
| 
 | ||||
|   //There are 3 kinds of joins for output polygons ...
 | ||||
|   //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere
 | ||||
|   //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are vertices anywhere
 | ||||
|   //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal).
 | ||||
|   //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same
 | ||||
|   //location at the Bottom of the overlapping segment (& Join.OffPt is above).
 | ||||
|  | @ -3508,6 +3586,7 @@ void Clipper::JoinCommonEdges() | |||
|     OutRec *outRec2 = GetOutRec(join->OutPt2->Idx); | ||||
| 
 | ||||
|     if (!outRec1->Pts || !outRec2->Pts) continue; | ||||
|     if (outRec1->IsOpen || outRec2->IsOpen) continue; | ||||
| 
 | ||||
|     //get the polygon fragment with the correct hole state (FirstLeft)
 | ||||
|     //before calling JoinPoints() ...
 | ||||
|  | @ -4355,7 +4434,7 @@ void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool p | |||
| } | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| void TranslatePath(const Path& input, Path& output, IntPoint delta)  | ||||
| void TranslatePath(const Path& input, Path& output, const IntPoint delta) | ||||
| { | ||||
|   //precondition: input != output
 | ||||
|   output.resize(input.size()); | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| /*******************************************************************************
 | ||||
| *                                                                              * | ||||
| * Author    :  Angus Johnson                                                   * | ||||
| * Version   :  6.2.1                                                           * | ||||
| * Date      :  31 October 2014                                                 * | ||||
| * Version   :  6.2.7                                                           * | ||||
| * Date      :  17 January 2015                                                 * | ||||
| * Website   :  http://www.angusj.com                                           *
 | ||||
| * Copyright :  Angus Johnson 2010-2014                                         * | ||||
| * Copyright :  Angus Johnson 2010-2015                                         * | ||||
| *                                                                              * | ||||
| * License:                                                                     * | ||||
| * Use, modification & distribution is subject to Boost Software License Ver 1. * | ||||
|  | @ -34,7 +34,7 @@ | |||
| #ifndef clipper_hpp | ||||
| #define clipper_hpp | ||||
| 
 | ||||
| #define CLIPPER_VERSION "6.2.0" | ||||
| #define CLIPPER_VERSION "6.2.6" | ||||
| 
 | ||||
| //use_int32: When enabled 32bit ints are used instead of 64bit ints. This
 | ||||
| //improve performance but coordinate values are limited to the range +/- 46340
 | ||||
|  | @ -50,6 +50,7 @@ | |||
| //#define use_deprecated  
 | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <list> | ||||
| #include <set> | ||||
| #include <stdexcept> | ||||
| #include <cstring> | ||||
|  | @ -200,7 +201,6 @@ enum EdgeSide { esLeft = 1, esRight = 2}; | |||
| struct TEdge; | ||||
| struct IntersectNode; | ||||
| struct LocalMinimum; | ||||
| struct Scanbeam; | ||||
| struct OutPt; | ||||
| struct OutRec; | ||||
| struct Join; | ||||
|  | @ -232,7 +232,6 @@ protected: | |||
|   void PopLocalMinima(); | ||||
|   virtual void Reset(); | ||||
|   TEdge* ProcessBound(TEdge* E, bool IsClockwise); | ||||
|   void DoMinimaLML(TEdge* E1, TEdge* E2, bool IsClosed); | ||||
|   TEdge* DescendToMin(TEdge *&E); | ||||
|   void AscendToMax(TEdge *&E, bool Appending, bool IsClosed); | ||||
| 
 | ||||
|  | @ -253,14 +252,20 @@ public: | |||
|   Clipper(int initOptions = 0); | ||||
|   ~Clipper(); | ||||
|   bool Execute(ClipType clipType, | ||||
|     Paths &solution, | ||||
|     PolyFillType subjFillType = pftEvenOdd, | ||||
|     PolyFillType clipFillType = pftEvenOdd); | ||||
|       Paths &solution, | ||||
|       PolyFillType fillType = pftEvenOdd); | ||||
|   bool Execute(ClipType clipType, | ||||
|     PolyTree &polytree, | ||||
|     PolyFillType subjFillType = pftEvenOdd, | ||||
|     PolyFillType clipFillType = pftEvenOdd); | ||||
|   bool ReverseSolution() {return m_ReverseOutput;}; | ||||
|       Paths &solution, | ||||
|       PolyFillType subjFillType, | ||||
|       PolyFillType clipFillType); | ||||
|   bool Execute(ClipType clipType, | ||||
|       PolyTree &polytree, | ||||
|       PolyFillType fillType = pftEvenOdd); | ||||
|   bool Execute(ClipType clipType, | ||||
|       PolyTree &polytree, | ||||
|       PolyFillType subjFillType, | ||||
|       PolyFillType clipFillType); | ||||
|   bool ReverseSolution() { return m_ReverseOutput; }; | ||||
|   void ReverseSolution(bool value) {m_ReverseOutput = value;}; | ||||
|   bool StrictlySimple() {return m_StrictSimple;}; | ||||
|   void StrictlySimple(bool value) {m_StrictSimple = value;}; | ||||
|  | @ -272,13 +277,15 @@ protected: | |||
|   void Reset(); | ||||
|   virtual bool ExecuteInternal(); | ||||
| private: | ||||
|   PolyOutList       m_PolyOuts; | ||||
|   JoinList          m_Joins; | ||||
|   JoinList          m_GhostJoins; | ||||
|   IntersectList     m_IntersectList; | ||||
|   ClipType          m_ClipType; | ||||
|   PolyOutList      m_PolyOuts; | ||||
|   JoinList         m_Joins; | ||||
|   JoinList         m_GhostJoins; | ||||
|   IntersectList    m_IntersectList; | ||||
|   ClipType         m_ClipType; | ||||
|   typedef std::priority_queue<cInt> ScanbeamList; | ||||
|   ScanbeamList      m_Scanbeam; | ||||
|   ScanbeamList     m_Scanbeam; | ||||
|   typedef std::list<cInt> MaximaList; | ||||
|   MaximaList       m_Maxima; | ||||
|   TEdge           *m_ActiveEdges; | ||||
|   TEdge           *m_SortedEdges; | ||||
|   bool             m_ExecuteLocked; | ||||
|  | @ -307,8 +314,8 @@ private: | |||
|   bool IsTopHorz(const cInt XPos); | ||||
|   void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2); | ||||
|   void DoMaxima(TEdge *e); | ||||
|   void ProcessHorizontals(bool IsTopOfScanbeam); | ||||
|   void ProcessHorizontal(TEdge *horzEdge, bool isTopOfScanbeam); | ||||
|   void ProcessHorizontals(); | ||||
|   void ProcessHorizontal(TEdge *horzEdge); | ||||
|   void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); | ||||
|   OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); | ||||
|   OutRec* GetOutRec(int idx); | ||||
|  | @ -316,6 +323,7 @@ private: | |||
|   void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); | ||||
|   OutRec* CreateOutRec(); | ||||
|   OutPt* AddOutPt(TEdge *e, const IntPoint &pt); | ||||
|   OutPt* GetLastOutPt(TEdge *e); | ||||
|   void DisposeAllOutRecs(); | ||||
|   void DisposeOutRec(PolyOutList::size_type index); | ||||
|   bool ProcessIntersections(const cInt topY); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci