2013-07-16 18:09:53 +00:00
/*******************************************************************************
* *
* Author : Angus Johnson *
2015-02-22 14:13:52 +00:00
* Version : 6.2 .9 *
* Date : 16 February 2015 *
2013-07-16 18:09:53 +00:00
* Website : http : //www.angusj.com *
2015-02-15 15:10:04 +00:00
* Copyright : Angus Johnson 2010 - 2015 *
2013-07-16 18:09:53 +00:00
* *
* License : *
* Use , modification & distribution is subject to Boost Software License Ver 1. *
* http : //www.boost.org/LICENSE_1_0.txt *
* *
* Attributions : *
* The code in this library is an extension of Bala Vatti ' s clipping algorithm : *
* " A generic solution to polygon clipping " *
* Communications of the ACM , Vol 35 , Issue 7 ( July 1992 ) pp 56 - 63. *
* http : //portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling : implementation and algorithms *
* By Max K . Agoston *
* Springer ; 1 edition ( January 4 , 2005 ) *
* http : //books.google.com/books?q=vatti+clipping+agoston *
* *
* See also : *
* " Polygon Offsetting by Computing Winding Numbers " *
* Paper no . DETC2005 - 85513 pp . 565 - 575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference ( IDETC / CIE2005 ) *
* September 24 - 28 , 2005 , Long Beach , California , USA *
* http : //www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifndef clipper_hpp
# define clipper_hpp
2015-02-15 15:10:04 +00:00
# define CLIPPER_VERSION "6.2.6"
2013-11-20 10:35:58 +00:00
//use_int32: When enabled 32bit ints are used instead of 64bit ints. This
//improve performance but coordinate values are limited to the range +/- 46340
//#define use_int32
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz
//use_lines: Enables line clipping. Adds a very minor cost to performance.
2013-11-21 13:15:38 +00:00
# define use_lines
2013-11-20 10:35:58 +00:00
2014-11-08 11:05:27 +00:00
//use_deprecated: Enables temporary support for the obsolete functions
2013-11-20 14:59:19 +00:00
//#define use_deprecated
2013-11-20 10:35:58 +00:00
2013-07-16 18:09:53 +00:00
# include <vector>
2017-03-02 16:11:46 +00:00
# include <deque>
2013-07-16 18:09:53 +00:00
# include <stdexcept>
# include <cstring>
# include <cstdlib>
# include <ostream>
2013-11-20 10:35:58 +00:00
# include <functional>
2014-11-08 11:05:27 +00:00
# include <queue>
2013-07-16 18:09:53 +00:00
namespace ClipperLib {
enum ClipType { ctIntersection , ctUnion , ctDifference , ctXor } ;
enum PolyType { ptSubject , ptClip } ;
//By far the most widely used winding rules for polygon filling are
//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
//see http://glprogramming.com/red/chapter11.html
enum PolyFillType { pftEvenOdd , pftNonZero , pftPositive , pftNegative } ;
2013-11-20 10:35:58 +00:00
# ifdef use_int32
2014-05-23 21:58:43 +00:00
typedef int cInt ;
2014-11-08 11:05:27 +00:00
static cInt const loRange = 0x7FFF ;
static cInt const hiRange = 0x7FFF ;
2013-11-20 10:35:58 +00:00
# else
2014-05-23 21:58:43 +00:00
typedef signed long long cInt ;
static cInt const loRange = 0x3FFFFFFF ;
static cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL ;
2014-11-08 11:05:27 +00:00
typedef signed long long long64 ; //used by Int128 class
typedef unsigned long long ulong64 ;
2013-11-20 10:35:58 +00:00
# endif
2013-07-16 18:09:53 +00:00
struct IntPoint {
2013-11-20 10:35:58 +00:00
cInt X ;
cInt Y ;
# ifdef use_xyz
cInt Z ;
IntPoint ( cInt x = 0 , cInt y = 0 , cInt z = 0 ) : X ( x ) , Y ( y ) , Z ( z ) { } ;
# else
IntPoint ( cInt x = 0 , cInt y = 0 ) : X ( x ) , Y ( y ) { } ;
# endif
friend inline bool operator = = ( const IntPoint & a , const IntPoint & b )
{
return a . X = = b . X & & a . Y = = b . Y ;
}
friend inline bool operator ! = ( const IntPoint & a , const IntPoint & b )
{
return a . X ! = b . X | | a . Y ! = b . Y ;
}
2013-07-16 18:09:53 +00:00
} ;
2013-11-20 10:35:58 +00:00
//------------------------------------------------------------------------------
typedef std : : vector < IntPoint > Path ;
typedef std : : vector < Path > Paths ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
inline Path & operator < < ( Path & poly , const IntPoint & p ) { poly . push_back ( p ) ; return poly ; }
inline Paths & operator < < ( Paths & polys , const Path & p ) { polys . push_back ( p ) ; return polys ; }
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
std : : ostream & operator < < ( std : : ostream & s , const IntPoint & p ) ;
std : : ostream & operator < < ( std : : ostream & s , const Path & p ) ;
std : : ostream & operator < < ( std : : ostream & s , const Paths & p ) ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
struct DoublePoint
{
double X ;
double Y ;
DoublePoint ( double x = 0 , double y = 0 ) : X ( x ) , Y ( y ) { }
DoublePoint ( IntPoint ip ) : X ( ( double ) ip . X ) , Y ( ( double ) ip . Y ) { }
} ;
//------------------------------------------------------------------------------
# ifdef use_xyz
2014-11-08 11:05:27 +00:00
typedef void ( * ZFillCallback ) ( IntPoint & e1bot , IntPoint & e1top , IntPoint & e2bot , IntPoint & e2top , IntPoint & pt ) ;
2013-11-20 10:35:58 +00:00
# endif
2013-07-16 18:09:53 +00:00
2013-12-24 11:40:46 +00:00
enum InitOptions { ioReverseSolution = 1 , ioStrictlySimple = 2 , ioPreserveCollinear = 4 } ;
enum JoinType { jtSquare , jtRound , jtMiter } ;
enum EndType { etClosedPolygon , etClosedLine , etOpenButt , etOpenSquare , etOpenRound } ;
2013-07-16 18:09:53 +00:00
class PolyNode ;
typedef std : : vector < PolyNode * > PolyNodes ;
class PolyNode
{
public :
2017-03-02 16:11:46 +00:00
PolyNode ( ) : Childs ( ) , Parent ( 0 ) , Index ( 0 ) , m_IsOpen ( false ) { }
2014-11-08 11:05:27 +00:00
virtual ~ PolyNode ( ) { } ;
2013-11-20 10:35:58 +00:00
Path Contour ;
2013-07-16 18:09:53 +00:00
PolyNodes Childs ;
PolyNode * Parent ;
2017-03-02 16:11:46 +00:00
// Traversal of the polygon tree in a depth first fashion.
PolyNode * GetNext ( ) const { return Childs . empty ( ) ? GetNextSiblingUp ( ) : Childs . front ( ) ; }
2013-07-16 18:09:53 +00:00
bool IsHole ( ) const ;
2017-03-02 16:11:46 +00:00
bool IsOpen ( ) const { return m_IsOpen ; }
int ChildCount ( ) const { return ( int ) Childs . size ( ) ; }
2013-07-16 18:09:53 +00:00
private :
2013-12-24 11:40:46 +00:00
unsigned Index ; //node index in Parent.Childs
2013-11-20 10:35:58 +00:00
bool m_IsOpen ;
2013-12-24 11:40:46 +00:00
JoinType m_jointype ;
EndType m_endtype ;
2017-03-02 16:11:46 +00:00
PolyNode * GetNextSiblingUp ( ) const { return Parent ? ( ( Index = = Parent - > Childs . size ( ) - 1 ) ? Parent - > GetNextSiblingUp ( ) : Parent - > Childs [ Index + 1 ] ) : nullptr ; }
2013-07-16 18:09:53 +00:00
void AddChild ( PolyNode & child ) ;
friend class Clipper ; //to access Index
2016-12-13 17:59:18 +00:00
friend class ClipperOffset ;
friend class PolyTree ; //to implement the PolyTree::move operator
2013-07-16 18:09:53 +00:00
} ;
class PolyTree : public PolyNode
{
public :
2016-12-13 17:59:18 +00:00
PolyTree ( ) { }
PolyTree ( PolyTree & & src ) { * this = std : : move ( src ) ; }
virtual ~ PolyTree ( ) { Clear ( ) ; } ;
PolyTree & operator = ( PolyTree & & src ) {
AllNodes = std : : move ( src . AllNodes ) ;
Contour = std : : move ( src . Contour ) ;
Childs = std : : move ( src . Childs ) ;
Parent = nullptr ;
Index = src . Index ;
m_IsOpen = src . m_IsOpen ;
m_jointype = src . m_jointype ;
m_endtype = src . m_endtype ;
for ( size_t i = 0 ; i < Childs . size ( ) ; + + i )
Childs [ i ] - > Parent = this ;
return * this ;
}
2017-03-02 16:11:46 +00:00
PolyNode * GetFirst ( ) const { return Childs . empty ( ) ? nullptr : Childs . front ( ) ; }
void Clear ( ) { AllNodes . clear ( ) ; Childs . clear ( ) ; }
2013-07-16 18:09:53 +00:00
int Total ( ) const ;
private :
2016-12-13 17:59:18 +00:00
PolyTree ( const PolyTree & src ) = delete ;
PolyTree & operator = ( const PolyTree & src ) = delete ;
2017-03-02 16:11:46 +00:00
std : : vector < PolyNode > AllNodes ;
2013-07-16 18:09:53 +00:00
friend class Clipper ; //to access AllNodes
} ;
2013-11-20 10:35:58 +00:00
double Area ( const Path & poly ) ;
2017-03-02 16:34:53 +00:00
inline bool Orientation ( const Path & poly ) { return Area ( poly ) > = 0 ; }
2014-03-23 20:40:35 +00:00
int PointInPolygon ( const IntPoint & pt , const Path & path ) ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
void SimplifyPolygon ( const Path & in_poly , Paths & out_polys , PolyFillType fillType = pftEvenOdd ) ;
void SimplifyPolygons ( const Paths & in_polys , Paths & out_polys , PolyFillType fillType = pftEvenOdd ) ;
void SimplifyPolygons ( Paths & polys , PolyFillType fillType = pftEvenOdd ) ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
void CleanPolygon ( const Path & in_poly , Path & out_poly , double distance = 1.415 ) ;
void CleanPolygon ( Path & poly , double distance = 1.415 ) ;
void CleanPolygons ( const Paths & in_polys , Paths & out_polys , double distance = 1.415 ) ;
void CleanPolygons ( Paths & polys , double distance = 1.415 ) ;
2013-07-16 18:09:53 +00:00
2014-03-23 20:40:35 +00:00
void MinkowskiSum ( const Path & pattern , const Path & path , Paths & solution , bool pathIsClosed ) ;
2014-05-23 21:58:43 +00:00
void MinkowskiSum ( const Path & pattern , const Paths & paths , Paths & solution , bool pathIsClosed ) ;
2014-03-23 20:40:35 +00:00
void MinkowskiDiff ( const Path & poly1 , const Path & poly2 , Paths & solution ) ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
void PolyTreeToPaths ( const PolyTree & polytree , Paths & paths ) ;
void ClosedPathsFromPolyTree ( const PolyTree & polytree , Paths & paths ) ;
void OpenPathsFromPolyTree ( PolyTree & polytree , Paths & paths ) ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
void ReversePath ( Path & p ) ;
void ReversePaths ( Paths & p ) ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
struct IntRect { cInt left ; cInt top ; cInt right ; cInt bottom ; } ;
2013-07-16 18:09:53 +00:00
2013-11-20 10:35:58 +00:00
//enums that are used internally ...
enum EdgeSide { esLeft = 1 , esRight = 2 } ;
2013-07-16 18:09:53 +00:00
2017-03-02 16:11:46 +00:00
// namespace Internal {
//forward declarations (for stuff used internally) ...
struct TEdge {
// Bottom point of this edge (with minimum Y).
IntPoint Bot ;
// Current position.
IntPoint Curr ;
// Top point of this edge (with maximum Y).
IntPoint Top ;
// Vector from Bot to Top.
IntPoint Delta ;
// Slope (dx/dy). For horiontal edges, the slope is set to HORIZONTAL (-1.0E+40).
double Dx ;
PolyType PolyTyp ;
EdgeSide Side ;
// Winding number delta. 1 or -1 depending on winding direction, 0 for open paths and flat closed paths.
int WindDelta ;
int WindCnt ;
int WindCnt2 ; //winding count of the opposite polytype
int OutIdx ;
// Next edge in the input path.
TEdge * Next ;
// Previous edge in the input path.
TEdge * Prev ;
// Next edge in the Local Minima List chain.
TEdge * NextInLML ;
TEdge * NextInAEL ;
TEdge * PrevInAEL ;
TEdge * NextInSEL ;
TEdge * PrevInSEL ;
} ;
struct IntersectNode {
IntersectNode ( TEdge * Edge1 , TEdge * Edge2 , IntPoint Pt ) :
Edge1 ( Edge1 ) , Edge2 ( Edge2 ) , Pt ( Pt ) { }
TEdge * Edge1 ;
TEdge * Edge2 ;
IntPoint Pt ;
} ;
struct LocalMinimum {
cInt Y ;
TEdge * LeftBound ;
TEdge * RightBound ;
} ;
struct OutPt ;
struct OutRec ;
struct Join {
Join ( OutPt * OutPt1 , OutPt * OutPt2 , IntPoint OffPt ) :
OutPt1 ( OutPt1 ) , OutPt2 ( OutPt2 ) , OffPt ( OffPt ) { }
OutPt * OutPt1 ;
OutPt * OutPt2 ;
IntPoint OffPt ;
} ;
// }; // namespace Internal
2013-12-24 11:40:46 +00:00
2013-11-20 10:35:58 +00:00
//------------------------------------------------------------------------------
2013-07-16 18:09:53 +00:00
//ClipperBase is the ancestor to the Clipper class. It should not be
//instantiated directly. This class simply abstracts the conversion of sets of
//polygon coordinates into edge objects that are stored in a LocalMinima list.
class ClipperBase
{
public :
2017-03-02 16:11:46 +00:00
ClipperBase ( ) : m_UseFullRange ( false ) , m_HasOpenPaths ( false ) { }
virtual ~ ClipperBase ( ) { Clear ( ) ; }
2013-11-20 10:35:58 +00:00
bool AddPath ( const Path & pg , PolyType PolyTyp , bool Closed ) ;
bool AddPaths ( const Paths & ppg , PolyType PolyTyp , bool Closed ) ;
2013-07-16 18:09:53 +00:00
virtual void Clear ( ) ;
IntRect GetBounds ( ) ;
2017-03-01 13:27:08 +00:00
// By default, when three or more vertices are collinear in input polygons (subject or clip), the Clipper object removes the 'inner' vertices before clipping.
// When enabled the PreserveCollinear property prevents this default behavior to allow these inner vertices to appear in the solution.
2015-07-27 23:26:01 +00:00
bool PreserveCollinear ( ) const { return m_PreserveCollinear ; } ;
2013-11-20 10:35:58 +00:00
void PreserveCollinear ( bool value ) { m_PreserveCollinear = value ; } ;
2013-07-16 18:09:53 +00:00
protected :
2017-03-03 20:40:40 +00:00
bool AddPathInternal ( const Path & pg , int highI , PolyType PolyTyp , bool Closed , TEdge * edges ) ;
2013-11-20 10:35:58 +00:00
TEdge * AddBoundsToLML ( TEdge * e , bool IsClosed ) ;
2013-07-16 18:09:53 +00:00
virtual void Reset ( ) ;
2013-12-24 11:40:46 +00:00
TEdge * ProcessBound ( TEdge * E , bool IsClockwise ) ;
2013-11-20 10:35:58 +00:00
TEdge * DescendToMin ( TEdge * & E ) ;
void AscendToMax ( TEdge * & E , bool Appending , bool IsClosed ) ;
2014-11-08 11:05:27 +00:00
2017-03-01 13:27:08 +00:00
// Local minima (Y, left edge, right edge) sorted by ascending Y.
std : : vector < LocalMinimum > m_MinimaList ;
2014-11-08 11:05:27 +00:00
2017-03-01 13:27:08 +00:00
// True if the input polygons have abs values higher than loRange, but lower than hiRange.
// False if the input polygons have abs values lower or equal to loRange.
2013-07-16 18:09:53 +00:00
bool m_UseFullRange ;
2017-03-01 13:27:08 +00:00
// A vector of edges per each input path.
2017-03-02 16:11:46 +00:00
std : : vector < std : : vector < TEdge > > m_edges ;
2017-03-01 13:27:08 +00:00
// Don't remove intermediate vertices of a collinear sequence of points.
2013-11-20 10:35:58 +00:00
bool m_PreserveCollinear ;
2017-03-01 13:27:08 +00:00
// Is any of the paths inserted by AddPath() or AddPaths() open?
2013-11-20 10:35:58 +00:00
bool m_HasOpenPaths ;
2013-07-16 18:09:53 +00:00
} ;
2013-11-20 10:35:58 +00:00
//------------------------------------------------------------------------------
2013-07-16 18:09:53 +00:00
class Clipper : public virtual ClipperBase
{
public :
2013-11-20 10:35:58 +00:00
Clipper ( int initOptions = 0 ) ;
2017-03-02 16:11:46 +00:00
~ Clipper ( ) { Clear ( ) ; }
2013-07-16 18:09:53 +00:00
bool Execute ( ClipType clipType ,
2015-02-15 15:10:04 +00:00
Paths & solution ,
2017-03-02 16:11:46 +00:00
PolyFillType fillType = pftEvenOdd )
{ return Execute ( clipType , solution , fillType , fillType ) ; }
2013-07-16 18:09:53 +00:00
bool Execute ( ClipType clipType ,
2015-02-15 15:10:04 +00:00
Paths & solution ,
PolyFillType subjFillType ,
PolyFillType clipFillType ) ;
bool Execute ( ClipType clipType ,
PolyTree & polytree ,
2017-03-02 16:11:46 +00:00
PolyFillType fillType = pftEvenOdd )
{ return Execute ( clipType , polytree , fillType , fillType ) ; }
2015-02-15 15:10:04 +00:00
bool Execute ( ClipType clipType ,
PolyTree & polytree ,
PolyFillType subjFillType ,
PolyFillType clipFillType ) ;
2015-07-27 23:26:01 +00:00
bool ReverseSolution ( ) const { return m_ReverseOutput ; } ;
2013-07-16 18:09:53 +00:00
void ReverseSolution ( bool value ) { m_ReverseOutput = value ; } ;
2015-07-27 23:26:01 +00:00
bool StrictlySimple ( ) const { return m_StrictSimple ; } ;
2013-11-20 10:35:58 +00:00
void StrictlySimple ( bool value ) { m_StrictSimple = value ; } ;
//set the callback function for z value filling on intersections (otherwise Z is 0)
# ifdef use_xyz
2017-03-02 16:11:46 +00:00
void ZFillFunction ( ZFillCallback zFillFunc ) { m_ZFill = zFillFunc ; }
2013-11-20 10:35:58 +00:00
# endif
2013-07-16 18:09:53 +00:00
protected :
void Reset ( ) ;
virtual bool ExecuteInternal ( ) ;
private :
2017-03-02 16:11:46 +00:00
std : : vector < OutRec * > m_PolyOuts ;
std : : vector < Join > m_Joins ;
std : : vector < Join > m_GhostJoins ;
std : : vector < IntersectNode > m_IntersectList ;
2015-02-15 15:10:04 +00:00
ClipType m_ClipType ;
2017-03-01 13:27:08 +00:00
// A priority queue (a binary heap) of Y coordinates.
std : : priority_queue < cInt > m_Scanbeam ;
2017-03-02 16:11:46 +00:00
// Maxima are collected by ProcessEdgesAtTopOfScanbeam(), consumed by ProcessHorizontal().
std : : vector < cInt > m_Maxima ;
2013-07-16 18:09:53 +00:00
TEdge * m_ActiveEdges ;
TEdge * m_SortedEdges ;
PolyFillType m_ClipFillType ;
PolyFillType m_SubjFillType ;
bool m_ReverseOutput ;
2017-03-01 13:27:08 +00:00
// Does the result go to a PolyTree or Paths?
2013-07-16 18:09:53 +00:00
bool m_UsingPolyTree ;
2013-11-20 10:35:58 +00:00
bool m_StrictSimple ;
# ifdef use_xyz
2014-11-08 11:05:27 +00:00
ZFillCallback m_ZFill ; //custom callback
2013-11-20 10:35:58 +00:00
# endif
2015-07-27 23:26:01 +00:00
void SetWindingCount ( TEdge & edge ) const ;
2017-03-02 16:11:46 +00:00
bool IsEvenOddFillType ( const TEdge & edge ) const
{ return ( edge . PolyTyp = = ptSubject ) ? m_SubjFillType = = pftEvenOdd : m_ClipFillType = = pftEvenOdd ; }
bool IsEvenOddAltFillType ( const TEdge & edge ) const
{ return ( edge . PolyTyp = = ptSubject ) ? m_ClipFillType = = pftEvenOdd : m_SubjFillType = = pftEvenOdd ; }
2013-11-20 10:35:58 +00:00
void InsertLocalMinimaIntoAEL ( const cInt botY ) ;
void InsertEdgeIntoAEL ( TEdge * edge , TEdge * startEdge ) ;
2013-07-16 18:09:53 +00:00
void AddEdgeToSEL ( TEdge * edge ) ;
void CopyAELToSEL ( ) ;
void DeleteFromSEL ( TEdge * e ) ;
void DeleteFromAEL ( TEdge * e ) ;
void UpdateEdgeIntoAEL ( TEdge * & e ) ;
void SwapPositionsInSEL ( TEdge * edge1 , TEdge * edge2 ) ;
bool IsContributing ( const TEdge & edge ) const ;
2013-11-20 10:35:58 +00:00
bool IsTopHorz ( const cInt XPos ) ;
2013-07-16 18:09:53 +00:00
void SwapPositionsInAEL ( TEdge * edge1 , TEdge * edge2 ) ;
2013-11-20 10:35:58 +00:00
void DoMaxima ( TEdge * e ) ;
2015-02-15 15:10:04 +00:00
void ProcessHorizontals ( ) ;
void ProcessHorizontal ( TEdge * horzEdge ) ;
2013-07-16 18:09:53 +00:00
void AddLocalMaxPoly ( TEdge * e1 , TEdge * e2 , const IntPoint & pt ) ;
2013-11-20 10:35:58 +00:00
OutPt * AddLocalMinPoly ( TEdge * e1 , TEdge * e2 , const IntPoint & pt ) ;
2013-07-16 18:09:53 +00:00
OutRec * GetOutRec ( int idx ) ;
2015-07-27 23:26:01 +00:00
void AppendPolygon ( TEdge * e1 , TEdge * e2 ) const ;
2014-05-23 21:58:43 +00:00
void IntersectEdges ( TEdge * e1 , TEdge * e2 , IntPoint & pt ) ;
2013-07-16 18:09:53 +00:00
OutRec * CreateOutRec ( ) ;
2013-11-20 10:35:58 +00:00
OutPt * AddOutPt ( TEdge * e , const IntPoint & pt ) ;
2015-02-15 15:10:04 +00:00
OutPt * GetLastOutPt ( TEdge * e ) ;
2013-11-20 10:35:58 +00:00
void DisposeAllOutRecs ( ) ;
2014-11-08 11:05:27 +00:00
bool ProcessIntersections ( const cInt topY ) ;
void BuildIntersectList ( const cInt topY ) ;
2013-11-20 10:35:58 +00:00
void ProcessEdgesAtTopOfScanbeam ( const cInt topY ) ;
void BuildResult ( Paths & polys ) ;
2013-07-16 18:09:53 +00:00
void BuildResult2 ( PolyTree & polytree ) ;
2015-07-27 23:26:01 +00:00
void SetHoleState ( TEdge * e , OutRec * outrec ) const ;
2013-07-16 18:09:53 +00:00
bool FixupIntersectionOrder ( ) ;
void FixupOutPolygon ( OutRec & outrec ) ;
2015-02-15 15:10:04 +00:00
void FixupOutPolyline ( OutRec & outrec ) ;
2013-12-24 11:40:46 +00:00
bool FindOwnerFromSplitRecs ( OutRec & outRec , OutRec * & currOrfl ) ;
2013-07-16 18:09:53 +00:00
void FixHoleLinkage ( OutRec & outrec ) ;
2013-12-24 11:40:46 +00:00
bool JoinPoints ( Join * j , OutRec * outRec1 , OutRec * outRec2 ) ;
2013-07-16 18:09:53 +00:00
void JoinCommonEdges ( ) ;
void DoSimplePolygons ( ) ;
2015-07-27 23:26:01 +00:00
void FixupFirstLefts1 ( OutRec * OldOutRec , OutRec * NewOutRec ) const ;
void FixupFirstLefts2 ( OutRec * OldOutRec , OutRec * NewOutRec ) const ;
2013-11-20 10:35:58 +00:00
# ifdef use_xyz
2014-05-23 21:58:43 +00:00
void SetZ ( IntPoint & pt , TEdge & e1 , TEdge & e2 ) ;
2013-11-20 10:35:58 +00:00
# endif
2013-07-16 18:09:53 +00:00
} ;
//------------------------------------------------------------------------------
2013-12-24 11:40:46 +00:00
class ClipperOffset
{
public :
ClipperOffset ( double miterLimit = 2.0 , double roundPrecision = 0.25 ) ;
2017-03-02 16:11:46 +00:00
~ ClipperOffset ( ) { Clear ( ) ; }
2013-12-24 11:40:46 +00:00
void AddPath ( const Path & path , JoinType joinType , EndType endType ) ;
void AddPaths ( const Paths & paths , JoinType joinType , EndType endType ) ;
void Execute ( Paths & solution , double delta ) ;
void Execute ( PolyTree & solution , double delta ) ;
void Clear ( ) ;
double MiterLimit ;
double ArcTolerance ;
private :
Paths m_destPolys ;
Path m_srcPoly ;
Path m_destPoly ;
std : : vector < DoublePoint > m_normals ;
double m_delta , m_sinA , m_sin , m_cos ;
double m_miterLim , m_StepsPerRad ;
IntPoint m_lowest ;
PolyNode m_polyNodes ;
void FixOrientations ( ) ;
void DoOffset ( double delta ) ;
void OffsetPoint ( int j , int & k , JoinType jointype ) ;
void DoSquare ( int j , int k ) ;
void DoMiter ( int j , int k , double r ) ;
void DoRound ( int j , int k ) ;
} ;
//------------------------------------------------------------------------------
2013-07-16 18:09:53 +00:00
class clipperException : public std : : exception
{
public :
clipperException ( const char * description ) : m_descr ( description ) { }
virtual ~ clipperException ( ) throw ( ) { }
virtual const char * what ( ) const throw ( ) { return m_descr . c_str ( ) ; }
private :
std : : string m_descr ;
} ;
//------------------------------------------------------------------------------
} //ClipperLib namespace
# endif //clipper_hpp