feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -1,8 +1,8 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 8 September 2023 *
* Date : 5 July 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : FAST rectangular clipping *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************/
@ -71,7 +71,7 @@ namespace Clipper2Lib {
return pt1.y == pt2.y;
}
inline bool GetSegmentIntersection(const Point64& p1,
bool GetSegmentIntersection(const Point64& p1,
const Point64& p2, const Point64& p3, const Point64& p4, Point64& ip)
{
double res1 = CrossProduct(p1, p3, p4);
@ -113,7 +113,7 @@ namespace Clipper2Lib {
if ((res3 > 0) == (res4 > 0)) return false;
// segments must intersect to get here
return GetIntersectPoint(p1, p2, p3, p4, ip);
return GetSegmentIntersectPt(p1, p2, p3, p4, ip);
}
inline bool GetIntersection(const Path64& rectPath,
@ -125,7 +125,7 @@ namespace Clipper2Lib {
{
case Location::Left:
if (GetSegmentIntersection(p, p2, rectPath[0], rectPath[3], ip)) return true;
else if ((p.y < rectPath[0].y) && GetSegmentIntersection(p, p2, rectPath[0], rectPath[1], ip))
else if ((p.y < rectPath[0].y) && GetSegmentIntersection(p, p2, rectPath[0], rectPath[1], ip))
{
loc = Location::Top;
return true;
@ -180,7 +180,7 @@ namespace Clipper2Lib {
else return false;
default: // loc == rInside
if (GetSegmentIntersection(p, p2, rectPath[0], rectPath[3], ip))
if (GetSegmentIntersection(p, p2, rectPath[0], rectPath[3], ip))
{
loc = Location::Left;
return true;
@ -320,9 +320,9 @@ namespace Clipper2Lib {
// this method is only called by InternalExecute.
// Later splitting & rejoining won't create additional op's,
// though they will change the (non-storage) results_ count.
int curr_idx = static_cast<int>(results_.size()) - 1;
size_t curr_idx = results_.size();
OutPt2* result;
if (curr_idx < 0 || start_new)
if (curr_idx == 0 || start_new)
{
result = &op_container_.emplace_back(OutPt2());
result->pt = pt;
@ -332,6 +332,7 @@ namespace Clipper2Lib {
}
else
{
--curr_idx;
OutPt2* prevOp = results_[curr_idx];
if (prevOp->pt == pt) return prevOp;
result = &op_container_.emplace_back(OutPt2());
@ -349,27 +350,27 @@ namespace Clipper2Lib {
void RectClip64::AddCorner(Location prev, Location curr)
{
if (HeadingClockwise(prev, curr))
Add(rect_as_path_[static_cast<int>(prev)]);
Add(rect_as_path_[static_cast<size_t>(prev)]);
else
Add(rect_as_path_[static_cast<int>(curr)]);
Add(rect_as_path_[static_cast<size_t>(curr)]);
}
void RectClip64::AddCorner(Location& loc, bool isClockwise)
{
if (isClockwise)
{
Add(rect_as_path_[static_cast<int>(loc)]);
Add(rect_as_path_[static_cast<size_t>(loc)]);
loc = GetAdjacentLocation(loc, true);
}
else
{
loc = GetAdjacentLocation(loc, false);
Add(rect_as_path_[static_cast<int>(loc)]);
Add(rect_as_path_[static_cast<size_t>(loc)]);
}
}
void RectClip64::GetNextLocation(const Path64& path,
Location& loc, int& i, int highI)
Location& loc, size_t& i, size_t highI)
{
switch (loc)
{
@ -420,31 +421,52 @@ namespace Clipper2Lib {
break; //inner loop
}
break;
} //switch
} //switch
}
bool StartLocsAreClockwise(const std::vector<Location>& startlocs)
{
int result = 0;
for (size_t i = 1; i < startlocs.size(); ++i)
{
int d = static_cast<int>(startlocs[i]) - static_cast<int>(startlocs[i - 1]);
switch (d)
{
case -1: result -= 1; break;
case 1: result += 1; break;
case -3: result += 1; break;
case 3: result -= 1; break;
}
}
return result > 0;
}
void RectClip64::ExecuteInternal(const Path64& path)
{
int i = 0, highI = static_cast<int>(path.size()) - 1;
if (path.size() < 1)
return;
size_t highI = path.size() - 1;
Location prev = Location::Inside, loc;
Location crossing_loc = Location::Inside;
Location first_cross_ = Location::Inside;
if (!GetLocation(rect_, path[highI], loc))
{
i = highI - 1;
while (i >= 0 && !GetLocation(rect_, path[i], prev)) --i;
if (i < 0)
size_t i = highI;
while (i > 0 && !GetLocation(rect_, path[i - 1], prev))
--i;
if (i == 0)
{
// all of path must be inside fRect
for (const auto& pt : path) Add(pt);
return;
}
if (prev == Location::Inside) loc = Location::Inside;
i = 0;
}
Location startingLoc = loc;
Location starting_loc = loc;
///////////////////////////////////////////////////
size_t i = 0;
while (i <= highI)
{
prev = loc;
@ -454,12 +476,12 @@ namespace Clipper2Lib {
if (i > highI) break;
Point64 ip, ip2;
Point64 prev_pt = (i) ?
path[static_cast<size_t>(i - 1)] :
Point64 prev_pt = (i) ?
path[static_cast<size_t>(i - 1)] :
path[highI];
crossing_loc = loc;
if (!GetIntersection(rect_as_path_,
if (!GetIntersection(rect_as_path_,
path[i], prev_pt, crossing_loc, ip))
{
// ie remaining outside
@ -470,7 +492,7 @@ namespace Clipper2Lib {
start_locs_.push_back(prev);
prev = GetAdjacentLocation(prev, isClockw);
} while (prev != loc);
crossing_loc = crossing_prev; // still not crossed
crossing_loc = crossing_prev; // still not crossed
}
else if (prev != Location::Inside && prev != loc)
{
@ -504,7 +526,7 @@ namespace Clipper2Lib {
}
else if (prev != Location::Inside)
{
// passing right through rect. 'ip' here will be the second
// passing right through rect. 'ip' here will be the second
// intersect pt but we'll also need the first intersect pt (ip2)
loc = prev;
GetIntersection(rect_as_path_, prev_pt, path[i], loc, ip2);
@ -543,7 +565,7 @@ namespace Clipper2Lib {
if (first_cross_ == Location::Inside)
{
// path never intersects
if (startingLoc != Location::Inside)
if (starting_loc != Location::Inside)
{
// path is outside rect
// but being outside, it still may not contain rect
@ -552,11 +574,13 @@ namespace Clipper2Lib {
{
// yep, the path does fully contain rect
// so add rect to the solution
bool is_clockwise_path = StartLocsAreClockwise(start_locs_);
for (size_t j = 0; j < 4; ++j)
{
Add(rect_as_path_[j]);
size_t k = is_clockwise_path ? j : 3 - j; // reverses result path
Add(rect_as_path_[k]);
// we may well need to do some splitting later, so
AddToEdge(edges_[j * 2], results_[0]);
AddToEdge(edges_[k * 2], results_[0]);
}
}
}
@ -589,8 +613,7 @@ namespace Clipper2Lib {
OutPt2* op2 = op;
do
{
if (!CrossProduct(op2->prev->pt,
op2->pt, op2->next->pt))
if (IsCollinear(op2->prev->pt, op2->pt, op2->next->pt))
{
if (op2 == op)
{
@ -640,7 +663,7 @@ namespace Clipper2Lib {
}
}
void RectClip64::TidyEdges(int idx, OutPt2List& cw, OutPt2List& ccw)
void RectClip64::TidyEdges(size_t idx, OutPt2List& cw, OutPt2List& ccw)
{
if (ccw.empty()) return;
bool isHorz = ((idx == 1) || (idx == 3));
@ -648,7 +671,7 @@ namespace Clipper2Lib {
size_t i = 0, j = 0;
OutPt2* p1, * p2, * p1a, * p2a, * op, * op2;
while (i < cw.size())
while (i < cw.size())
{
p1 = cw[i];
if (!p1 || p1->next == p1->prev)
@ -825,8 +848,8 @@ namespace Clipper2Lib {
OutPt2* op2 = op->next;
while (op2 && op2 != op)
{
if (CrossProduct(op2->prev->pt,
op2->pt, op2->next->pt) == 0)
if (IsCollinear(op2->prev->pt,
op2->pt, op2->next->pt))
{
op = op2->prev;
op2 = UnlinkOp(op2);
@ -854,7 +877,7 @@ namespace Clipper2Lib {
if (rect_.IsEmpty()) return result;
for (const Path64& path : paths)
{
{
if (path.size() < 3) continue;
path_bounds_ = GetBounds(path);
if (!rect_.Intersects(path_bounds_))
@ -868,9 +891,9 @@ namespace Clipper2Lib {
ExecuteInternal(path);
CheckEdges();
for (int i = 0; i < 4; ++i)
for (size_t i = 0; i < 4; ++i)
TidyEdges(i, edges_[i * 2], edges_[i * 2 + 1]);
for (OutPt2*& op : results_)
{
Path64 tmp = GetPath(op);
@ -925,14 +948,14 @@ namespace Clipper2Lib {
op_container_ = std::deque<OutPt2>();
start_locs_.clear();
int i = 1, highI = static_cast<int>(path.size()) - 1;
size_t i = 1, highI = path.size() - 1;
Location prev = Location::Inside, loc;
Location crossing_loc;
if (!GetLocation(rect_, path[0], loc))
{
while (i <= highI && !GetLocation(rect_, path[i], prev)) ++i;
if (i > highI)
if (i > highI)
{
// all of path must be inside fRect
for (const auto& pt : path) Add(pt);
@ -953,7 +976,7 @@ namespace Clipper2Lib {
Point64 prev_pt = path[static_cast<size_t>(i - 1)];
crossing_loc = loc;
if (!GetIntersection(rect_as_path_,
if (!GetIntersection(rect_as_path_,
path[i], prev_pt, crossing_loc, ip))
{
// ie remaining outside
@ -971,10 +994,10 @@ namespace Clipper2Lib {
}
else if (prev != Location::Inside)
{
// passing right through rect. 'ip' here will be the second
// passing right through rect. 'ip' here will be the second
// intersect pt but we'll also need the first intersect pt (ip2)
crossing_loc = prev;
GetIntersection(rect_as_path_,
GetIntersection(rect_as_path_,
prev_pt, path[i], crossing_loc, ip2);
Add(ip2, true);
Add(ip);
@ -991,14 +1014,14 @@ namespace Clipper2Lib {
{
Path64 result;
if (!op || op == op->next) return result;
op = op->next; // starting at path beginning
op = op->next; // starting at path beginning
result.push_back(op->pt);
OutPt2 *op2 = op->next;
while (op2 != op)
{
result.push_back(op2->pt);
op2 = op2->next;
}
}
return result;
}