Fixed Clipper library (our own fork of it) when working with Z coordinate (#7180)

Fixed Clipper library (our own fork of it) when working with Z coordinate:
The Eigen vector type compares all components, while the ClipperLib
own IntPoint type compared x and y only.
Fixed by overriding the ==/!= operators to compare just x and y components
for Eigen types.

Cherry-picked from prusa3d/PrusaSlicer@0202eec4b7

Co-authored-by: Vojtech Bubnik <bubnikv@gmail.com>
This commit is contained in:
Noisyfox 2024-10-24 22:26:40 +08:00 committed by GitHub
parent 425d9c97e4
commit be5bc632ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -119,6 +119,10 @@ inline cInt Round(double val)
return static_cast<cInt>((val < 0) ? (val - 0.5) : (val + 0.5)); return static_cast<cInt>((val < 0) ? (val - 0.5) : (val + 0.5));
} }
// Overriding the Eigen operators because we don't want to compare Z coordinate if IntPoint is 3 dimensional.
inline bool operator==(const IntPoint &l, const IntPoint &r) { return l.x() == r.x() && l.y() == r.y(); }
inline bool operator!=(const IntPoint &l, const IntPoint &r) { return l.x() != r.x() || l.y() != r.y(); }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// PolyTree methods ... // PolyTree methods ...
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -189,19 +193,25 @@ double Area(const Path &poly)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
double Area(const OutRec &outRec) double Area(const OutPt *op)
{ {
OutPt *op = outRec.Pts; const OutPt *startOp = op;
if (!op) return 0; if (!op) return 0;
double a = 0; double a = 0;
do { do {
a += (double)(op->Prev->Pt.x() + op->Pt.x()) * (double)(op->Prev->Pt.y() - op->Pt.y()); a += (double)(op->Prev->Pt.x() + op->Pt.x()) * (double)(op->Prev->Pt.y() - op->Pt.y());
op = op->Next; op = op->Next;
} while (op != outRec.Pts); } while (op != startOp);
return a * 0.5; return a * 0.5;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
double Area(const OutRec &outRec)
{
return Area(outRec.Pts);
}
//------------------------------------------------------------------------------
bool PointIsVertex(const IntPoint &Pt, OutPt *pp) bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
{ {
OutPt *pp2 = pp; OutPt *pp2 = pp;
@ -536,6 +546,11 @@ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
p = btmPt2->Next; p = btmPt2->Next;
while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next; while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt)); double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
return Area(btmPt1) > 0; //if otherwise identical use orientation
else
return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n); return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -543,20 +558,20 @@ bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
// Called by GetLowermostRec() // Called by GetLowermostRec()
OutPt* GetBottomPt(OutPt *pp) OutPt* GetBottomPt(OutPt *pp)
{ {
OutPt* dups = 0; OutPt* dups = nullptr;
OutPt* p = pp->Next; OutPt* p = pp->Next;
while (p != pp) while (p != pp)
{ {
if (p->Pt.y() > pp->Pt.y()) if (p->Pt.y() > pp->Pt.y())
{ {
pp = p; pp = p;
dups = 0; dups = nullptr;
} }
else if (p->Pt.y() == pp->Pt.y() && p->Pt.x() <= pp->Pt.x()) else if (p->Pt.y() == pp->Pt.y() && p->Pt.x() <= pp->Pt.x())
{ {
if (p->Pt.x() < pp->Pt.x()) if (p->Pt.x() < pp->Pt.x())
{ {
dups = 0; dups = nullptr;
pp = p; pp = p;
} else } else
{ {
@ -577,6 +592,7 @@ OutPt* GetBottomPt(OutPt *pp)
} }
return pp; return pp;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool Pt2IsBetweenPt1AndPt3(const IntPoint &pt1, bool Pt2IsBetweenPt1AndPt3(const IntPoint &pt1,