mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Clipper library:
Added some comments, some methods were made inline, tiny methods moved to the header as inline, dynamic allocation replaced with std:: containers, changed some loops to the condensed C++11 syntax.
This commit is contained in:
		
							parent
							
								
									4287362aa6
								
							
						
					
					
						commit
						90a415ae10
					
				
					 2 changed files with 290 additions and 466 deletions
				
			
		
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -50,8 +50,7 @@ | |||
| //#define use_deprecated  
 | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <list> | ||||
| #include <set> | ||||
| #include <deque> | ||||
| #include <stdexcept> | ||||
| #include <cstring> | ||||
| #include <cstdlib> | ||||
|  | @ -136,21 +135,22 @@ typedef std::vector< PolyNode* > PolyNodes; | |||
| class PolyNode  | ||||
| {  | ||||
| public: | ||||
|     PolyNode(); | ||||
|     PolyNode() : Childs(), Parent(0), Index(0), m_IsOpen(false) {} | ||||
|     virtual ~PolyNode(){}; | ||||
|     Path Contour; | ||||
|     PolyNodes Childs; | ||||
|     PolyNode* Parent; | ||||
|     PolyNode* GetNext() const; | ||||
|     // Traversal of the polygon tree in a depth first fashion.
 | ||||
|     PolyNode* GetNext() const { return Childs.empty() ? GetNextSiblingUp() : Childs.front(); } | ||||
|     bool IsHole() const; | ||||
|     bool IsOpen() const; | ||||
|     int ChildCount() const; | ||||
|     bool IsOpen() const { return m_IsOpen; }   | ||||
|     int  ChildCount() const { return (int)Childs.size(); } | ||||
| private: | ||||
|     unsigned Index; //node index in Parent.Childs
 | ||||
|     bool m_IsOpen; | ||||
|     JoinType m_jointype; | ||||
|     EndType m_endtype; | ||||
|     PolyNode* GetNextSiblingUp() const; | ||||
|     PolyNode* GetNextSiblingUp() const { return Parent ? ((Index == Parent->Childs.size() - 1) ? Parent->GetNextSiblingUp() : Parent->Childs[Index + 1]) : nullptr; } | ||||
|     void AddChild(PolyNode& child); | ||||
|     friend class Clipper; //to access Index
 | ||||
|     friend class ClipperOffset; | ||||
|  | @ -176,13 +176,13 @@ public: | |||
|           Childs[i]->Parent = this; | ||||
|         return *this;  | ||||
|     } | ||||
|     PolyNode* GetFirst() const; | ||||
|     void Clear(); | ||||
|     PolyNode* GetFirst() const { return Childs.empty() ? nullptr : Childs.front(); } | ||||
|     void Clear() {  AllNodes.clear(); Childs.clear(); } | ||||
|     int Total() const; | ||||
| private: | ||||
|     PolyTree(const PolyTree &src) = delete; | ||||
|     PolyTree& operator=(const PolyTree &src) = delete; | ||||
|     PolyNodes AllNodes; | ||||
|     std::vector<PolyNode> AllNodes; | ||||
|     friend class Clipper; //to access AllNodes
 | ||||
| }; | ||||
| 
 | ||||
|  | @ -215,24 +215,62 @@ struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }; | |||
| //enums that are used internally ...
 | ||||
| enum EdgeSide { esLeft = 1, esRight = 2}; | ||||
| 
 | ||||
| //forward declarations (for stuff used internally) ...
 | ||||
| struct TEdge; | ||||
| struct IntersectNode; | ||||
| struct LocalMinimum; | ||||
| 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 {
 | ||||
|   //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; | ||||
|   }; | ||||
| 
 | ||||
| typedef std::vector < OutRec* > PolyOutList; | ||||
| typedef std::vector < TEdge* > EdgeList; | ||||
| typedef std::vector < Join > JoinList; | ||||
| typedef std::vector < IntersectNode* > IntersectList; | ||||
|   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
 | ||||
| 
 | ||||
| //------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|  | @ -242,8 +280,8 @@ typedef std::vector < IntersectNode* > IntersectList; | |||
| class ClipperBase | ||||
| { | ||||
| public: | ||||
|   ClipperBase(); | ||||
|   virtual ~ClipperBase(); | ||||
|   ClipperBase() : m_UseFullRange(false), m_HasOpenPaths(false) {} | ||||
|   virtual ~ClipperBase() { Clear(); } | ||||
|   bool AddPath(const Path &pg, PolyType PolyTyp, bool Closed); | ||||
|   bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); | ||||
|   virtual void Clear(); | ||||
|  | @ -254,7 +292,6 @@ public: | |||
|   void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; | ||||
| protected: | ||||
|   TEdge* AddBoundsToLML(TEdge *e, bool IsClosed); | ||||
|   void PopLocalMinima(); | ||||
|   virtual void Reset(); | ||||
|   TEdge* ProcessBound(TEdge* E, bool IsClockwise); | ||||
|   TEdge* DescendToMin(TEdge *&E); | ||||
|  | @ -267,7 +304,7 @@ protected: | |||
|   // False if the input polygons have abs values lower or equal to loRange.
 | ||||
|   bool              m_UseFullRange; | ||||
|   // A vector of edges per each input path.
 | ||||
|   EdgeList          m_edges; | ||||
|   std::vector<std::vector<TEdge>> m_edges; | ||||
|   // Don't remove intermediate vertices of a collinear sequence of points.
 | ||||
|   bool             m_PreserveCollinear; | ||||
|   // Is any of the paths inserted by AddPath() or AddPaths() open?
 | ||||
|  | @ -279,17 +316,19 @@ class Clipper : public virtual ClipperBase | |||
| { | ||||
| public: | ||||
|   Clipper(int initOptions = 0); | ||||
|   ~Clipper(); | ||||
|   ~Clipper() { Clear(); } | ||||
|   bool Execute(ClipType clipType, | ||||
|       Paths &solution, | ||||
|       PolyFillType fillType = pftEvenOdd); | ||||
|       PolyFillType fillType = pftEvenOdd)  | ||||
|     { return Execute(clipType, solution, fillType, fillType); } | ||||
|   bool Execute(ClipType clipType, | ||||
|       Paths &solution, | ||||
|       PolyFillType subjFillType, | ||||
|       PolyFillType clipFillType); | ||||
|   bool Execute(ClipType clipType, | ||||
|       PolyTree &polytree, | ||||
|       PolyFillType fillType = pftEvenOdd); | ||||
|       PolyFillType fillType = pftEvenOdd) | ||||
|     { return Execute(clipType, polytree, fillType, fillType); } | ||||
|   bool Execute(ClipType clipType, | ||||
|       PolyTree &polytree, | ||||
|       PolyFillType subjFillType, | ||||
|  | @ -300,21 +339,21 @@ public: | |||
|   void StrictlySimple(bool value) {m_StrictSimple = value;}; | ||||
|   //set the callback function for z value filling on intersections (otherwise Z is 0)
 | ||||
| #ifdef use_xyz | ||||
|   void ZFillFunction(ZFillCallback zFillFunc); | ||||
|   void ZFillFunction(ZFillCallback zFillFunc) { m_ZFill = zFillFunc; } | ||||
| #endif | ||||
| protected: | ||||
|   void Reset(); | ||||
|   virtual bool ExecuteInternal(); | ||||
| private: | ||||
|   PolyOutList      m_PolyOuts; | ||||
|   JoinList         m_Joins; | ||||
|   JoinList         m_GhostJoins; | ||||
|   IntersectList    m_IntersectList; | ||||
|   std::vector<OutRec*> m_PolyOuts; | ||||
|   std::vector<Join> m_Joins; | ||||
|   std::vector<Join> m_GhostJoins; | ||||
|   std::vector<IntersectNode> m_IntersectList; | ||||
|   ClipType         m_ClipType; | ||||
|   // A priority queue (a binary heap) of Y coordinates.
 | ||||
|   std::priority_queue<cInt> m_Scanbeam; | ||||
|   typedef std::list<cInt> MaximaList; | ||||
|   MaximaList       m_Maxima; | ||||
|   // Maxima are collected by ProcessEdgesAtTopOfScanbeam(), consumed by ProcessHorizontal().
 | ||||
|   std::vector<cInt> m_Maxima; | ||||
|   TEdge           *m_ActiveEdges; | ||||
|   TEdge           *m_SortedEdges; | ||||
|   PolyFillType     m_ClipFillType; | ||||
|  | @ -327,9 +366,10 @@ private: | |||
|   ZFillCallback   m_ZFill; //custom callback 
 | ||||
| #endif | ||||
|   void SetWindingCount(TEdge& edge) const; | ||||
|   bool IsEvenOddFillType(const TEdge& edge) const; | ||||
|   bool IsEvenOddAltFillType(const TEdge& edge) const; | ||||
|   cInt PopScanbeam(); | ||||
|   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; } | ||||
|   void InsertLocalMinimaIntoAEL(const cInt botY); | ||||
|   void InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge); | ||||
|   void AddEdgeToSEL(TEdge *edge); | ||||
|  | @ -353,15 +393,12 @@ private: | |||
|   OutPt* AddOutPt(TEdge *e, const IntPoint &pt); | ||||
|   OutPt* GetLastOutPt(TEdge *e); | ||||
|   void DisposeAllOutRecs(); | ||||
|   void DisposeOutRec(PolyOutList::size_type index); | ||||
|   bool ProcessIntersections(const cInt topY); | ||||
|   void BuildIntersectList(const cInt topY); | ||||
|   void ProcessIntersectList(); | ||||
|   void ProcessEdgesAtTopOfScanbeam(const cInt topY); | ||||
|   void BuildResult(Paths& polys); | ||||
|   void BuildResult2(PolyTree& polytree); | ||||
|   void SetHoleState(TEdge *e, OutRec *outrec) const; | ||||
|   void DisposeIntersectNodes(); | ||||
|   bool FixupIntersectionOrder(); | ||||
|   void FixupOutPolygon(OutRec &outrec); | ||||
|   void FixupOutPolyline(OutRec &outrec); | ||||
|  | @ -382,7 +419,7 @@ class ClipperOffset | |||
| { | ||||
| public: | ||||
|   ClipperOffset(double miterLimit = 2.0, double roundPrecision = 0.25); | ||||
|   ~ClipperOffset(); | ||||
|   ~ClipperOffset() { Clear(); } | ||||
|   void AddPath(const Path& path, JoinType joinType, EndType endType); | ||||
|   void AddPaths(const Paths& paths, JoinType joinType, EndType endType); | ||||
|   void Execute(Paths& solution, double delta); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv