mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 20:51:23 -07:00 
			
		
		
		
	Fix building with GCC13 (required to build on Arch and Fedora) (#1220)
* Backport TBB fix to allow building on GCC13 * Fix OpenEXR build with GCC13 * Fix Clipper2 build with GCC13 --------- Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
		
							parent
							
								
									6108d8ee40
								
							
						
					
					
						commit
						e065809e3a
					
				
					 6 changed files with 140 additions and 91 deletions
				
			
		
							
								
								
									
										31
									
								
								deps/OpenEXR/0001-OpenEXR-GCC13.patch
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								deps/OpenEXR/0001-OpenEXR-GCC13.patch
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
--- a/OpenEXR/IlmImf/ImfDwaCompressor.cpp
 | 
			
		||||
+++ b/OpenEXR/IlmImf/ImfDwaCompressor.cpp
 | 
			
		||||
@@ -159,6 +159,7 @@
 | 
			
		||||
 #include <limits>
 | 
			
		||||
 | 
			
		||||
 #include <cstddef>
 | 
			
		||||
+#include <cstdint>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 // Windows specific addition to prevent the indirect import of the redefined min/max macros
 | 
			
		||||
--- a/OpenEXR/IlmImf/ImfHuf.h
 | 
			
		||||
+++ b/OpenEXR/IlmImf/ImfHuf.h
 | 
			
		||||
@@ -40,6 +40,8 @@
 | 
			
		||||
 #include "ImfExport.h"
 | 
			
		||||
 #include "ImfNamespace.h"
 | 
			
		||||
 | 
			
		||||
+#include <cstdint>
 | 
			
		||||
+
 | 
			
		||||
 //-----------------------------------------------------------------------------
 | 
			
		||||
 //
 | 
			
		||||
 //	16-bit Huffman compression and decompression:
 | 
			
		||||
--- a/OpenEXR/IlmImf/ImfMisc.h
 | 
			
		||||
+++ b/OpenEXR/IlmImf/ImfMisc.h
 | 
			
		||||
@@ -51,6 +51,7 @@
 | 
			
		||||
 #include "ImfForward.h"
 | 
			
		||||
 | 
			
		||||
 #include <cstddef>
 | 
			
		||||
+#include <cstdint>
 | 
			
		||||
 #include <vector>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								deps/OpenEXR/OpenEXR.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								deps/OpenEXR/OpenEXR.cmake
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -33,12 +33,13 @@ bambustudio_add_cmake_project(OpenEXR
 | 
			
		|||
    # GIT_REPOSITORY https://github.com/openexr/openexr.git
 | 
			
		||||
    URL https://github.com/AcademySoftwareFoundation/openexr/archive/refs/tags/v2.5.5.zip
 | 
			
		||||
    URL_HASH SHA256=0307a3d7e1fa1e77e9d84d7e9a8694583fbbbfd50bdc6884e2c96b8ef6b902de
 | 
			
		||||
    PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-OpenEXR-GCC13.patch
 | 
			
		||||
    DEPENDS ${ZLIB_PKG}
 | 
			
		||||
    GIT_TAG v2.5.5
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
        -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
        -DBUILD_TESTING=OFF 
 | 
			
		||||
        -DPYILMBASE_ENABLE:BOOL=OFF 
 | 
			
		||||
        -DBUILD_TESTING=OFF
 | 
			
		||||
        -DPYILMBASE_ENABLE:BOOL=OFF
 | 
			
		||||
        -DOPENEXR_VIEWERS_ENABLE:BOOL=OFF
 | 
			
		||||
        -DOPENEXR_BUILD_UTILS:BOOL=OFF
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								deps/TBB/0001-TBB-GCC13.patch
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								deps/TBB/0001-TBB-GCC13.patch
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
--- a/include/tbb/task.h
 | 
			
		||||
+++ b/include/tbb/task.h
 | 
			
		||||
@@ -219,7 +219,7 @@
 | 
			
		||||
 #if __TBB_TASK_PRIORITY
 | 
			
		||||
         //! Pointer to the next offloaded lower priority task.
 | 
			
		||||
         /** Used to maintain a list of offloaded tasks inside the scheduler. **/
 | 
			
		||||
-        task* next_offloaded;
 | 
			
		||||
+        tbb::task* next_offloaded;
 | 
			
		||||
         };
 | 
			
		||||
 #endif /* __TBB_TASK_PRIORITY */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								deps/TBB/TBB.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								deps/TBB/TBB.cmake
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -2,7 +2,8 @@ bambustudio_add_cmake_project(
 | 
			
		|||
    TBB
 | 
			
		||||
    URL "https://github.com/wjakob/tbb/archive/a0dc9bf76d0120f917b641ed095360448cabc85b.tar.gz"
 | 
			
		||||
    URL_HASH SHA256=0545cb6033bd1873fcae3ea304def720a380a88292726943ae3b9b207f322efe
 | 
			
		||||
    CMAKE_ARGS          
 | 
			
		||||
    PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-TBB-GCC13.patch
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
        -DTBB_BUILD_SHARED=OFF
 | 
			
		||||
        -DTBB_BUILD_TESTS=OFF
 | 
			
		||||
        -DTBB_BUILD_TESTS=OFF
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,8 @@ constexpr auto CLIPPER2_VERSION = "1.0.6";
 | 
			
		|||
#include <stdexcept>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include "clipper.core.h"
 | 
			
		||||
 | 
			
		||||
namespace Clipper2Lib {
 | 
			
		||||
| 
						 | 
				
			
			@ -31,19 +33,19 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
	//Note: all clipping operations except for Difference are commutative.
 | 
			
		||||
	enum class ClipType { None, Intersection, Union, Difference, Xor };
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	enum class PathType { Subject, Clip };
 | 
			
		||||
 | 
			
		||||
	enum class VertexFlags : uint32_t {
 | 
			
		||||
		None = 0, OpenStart = 1, OpenEnd = 2, LocalMax = 4, LocalMin = 8
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	constexpr enum VertexFlags operator &(enum VertexFlags a, enum VertexFlags b) 
 | 
			
		||||
	constexpr enum VertexFlags operator &(enum VertexFlags a, enum VertexFlags b)
 | 
			
		||||
	{
 | 
			
		||||
		return (enum VertexFlags)(uint32_t(a) & uint32_t(b));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	constexpr enum VertexFlags operator |(enum VertexFlags a, enum VertexFlags b) 
 | 
			
		||||
	constexpr enum VertexFlags operator |(enum VertexFlags a, enum VertexFlags b)
 | 
			
		||||
	{
 | 
			
		||||
		return (enum VertexFlags)(uint32_t(a) | uint32_t(b));
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +99,7 @@ namespace Clipper2Lib {
 | 
			
		|||
	//Important: UP and DOWN here are premised on Y-axis positive down
 | 
			
		||||
	//displays, which is the orientation used in Clipper's development.
 | 
			
		||||
	///////////////////////////////////////////////////////////////////
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	struct Active {
 | 
			
		||||
		Point64 bot;
 | 
			
		||||
		Point64 top;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +170,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		std::vector<LocalMinima*>::iterator current_locmin_iter_;
 | 
			
		||||
		std::vector<Vertex*> vertex_lists_;
 | 
			
		||||
		std::priority_queue<int64_t> scanline_list_;
 | 
			
		||||
		std::vector<IntersectNode> intersect_nodes_; 
 | 
			
		||||
		std::vector<IntersectNode> intersect_nodes_;
 | 
			
		||||
		std::vector<Joiner*> joiner_list_;				//pointers in case of memory reallocs
 | 
			
		||||
		void Reset();
 | 
			
		||||
		void InsertScanline(int64_t y);
 | 
			
		||||
| 
						 | 
				
			
			@ -197,7 +199,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		void ProcessIntersectList();
 | 
			
		||||
		void SwapPositionsInAEL(Active& edge1, Active& edge2);
 | 
			
		||||
		OutPt* AddOutPt(const Active &e, const Point64& pt);
 | 
			
		||||
		OutPt* AddLocalMinPoly(Active &e1, Active &e2, 
 | 
			
		||||
		OutPt* AddLocalMinPoly(Active &e1, Active &e2,
 | 
			
		||||
			const Point64& pt, bool is_new = false);
 | 
			
		||||
		OutPt* AddLocalMaxPoly(Active &e1, Active &e2, const Point64& pt);
 | 
			
		||||
		void DoHorizontal(Active &horz);
 | 
			
		||||
| 
						 | 
				
			
			@ -254,7 +256,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		PolyPath* parent_;
 | 
			
		||||
	public:
 | 
			
		||||
		PolyPath(PolyPath* parent = nullptr): parent_(parent){}
 | 
			
		||||
		virtual ~PolyPath() { Clear(); };		
 | 
			
		||||
		virtual ~PolyPath() { Clear(); };
 | 
			
		||||
		//https://en.cppreference.com/w/cpp/language/rule_of_three
 | 
			
		||||
		PolyPath(const PolyPath&) = delete;
 | 
			
		||||
		PolyPath& operator=(const PolyPath&) = delete;
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +276,7 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
		const PolyPath* Parent() const { return parent_; }
 | 
			
		||||
 | 
			
		||||
		bool IsHole() const 
 | 
			
		||||
		bool IsHole() const
 | 
			
		||||
		{
 | 
			
		||||
			const PolyPath* pp = parent_;
 | 
			
		||||
			bool is_hole = pp;
 | 
			
		||||
| 
						 | 
				
			
			@ -364,13 +366,13 @@ namespace Clipper2Lib {
 | 
			
		|||
		PathD polygon_;
 | 
			
		||||
		typedef typename std::vector<PolyPathD*>::const_iterator ppD_itor;
 | 
			
		||||
	public:
 | 
			
		||||
		PolyPathD(PolyPathD* parent = nullptr) : PolyPath(parent) 
 | 
			
		||||
		PolyPathD(PolyPathD* parent = nullptr) : PolyPath(parent)
 | 
			
		||||
		{
 | 
			
		||||
			inv_scale_ = parent ? parent->inv_scale_ : 1.0;
 | 
			
		||||
		}
 | 
			
		||||
		PolyPathD* operator [] (size_t index) 
 | 
			
		||||
		{ 
 | 
			
		||||
			return static_cast<PolyPathD*>(childs_[index]); 
 | 
			
		||||
		PolyPathD* operator [] (size_t index)
 | 
			
		||||
		{
 | 
			
		||||
			return static_cast<PolyPathD*>(childs_[index]);
 | 
			
		||||
		}
 | 
			
		||||
		ppD_itor begin() const { return childs_.cbegin(); }
 | 
			
		||||
		ppD_itor end() const { return childs_.cend(); }
 | 
			
		||||
| 
						 | 
				
			
			@ -437,7 +439,7 @@ namespace Clipper2Lib {
 | 
			
		|||
			return Execute(clip_type, fill_rule, closed_paths, dummy);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool Execute(ClipType clip_type, FillRule fill_rule, 
 | 
			
		||||
		bool Execute(ClipType clip_type, FillRule fill_rule,
 | 
			
		||||
			Paths64& closed_paths, Paths64& open_paths)
 | 
			
		||||
		{
 | 
			
		||||
			closed_paths.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -509,12 +511,12 @@ namespace Clipper2Lib {
 | 
			
		|||
		void CheckCallback()
 | 
			
		||||
		{
 | 
			
		||||
			if(zCallback_)
 | 
			
		||||
				// if the user defined float point callback has been assigned 
 | 
			
		||||
				// if the user defined float point callback has been assigned
 | 
			
		||||
				// then assign the proxy callback function
 | 
			
		||||
				ClipperBase::zCallback_ = 
 | 
			
		||||
				ClipperBase::zCallback_ =
 | 
			
		||||
					std::bind(&ClipperD::ZCB, this, std::placeholders::_1,
 | 
			
		||||
					std::placeholders::_2, std::placeholders::_3,
 | 
			
		||||
					std::placeholders::_4, std::placeholders::_5); 
 | 
			
		||||
					std::placeholders::_4, std::placeholders::_5);
 | 
			
		||||
			else
 | 
			
		||||
				ClipperBase::zCallback_ = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -581,6 +583,6 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
}  // namespace 
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
#endif  // CLIPPER_ENGINE_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,9 @@
 | 
			
		|||
#include <algorithm>
 | 
			
		||||
#include "clipper2/clipper.engine.h"
 | 
			
		||||
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace Clipper2Lib {
 | 
			
		||||
 | 
			
		||||
	static const double FloatingPointTolerance = 1.0e-12;
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +97,7 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
	inline bool IsOpenEnd(const Vertex& v)
 | 
			
		||||
	{
 | 
			
		||||
		return (v.flags & (VertexFlags::OpenStart | VertexFlags::OpenEnd)) != 
 | 
			
		||||
		return (v.flags & (VertexFlags::OpenStart | VertexFlags::OpenEnd)) !=
 | 
			
		||||
			VertexFlags::None;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -189,8 +192,8 @@ namespace Clipper2Lib {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	inline Point64 GetEndE1ClosestToEndE2(
 | 
			
		||||
		const Active& e1, const Active& e2) 
 | 
			
		||||
	{		
 | 
			
		||||
		const Active& e1, const Active& e2)
 | 
			
		||||
	{
 | 
			
		||||
		double d[] = {
 | 
			
		||||
			DistanceSqr(e1.bot, e2.bot),
 | 
			
		||||
			DistanceSqr(e1.top, e2.top),
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +207,7 @@ namespace Clipper2Lib {
 | 
			
		|||
			if (d[i] < d[idx]) idx = i;
 | 
			
		||||
			if (d[i] == 0) break;
 | 
			
		||||
		}
 | 
			
		||||
		switch (idx) 
 | 
			
		||||
		switch (idx)
 | 
			
		||||
		{
 | 
			
		||||
		case 1: case 2: return e1.top;
 | 
			
		||||
		default: return e1.bot;
 | 
			
		||||
| 
						 | 
				
			
			@ -214,7 +217,7 @@ namespace Clipper2Lib {
 | 
			
		|||
	Point64 GetIntersectPoint(const Active& e1, const Active& e2)
 | 
			
		||||
	{
 | 
			
		||||
		double b1, b2, q = (e1.dx - e2.dx);
 | 
			
		||||
		if (std::abs(q) < 1e-5)			// 1e-5 is a rough empirical limit 
 | 
			
		||||
		if (std::abs(q) < 1e-5)			// 1e-5 is a rough empirical limit
 | 
			
		||||
			return GetEndE1ClosestToEndE2(e1, e2); // ie almost parallel
 | 
			
		||||
 | 
			
		||||
		if (e1.dx == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +238,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		{
 | 
			
		||||
			b1 = e1.bot.x - e1.bot.y * e1.dx;
 | 
			
		||||
			b2 = e2.bot.x - e2.bot.y * e2.dx;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			q = (b2 - b1) / q;
 | 
			
		||||
			return (abs(e1.dx) < abs(e2.dx)) ?
 | 
			
		||||
				Point64(static_cast<int64_t>(e1.dx * q + b1),
 | 
			
		||||
| 
						 | 
				
			
			@ -306,7 +309,7 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
	//PrevPrevVertex: useful to get the (inverted Y-axis) top of the
 | 
			
		||||
	//alternate edge (ie left or right bound) during edge insertion.	
 | 
			
		||||
	//alternate edge (ie left or right bound) during edge insertion.
 | 
			
		||||
	inline Vertex* PrevPrevVertex(const Active& ae)
 | 
			
		||||
	{
 | 
			
		||||
		if (ae.wind_dx > 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +356,7 @@ namespace Clipper2Lib {
 | 
			
		|||
			while (result->next->pt.y == result->pt.y) result = result->next;
 | 
			
		||||
		else
 | 
			
		||||
			while (result->prev->pt.y == result->pt.y) result = result->prev;
 | 
			
		||||
		if (!IsMaxima(*result)) result = nullptr; // not a maxima   
 | 
			
		||||
		if (!IsMaxima(*result)) result = nullptr; // not a maxima
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -494,7 +497,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		return result * 0.5;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	inline double AreaTriangle(const Point64& pt1, 
 | 
			
		||||
	inline double AreaTriangle(const Point64& pt1,
 | 
			
		||||
		const Point64& pt2, const Point64& pt3)
 | 
			
		||||
	{
 | 
			
		||||
		return (static_cast<double>(pt3.y + pt1.y) * static_cast<double>(pt3.x - pt1.x) +
 | 
			
		||||
| 
						 | 
				
			
			@ -630,7 +633,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		Clear();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void ClipperBase::DeleteEdges(Active*& e) 
 | 
			
		||||
	void ClipperBase::DeleteEdges(Active*& e)
 | 
			
		||||
	{
 | 
			
		||||
		while (e)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -681,7 +684,7 @@ namespace Clipper2Lib {
 | 
			
		|||
	void ClipperBase::SetZ(const Active& e1, const Active& e2, Point64& ip)
 | 
			
		||||
	{
 | 
			
		||||
		if (!zCallback_) return;
 | 
			
		||||
		// prioritize subject over clip vertices by passing 
 | 
			
		||||
		// prioritize subject over clip vertices by passing
 | 
			
		||||
		// subject vertices before clip vertices in the callback
 | 
			
		||||
		if (GetPolyType(e1) == PathType::Subject)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -872,19 +875,19 @@ namespace Clipper2Lib {
 | 
			
		|||
		case FillRule::EvenOdd:
 | 
			
		||||
			break;
 | 
			
		||||
		case FillRule::NonZero:
 | 
			
		||||
			if (abs(e.wind_cnt) != 1) return false; 
 | 
			
		||||
			if (abs(e.wind_cnt) != 1) return false;
 | 
			
		||||
			break;
 | 
			
		||||
		case FillRule::Positive:
 | 
			
		||||
			if (e.wind_cnt != 1) return false; 
 | 
			
		||||
			if (e.wind_cnt != 1) return false;
 | 
			
		||||
			break;
 | 
			
		||||
		case FillRule::Negative:
 | 
			
		||||
			if (e.wind_cnt != -1) return false; 
 | 
			
		||||
			if (e.wind_cnt != -1) return false;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch (cliptype_)
 | 
			
		||||
		{
 | 
			
		||||
		case ClipType::None: 
 | 
			
		||||
		case ClipType::None:
 | 
			
		||||
			return false;
 | 
			
		||||
		case ClipType::Intersection:
 | 
			
		||||
			switch (fillrule_)
 | 
			
		||||
| 
						 | 
				
			
			@ -914,17 +917,17 @@ namespace Clipper2Lib {
 | 
			
		|||
			bool result;
 | 
			
		||||
			switch (fillrule_)
 | 
			
		||||
			{
 | 
			
		||||
			case FillRule::Positive: 
 | 
			
		||||
				result = (e.wind_cnt2 <= 0); 
 | 
			
		||||
			case FillRule::Positive:
 | 
			
		||||
				result = (e.wind_cnt2 <= 0);
 | 
			
		||||
				break;
 | 
			
		||||
			case FillRule::Negative:
 | 
			
		||||
				result = (e.wind_cnt2 >= 0); 
 | 
			
		||||
				result = (e.wind_cnt2 >= 0);
 | 
			
		||||
				break;
 | 
			
		||||
			default: 
 | 
			
		||||
			default:
 | 
			
		||||
				result = (e.wind_cnt2 == 0);
 | 
			
		||||
			}
 | 
			
		||||
			if (GetPolyType(e) == PathType::Subject)
 | 
			
		||||
				return result; 
 | 
			
		||||
				return result;
 | 
			
		||||
			else
 | 
			
		||||
				return !result;
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			@ -940,15 +943,15 @@ namespace Clipper2Lib {
 | 
			
		|||
		bool is_in_clip, is_in_subj;
 | 
			
		||||
		switch (fillrule_)
 | 
			
		||||
		{
 | 
			
		||||
		case FillRule::Positive: 
 | 
			
		||||
			is_in_clip = e.wind_cnt2 > 0; 
 | 
			
		||||
		case FillRule::Positive:
 | 
			
		||||
			is_in_clip = e.wind_cnt2 > 0;
 | 
			
		||||
			is_in_subj = e.wind_cnt > 0;
 | 
			
		||||
			break;
 | 
			
		||||
		case FillRule::Negative: 
 | 
			
		||||
			is_in_clip = e.wind_cnt2 < 0; 
 | 
			
		||||
		case FillRule::Negative:
 | 
			
		||||
			is_in_clip = e.wind_cnt2 < 0;
 | 
			
		||||
			is_in_subj = e.wind_cnt < 0;
 | 
			
		||||
			break;
 | 
			
		||||
		default: 
 | 
			
		||||
		default:
 | 
			
		||||
			is_in_clip = e.wind_cnt2 != 0;
 | 
			
		||||
			is_in_subj = e.wind_cnt != 0;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -1085,15 +1088,15 @@ namespace Clipper2Lib {
 | 
			
		|||
		//the direction they're about to turn
 | 
			
		||||
		if (!IsMaxima(resident) && (resident.top.y > newcomer.top.y))
 | 
			
		||||
		{
 | 
			
		||||
			return CrossProduct(newcomer.bot, 
 | 
			
		||||
			return CrossProduct(newcomer.bot,
 | 
			
		||||
				resident.top, NextVertex(resident)->pt) <= 0;
 | 
			
		||||
		}
 | 
			
		||||
		else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y))		
 | 
			
		||||
		else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y))
 | 
			
		||||
		{
 | 
			
		||||
			return CrossProduct(newcomer.bot,
 | 
			
		||||
				newcomer.top, NextVertex(newcomer)->pt) >= 0;
 | 
			
		||||
		}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		int64_t y = newcomer.bot.y;
 | 
			
		||||
		bool newcomerIsLeft = newcomer.is_left_bound;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1103,7 +1106,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		else if (resident.is_left_bound != newcomerIsLeft)
 | 
			
		||||
			return newcomerIsLeft;
 | 
			
		||||
		else if (CrossProduct(PrevPrevVertex(resident)->pt,
 | 
			
		||||
			resident.bot, resident.top) == 0) return true;				
 | 
			
		||||
			resident.bot, resident.top) == 0) return true;
 | 
			
		||||
		else
 | 
			
		||||
			//compare turning direction of the alternate bound
 | 
			
		||||
			return (CrossProduct(PrevPrevVertex(resident)->pt,
 | 
			
		||||
| 
						 | 
				
			
			@ -1319,7 +1322,7 @@ namespace Clipper2Lib {
 | 
			
		|||
				SetSides(*outrec, e1, e2);
 | 
			
		||||
			else
 | 
			
		||||
				SetSides(*outrec, e2, e1);
 | 
			
		||||
		}	 
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			Active* prevHotEdge = GetPrevHotEdge(e1);
 | 
			
		||||
| 
						 | 
				
			
			@ -1335,7 +1338,7 @@ namespace Clipper2Lib {
 | 
			
		|||
				else
 | 
			
		||||
					SetSides(*outrec, e1, e2);
 | 
			
		||||
			}
 | 
			
		||||
			else 
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				outrec->owner = nullptr;
 | 
			
		||||
				if (is_new)
 | 
			
		||||
| 
						 | 
				
			
			@ -1344,7 +1347,7 @@ namespace Clipper2Lib {
 | 
			
		|||
					SetSides(*outrec, e2, e1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		OutPt* op = new OutPt(pt, outrec);
 | 
			
		||||
		outrec->pts = op;
 | 
			
		||||
		return op;
 | 
			
		||||
| 
						 | 
				
			
			@ -1359,7 +1362,7 @@ namespace Clipper2Lib {
 | 
			
		|||
				SwapFrontBackSides(*e1.outrec);
 | 
			
		||||
			else if (IsOpenEnd(e2))
 | 
			
		||||
				SwapFrontBackSides(*e2.outrec);
 | 
			
		||||
			else 
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				succeeded_ = false;
 | 
			
		||||
				return nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -1369,7 +1372,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		OutPt* result = AddOutPt(e1, pt);
 | 
			
		||||
		if (e1.outrec == e2.outrec)
 | 
			
		||||
		{
 | 
			
		||||
			OutRec& outrec = *e1.outrec;		
 | 
			
		||||
			OutRec& outrec = *e1.outrec;
 | 
			
		||||
			outrec.pts = result;
 | 
			
		||||
 | 
			
		||||
			UncoupleOutRec(e1);
 | 
			
		||||
| 
						 | 
				
			
			@ -1523,7 +1526,7 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
	void ClipperBase::DoSplitOp(OutRec* outrec, OutPt* splitOp)
 | 
			
		||||
	{
 | 
			
		||||
		// splitOp.prev -> splitOp && 
 | 
			
		||||
		// splitOp.prev -> splitOp &&
 | 
			
		||||
		// splitOp.next -> splitOp.next.next are intersecting
 | 
			
		||||
		OutPt* prevOp = splitOp->prev;
 | 
			
		||||
		OutPt* nextNextOp = splitOp->next->next;
 | 
			
		||||
| 
						 | 
				
			
			@ -1572,7 +1575,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		SafeDeleteOutPtJoiners(splitOp->next);
 | 
			
		||||
		SafeDeleteOutPtJoiners(splitOp);
 | 
			
		||||
 | 
			
		||||
		if (absArea2 >= 1 && 
 | 
			
		||||
		if (absArea2 >= 1 &&
 | 
			
		||||
			(absArea2 > absArea1 || (area2 > 0) == (area1 > 0)))
 | 
			
		||||
		{
 | 
			
		||||
			OutRec* newOutRec = new OutRec();
 | 
			
		||||
| 
						 | 
				
			
			@ -1762,7 +1765,7 @@ namespace Clipper2Lib {
 | 
			
		|||
			else result = result->next_in_ael;
 | 
			
		||||
		}
 | 
			
		||||
		result = e->prev_in_ael;
 | 
			
		||||
		while (result) 
 | 
			
		||||
		while (result)
 | 
			
		||||
		{
 | 
			
		||||
			if (result->local_min == e->local_min) return result;
 | 
			
		||||
			else if (!IsHorizontal(*result) && e->bot != result->bot) return nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -1791,14 +1794,14 @@ namespace Clipper2Lib {
 | 
			
		|||
				edge_c = &e1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (abs(edge_c->wind_cnt) != 1) return nullptr;			
 | 
			
		||||
			if (abs(edge_c->wind_cnt) != 1) return nullptr;
 | 
			
		||||
			switch (cliptype_)
 | 
			
		||||
			{
 | 
			
		||||
			case ClipType::Union: 
 | 
			
		||||
				if (!IsHotEdge(*edge_c)) return nullptr; 
 | 
			
		||||
			case ClipType::Union:
 | 
			
		||||
				if (!IsHotEdge(*edge_c)) return nullptr;
 | 
			
		||||
				break;
 | 
			
		||||
			default: 
 | 
			
		||||
				if (edge_c->local_min->polytype == PathType::Subject) 
 | 
			
		||||
			default:
 | 
			
		||||
				if (edge_c->local_min->polytype == PathType::Subject)
 | 
			
		||||
					return nullptr;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1821,11 +1824,11 @@ namespace Clipper2Lib {
 | 
			
		|||
				edge_o->outrec = nullptr;
 | 
			
		||||
				return resultOp;
 | 
			
		||||
			}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
			//horizontal edges can pass under open paths at a LocMins
 | 
			
		||||
			else if (pt == edge_o->local_min->vertex->pt &&
 | 
			
		||||
				!IsOpenEnd(*edge_o->local_min->vertex))
 | 
			
		||||
			{ 
 | 
			
		||||
			{
 | 
			
		||||
				//find the other side of the LocMin and
 | 
			
		||||
				//if it's 'hot' join up with it ...
 | 
			
		||||
				Active* e3 = FindEdgeWithMatchingLocMin(edge_o);
 | 
			
		||||
| 
						 | 
				
			
			@ -1833,7 +1836,7 @@ namespace Clipper2Lib {
 | 
			
		|||
				{
 | 
			
		||||
					edge_o->outrec = e3->outrec;
 | 
			
		||||
					if (edge_o->wind_dx > 0)
 | 
			
		||||
						SetSides(*e3->outrec, *edge_o, *e3); 
 | 
			
		||||
						SetSides(*e3->outrec, *edge_o, *e3);
 | 
			
		||||
					else
 | 
			
		||||
						SetSides(*e3->outrec, *e3, *edge_o);
 | 
			
		||||
					return e3->outrec->pts;
 | 
			
		||||
| 
						 | 
				
			
			@ -1847,7 +1850,7 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
		//MANAGING CLOSED PATHS FROM HERE ON
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		//UPDATE WINDING COUNTS...
 | 
			
		||||
 | 
			
		||||
		int old_e1_windcnt, old_e2_windcnt;
 | 
			
		||||
| 
						 | 
				
			
			@ -1913,7 +1916,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		{
 | 
			
		||||
			return nullptr;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		//NOW PROCESS THE INTERSECTION ...
 | 
			
		||||
		OutPt* resultOp = nullptr;
 | 
			
		||||
		//if both edges are 'hot' ...
 | 
			
		||||
| 
						 | 
				
			
			@ -2282,7 +2285,7 @@ namespace Clipper2Lib {
 | 
			
		|||
	inline bool HorzIsSpike(const Active& horzEdge)
 | 
			
		||||
	{
 | 
			
		||||
		Point64 nextPt = NextVertex(horzEdge)->pt;
 | 
			
		||||
		return (nextPt.y == horzEdge.bot.y) && 
 | 
			
		||||
		return (nextPt.y == horzEdge.bot.y) &&
 | 
			
		||||
			(horzEdge.bot.x < horzEdge.top.x) != (horzEdge.top.x < nextPt.x);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2295,7 +2298,7 @@ namespace Clipper2Lib {
 | 
			
		|||
			//always trim 180 deg. spikes (in closed paths)
 | 
			
		||||
			//but otherwise break if preserveCollinear = true
 | 
			
		||||
			if (preserveCollinear &&
 | 
			
		||||
				((pt.x < horzEdge.top.x) != (horzEdge.bot.x < horzEdge.top.x))) 
 | 
			
		||||
				((pt.x < horzEdge.top.x) != (horzEdge.bot.x < horzEdge.top.x)))
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
			horzEdge.vertex_top = NextVertex(horzEdge);
 | 
			
		||||
| 
						 | 
				
			
			@ -2353,11 +2356,11 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
		OutPt* op;
 | 
			
		||||
		while (true) // loop through consec. horizontal edges
 | 
			
		||||
		{  
 | 
			
		||||
		{
 | 
			
		||||
			if (horzIsOpen && IsMaxima(horz) && !IsOpenEnd(horz))
 | 
			
		||||
			{
 | 
			
		||||
				vertex_max = GetCurrYMaximaVertex(horz);
 | 
			
		||||
				if (vertex_max) 
 | 
			
		||||
				if (vertex_max)
 | 
			
		||||
					max_pair = GetHorzMaximaPair(horz, vertex_max);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2388,7 +2391,7 @@ namespace Clipper2Lib {
 | 
			
		|||
 | 
			
		||||
				//if horzEdge is a maxima, keep going until we reach
 | 
			
		||||
				//its maxima pair, otherwise check for break conditions
 | 
			
		||||
				if (vertex_max != horz.vertex_top || IsOpenEnd(horz)) 
 | 
			
		||||
				if (vertex_max != horz.vertex_top || IsOpenEnd(horz))
 | 
			
		||||
				{
 | 
			
		||||
					//otherwise stop when 'ae' is beyond the end of the horizontal line
 | 
			
		||||
					if ((is_left_to_right && e->curr_x > horz_right) ||
 | 
			
		||||
| 
						 | 
				
			
			@ -2467,15 +2470,15 @@ namespace Clipper2Lib {
 | 
			
		|||
				{
 | 
			
		||||
					AddOutPt(horz, horz.top);
 | 
			
		||||
					if (IsFront(horz))
 | 
			
		||||
						horz.outrec->front_edge = nullptr; 
 | 
			
		||||
						horz.outrec->front_edge = nullptr;
 | 
			
		||||
					else
 | 
			
		||||
						horz.outrec->back_edge = nullptr;
 | 
			
		||||
					horz.outrec = nullptr;
 | 
			
		||||
				}
 | 
			
		||||
				DeleteFromAEL(horz); 
 | 
			
		||||
				DeleteFromAEL(horz);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			else if (NextVertex(horz)->pt.y != horz.top.y) 
 | 
			
		||||
			else if (NextVertex(horz)->pt.y != horz.top.y)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			//still more horizontals in bound to process ...
 | 
			
		||||
| 
						 | 
				
			
			@ -2486,7 +2489,7 @@ namespace Clipper2Lib {
 | 
			
		|||
			if (PreserveCollinear && !horzIsOpen && HorzIsSpike(horz))
 | 
			
		||||
				TrimHorz(horz, true);
 | 
			
		||||
 | 
			
		||||
			is_left_to_right = 
 | 
			
		||||
			is_left_to_right =
 | 
			
		||||
				ResetHorzDirection(horz, max_pair, horz_left, horz_right);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2499,7 +2502,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		else
 | 
			
		||||
			op = nullptr;
 | 
			
		||||
 | 
			
		||||
		if ((horzIsOpen && !IsOpenEnd(horz)) || 
 | 
			
		||||
		if ((horzIsOpen && !IsOpenEnd(horz)) ||
 | 
			
		||||
			(!horzIsOpen && vertex_max != horz.vertex_top))
 | 
			
		||||
		{
 | 
			
		||||
			UpdateEdgeIntoAEL(&horz); // this is the end of an intermediate horiz.
 | 
			
		||||
| 
						 | 
				
			
			@ -2516,7 +2519,7 @@ namespace Clipper2Lib {
 | 
			
		|||
				AddJoin(op2, op);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if (IsHotEdge(horz)) 
 | 
			
		||||
		else if (IsHotEdge(horz))
 | 
			
		||||
			AddLocalMaxPoly(horz, *max_pair, horz.top);
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -2966,7 +2969,7 @@ namespace Clipper2Lib {
 | 
			
		|||
				OutRec* outrec = ProcessJoin(j);
 | 
			
		||||
				CleanCollinear(outrec);
 | 
			
		||||
			}
 | 
			
		||||
			else 
 | 
			
		||||
			else
 | 
			
		||||
				delete j;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3015,7 +3018,7 @@ namespace Clipper2Lib {
 | 
			
		|||
	bool CollinearSegsOverlap(const Point64& seg1a, const Point64& seg1b,
 | 
			
		||||
		const Point64& seg2a, const Point64& seg2b)
 | 
			
		||||
	{
 | 
			
		||||
		//precondition: seg1 and seg2 are collinear      
 | 
			
		||||
		//precondition: seg1 and seg2 are collinear
 | 
			
		||||
		if (seg1a.x == seg1b.x)
 | 
			
		||||
		{
 | 
			
		||||
			if (seg2a.x != seg1a.x || seg2a.x != seg2b.x) return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -3146,7 +3149,7 @@ namespace Clipper2Lib {
 | 
			
		|||
					{
 | 
			
		||||
						or1->pts = op1;
 | 
			
		||||
						or2->pts = nullptr;
 | 
			
		||||
						if (or1->owner && (!or2->owner || 
 | 
			
		||||
						if (or1->owner && (!or2->owner ||
 | 
			
		||||
							or2->owner->idx < or1->owner->idx))
 | 
			
		||||
								or1->owner = or2->owner;
 | 
			
		||||
						or2->owner = or1;
 | 
			
		||||
| 
						 | 
				
			
			@ -3156,7 +3159,7 @@ namespace Clipper2Lib {
 | 
			
		|||
						result = or2;
 | 
			
		||||
						or2->pts = op1;
 | 
			
		||||
						or1->pts = nullptr;
 | 
			
		||||
						if (or2->owner && (!or1->owner || 
 | 
			
		||||
						if (or2->owner && (!or1->owner ||
 | 
			
		||||
							or1->owner->idx < or2->owner->idx))
 | 
			
		||||
								or2->owner = or1->owner;
 | 
			
		||||
						or1->owner = or2;
 | 
			
		||||
| 
						 | 
				
			
			@ -3207,7 +3210,7 @@ namespace Clipper2Lib {
 | 
			
		|||
					{
 | 
			
		||||
						or1->pts = op1;
 | 
			
		||||
						or2->pts = nullptr;
 | 
			
		||||
						if (or1->owner && (!or2->owner || 
 | 
			
		||||
						if (or1->owner && (!or2->owner ||
 | 
			
		||||
							or2->owner->idx < or1->owner->idx))
 | 
			
		||||
								or1->owner = or2->owner;
 | 
			
		||||
						or2->owner = or1;
 | 
			
		||||
| 
						 | 
				
			
			@ -3217,9 +3220,9 @@ namespace Clipper2Lib {
 | 
			
		|||
						result = or2;
 | 
			
		||||
						or2->pts = op1;
 | 
			
		||||
						or1->pts = nullptr;
 | 
			
		||||
						if (or2->owner && (!or1->owner || 
 | 
			
		||||
						if (or2->owner && (!or1->owner ||
 | 
			
		||||
							or1->owner->idx < or2->owner->idx))
 | 
			
		||||
								or2->owner = or1->owner; 
 | 
			
		||||
								or2->owner = or1->owner;
 | 
			
		||||
						or1->owner = or2;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -3310,11 +3313,11 @@ namespace Clipper2Lib {
 | 
			
		|||
			if (pt.y > result.bottom) result.bottom = pt.y;
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool BuildPath64(OutPt* op, bool reverse, bool isOpen, Path64& path)
 | 
			
		||||
	{
 | 
			
		||||
		if (op->next == op || (!isOpen && op->next == op->prev)) 
 | 
			
		||||
		if (op->next == op || (!isOpen && op->next == op->prev))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		path.resize(0);
 | 
			
		||||
| 
						 | 
				
			
			@ -3355,9 +3358,9 @@ namespace Clipper2Lib {
 | 
			
		|||
		if (owner->bounds.IsEmpty()) owner->bounds = GetBounds(owner->path);
 | 
			
		||||
		bool is_inside_owner_bounds = owner->bounds.Contains(outrec->bounds);
 | 
			
		||||
 | 
			
		||||
		// while looking for the correct owner, check the owner's 
 | 
			
		||||
		// splits **before** checking the owner itself because 
 | 
			
		||||
		// splits can occur internally, and checking the owner 
 | 
			
		||||
		// while looking for the correct owner, check the owner's
 | 
			
		||||
		// splits **before** checking the owner itself because
 | 
			
		||||
		// splits can occur internally, and checking the owner
 | 
			
		||||
		// first would miss the inner split's true ownership
 | 
			
		||||
		if (owner->splits)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -3388,7 +3391,7 @@ namespace Clipper2Lib {
 | 
			
		|||
		{
 | 
			
		||||
			if (is_inside_owner_bounds && Path1InsidePath2(outrec, outrec->owner))
 | 
			
		||||
				return true;
 | 
			
		||||
			// otherwise keep trying with owner's owner 
 | 
			
		||||
			// otherwise keep trying with owner's owner
 | 
			
		||||
			outrec->owner = outrec->owner->owner;
 | 
			
		||||
			if (!outrec->owner) return true; // true or false
 | 
			
		||||
			is_inside_owner_bounds = outrec->owner->bounds.Contains(outrec->bounds);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue