Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/upstream/main'
Browse files Browse the repository at this point in the history
* remotes/upstream/main:
  Minor tweak to CMakeLists.txt (AngusJohnson#754)
  Fixed a bug when offsetting, using delta callback, a path with a single point. (AngusJohnson#752) Minor code tidy (Delphi).
  • Loading branch information
jiajuncccc committed Dec 22, 2023
2 parents 05e4b68 + 76fa070 commit d47115a
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 103 deletions.
3 changes: 2 additions & 1 deletion CPP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ endif ()

include(GNUInstallDirs)
set(CLIPPER2_INC_FOLDER ${PROJECT_SOURCE_DIR}/Clipper2Lib/include/clipper2)
configure_file(clipper.version.in ${CLIPPER2_INC_FOLDER}/clipper.version.h)
configure_file(clipper.version.in
${CLIPPER2_INC_FOLDER}/clipper.version.h NEWLINE_STYLE UNIX)

set(CLIPPER2_INC
${CLIPPER2_INC_FOLDER}/clipper.h
Expand Down
10 changes: 5 additions & 5 deletions CPP/Clipper2Lib/include/clipper2/clipper.core.h
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ namespace Clipper2Lib
return Area<T>(poly) >= 0;
}

#if CLIPPER2_HI_PRECISION
#if CLIPPER2_HI_PRECISION
// caution: this will compromise performance
// https://github.com/AngusJohnson/Clipper2/issues/317#issuecomment-1314023253
// See also CPP/BenchMark/GetIntersectPtBenchmark.cpp
Expand All @@ -756,9 +756,9 @@ namespace Clipper2Lib
T bb1maxy = CC_MAX(ln2a.y, ln2b.y);
T originx = (CC_MIN(bb0maxx, bb1maxx) + CC_MAX(bb0minx, bb1minx)) >> 1;
T originy = (CC_MIN(bb0maxy, bb1maxy) + CC_MAX(bb0miny, bb1miny)) >> 1;
double ln0c = (ln1dy * static_cast<double>(ln1a.x - originx)) +
double ln0c = (ln1dy * static_cast<double>(ln1a.x - originx)) +
(ln1dx * static_cast<double>(ln1a.y - originy));
double ln1c = (ln2dy * static_cast<double>(ln2a.x - originx)) +
double ln1c = (ln2dy * static_cast<double>(ln2a.x - originx)) +
(ln2dx * static_cast<double>(ln2a.y - originy));
double hitx = ((ln1dx * ln1c) - (ln2dx * ln0c)) / det;
double hity = ((ln2dy * ln0c) - (ln1dy * ln1c)) / det;
Expand All @@ -774,7 +774,7 @@ namespace Clipper2Lib
}
return true;
}
#else
#else
template<typename T>
inline bool GetIntersectPoint(const Point<T>& ln1a, const Point<T>& ln1b,
const Point<T>& ln2a, const Point<T>& ln2b, Point<T>& ip)
Expand All @@ -788,7 +788,7 @@ namespace Clipper2Lib
double det = dy1 * dx2 - dy2 * dx1;
if (det == 0.0) return false;
double t = ((ln1a.x - ln2a.x) * dy2 - (ln1a.y - ln2a.y) * dx2) / det;
if (t <= 0.0) ip = ln1a;
if (t <= 0.0) ip = ln1a;
else if (t >= 1.0) ip = ln1b;
else
{
Expand Down
10 changes: 5 additions & 5 deletions CPP/Clipper2Lib/include/clipper2/clipper.engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ 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 JoinWith { None, Left, Right };

Expand Down Expand Up @@ -106,7 +106,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;
Expand Down Expand Up @@ -251,7 +251,7 @@ namespace Clipper2Lib {
void JoinOutrecPaths(Active &e1, Active &e2);
void FixSelfIntersects(OutRec* outrec);
void DoSplitOp(OutRec* outRec, OutPt* splitOp);

inline void AddTrialHorzJoin(OutPt* op);
void ConvertHorzSegsToJoins();
void ProcessHorzJoins();
Expand Down Expand Up @@ -331,7 +331,7 @@ namespace Clipper2Lib {
unsigned lvl = Level();
//Even levels except level 0
return lvl && !(lvl & 1);
}
}
};

typedef typename std::vector<std::unique_ptr<PolyPath64>> PolyPath64List;
Expand Down Expand Up @@ -420,7 +420,7 @@ namespace Clipper2Lib {

void SetScale(double value) { scale_ = value; }
double Scale() const { return scale_; }

PolyPathD* AddChild(const Path64& path) override
{
int error_code = 0;
Expand Down
21 changes: 14 additions & 7 deletions CPP/Clipper2Lib/src/clipper.offset.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 28 November 2023 *
* Date : 21 December 2023 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Purpose : Path Offset (Inflate/Shrink) *
Expand Down Expand Up @@ -67,7 +67,7 @@ int GetLowestClosedPathIdx(std::vector<Rect64>& boundsList)
int i = -1, result = -1;
Point64 botPt = Point64(INT64_MAX, INT64_MIN);
for (const Rect64& r : boundsList)
{
{
++i;
if (!r.IsValid()) continue; // ignore invalid paths
else if (r.bottom > botPt.y || (r.bottom == botPt.y && r.left < botPt.x))
Expand Down Expand Up @@ -103,7 +103,7 @@ inline double Hypot(double x, double y)
}

inline PointD NormalizeVector(const PointD& vec)
{
{
double h = Hypot(vec.x, vec.y);
if (AlmostZero(h)) return PointD(0,0);
double inverseHypot = 1 / h;
Expand Down Expand Up @@ -358,7 +358,7 @@ void ClipperOffset::OffsetPoint(Group& group, const Path64& path, size_t j, size
// is concave
path_out.push_back(GetPerpendic(path[j], norms[k], group_delta_));
// this extra point is the only (simple) way to ensure that
// path reversals are fully cleaned with the trailing clipper
// path reversals are fully cleaned with the trailing clipper
path_out.push_back(path[j]); // (#405)
path_out.push_back(GetPerpendic(path[j], norms[j], group_delta_));
}
Expand Down Expand Up @@ -394,7 +394,7 @@ void ClipperOffset::OffsetOpenJoined(Group& group, const Path64& path)
OffsetPolygon(group, path);
Path64 reverse_path(path);
std::reverse(reverse_path.begin(), reverse_path.end());

//rebuild normals // BuildNormals(path);
std::reverse(norms.begin(), norms.end());
norms.push_back(norms[0]);
Expand All @@ -408,7 +408,7 @@ void ClipperOffset::OffsetOpenPath(Group& group, const Path64& path)
{
// do the line start cap
if (deltaCallback64_) group_delta_ = deltaCallback64_(path, norms, 0, 0);

if (std::fabs(group_delta_) <= floating_point_tolerance)
path_out.push_back(path[0]);
else
Expand All @@ -426,7 +426,7 @@ void ClipperOffset::OffsetOpenPath(Group& group, const Path64& path)
break;
}
}

size_t highI = path.size() - 1;
// offset the left side going forward
for (Path64::size_type j = 1, k = 0; j < highI; k = j, ++j)
Expand Down Expand Up @@ -516,6 +516,13 @@ void ClipperOffset::DoGroupOffset(Group& group)

if (pathLen == 1) // single point
{
if (deltaCallback64_)
{
group_delta_ = deltaCallback64_(*path_in_it, norms, 0, 0);
if (group.is_reversed) group_delta_ = -group_delta_;
abs_delta = std::fabs(group_delta_);
}

if (group_delta_ < 1) continue;
const Point64& pt = (*path_in_it)[0];
//single vertex so build a circle or square ...
Expand Down
25 changes: 20 additions & 5 deletions CSharp/Clipper2Lib/Clipper.Offset.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 28 November 2023 *
* Date : 21 December 2023 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Purpose : Path Offset (Inflate/Shrink) *
Expand Down Expand Up @@ -442,13 +442,21 @@ private void DoBevel(Path64 path, int j, int k)
if (j == k)
{
double absDelta = Math.Abs(_groupDelta);
pt1 = new Point64(path[j].X - absDelta * _normals[j].x, path[j].Y - absDelta * _normals[j].y);
pt2 = new Point64(path[j].X + absDelta * _normals[j].x, path[j].Y + absDelta * _normals[j].y);
pt1 = new Point64(
path[j].X - absDelta * _normals[j].x,
path[j].Y - absDelta * _normals[j].y);
pt2 = new Point64(
path[j].X + absDelta * _normals[j].x,
path[j].Y + absDelta * _normals[j].y);
}
else
{
pt1 = new Point64(path[j].X + _groupDelta * _normals[k].x, path[j].Y + _groupDelta * _normals[k].y);
pt2 = new Point64(path[j].X + _groupDelta * _normals[j].x, path[j].Y + _groupDelta * _normals[j].y);
pt1 = new Point64(
path[j].X + _groupDelta * _normals[k].x,
path[j].Y + _groupDelta * _normals[k].y);
pt2 = new Point64(
path[j].X + _groupDelta * _normals[j].x,
path[j].Y + _groupDelta * _normals[j].y);
}
pathOut.Add(pt1);
pathOut.Add(pt2);
Expand Down Expand Up @@ -779,6 +787,13 @@ private void DoGroupOffset(Group group)
{
Point64 pt = p[0];

if (DeltaCallback != null)
{
_groupDelta = DeltaCallback(p, _normals, 0, 0);
if (group.pathsReversed) _groupDelta = -_groupDelta;
absDelta = Math.Abs(_groupDelta);
}

// single vertex so build a circle or square ...
if (group.endType == EndType.Round)
{
Expand Down
35 changes: 34 additions & 1 deletion Delphi/Clipper2Lib/Clipper.Core.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

(*******************************************************************************
* Author : Angus Johnson *
* Date : 5 November 2023 *
* Date : 21 December 2023 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Purpose : Core Clipper Library module *
Expand Down Expand Up @@ -337,6 +337,11 @@ procedure QuickSort(SortList: TPointerList;

procedure CheckPrecisionRange(var precision: integer);

function Iif(eval: Boolean; trueVal, falseVal: Boolean): Boolean; overload;
function Iif(eval: Boolean; trueVal, falseVal: integer): integer; overload;
function Iif(eval: Boolean; trueVal, falseVal: Int64): Int64; overload;
function Iif(eval: Boolean; trueVal, falseVal: double): double; overload;

const
MaxInt64 = 9223372036854775807;
MinInt64 = -MaxInt64;
Expand Down Expand Up @@ -655,6 +660,34 @@ procedure TListEx.Swap(idx1, idx2: integer);
// Miscellaneous Functions ...
//------------------------------------------------------------------------------

function Iif(eval: Boolean; trueVal, falseVal: Boolean): Boolean;
{$IFDEF INLINING} inline; {$ENDIF}
begin
if eval then Result := trueVal else Result := falseVal;
end;
//------------------------------------------------------------------------------

function Iif(eval: Boolean; trueVal, falseVal: integer): integer;
{$IFDEF INLINING} inline; {$ENDIF}
begin
if eval then Result := trueVal else Result := falseVal;
end;
//------------------------------------------------------------------------------

function Iif(eval: Boolean; trueVal, falseVal: Int64): Int64;
{$IFDEF INLINING} inline; {$ENDIF}
begin
if eval then Result := trueVal else Result := falseVal;
end;
//------------------------------------------------------------------------------

function Iif(eval: Boolean; trueVal, falseVal: double): double;
{$IFDEF INLINING} inline; {$ENDIF}
begin
if eval then Result := trueVal else Result := falseVal;
end;
//------------------------------------------------------------------------------

procedure CheckPrecisionRange(var precision: integer);
begin
if (precision < -MaxDecimalPrecision) or (precision > MaxDecimalPrecision) then
Expand Down
57 changes: 22 additions & 35 deletions Delphi/Clipper2Lib/Clipper.Engine.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

(*******************************************************************************
* Author : Angus Johnson *
* Date : 1 December 2023 *
* Date : 21 December 2023 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2023 *
* Purpose : This is the main polygon clipping module *
Expand Down Expand Up @@ -1721,23 +1721,18 @@ procedure TClipperBase.SetWindCountForClosedPathEdge(e: PActive);
if (Abs(e2.windCnt) > 1) then
begin
// outside prev poly but still inside another.
if (e2.windDx * e.windDx < 0) then
// reversing direction so use the same WC
e.windCnt := e2.windCnt else
// otherwise keep 'reducing' the WC by 1 (ie towards 0) ...
e.windCnt := e2.windCnt + e.windDx;
e.windCnt := Iif(e2.windDx * e.windDx < 0,
e2.windCnt, // reversing direction so use the same WC
e2.windCnt + e.windDx);
end
// now outside all polys of same polytype so set own WC ...
else e.windCnt := e.windDx;
end else
begin
//'e' must be inside 'e2'
if (e2.windDx * e.windDx < 0) then
// reversing direction so use the same WC
e.windCnt := e2.windCnt
else
// otherwise keep 'increasing' the WC by 1 (ie away from 0) ...
e.windCnt := e2.windCnt + e.windDx;
e.windCnt := Iif(e2.windDx * e.windDx < 0,
e2.windCnt, // reversing direction so use the same WC
e2.windCnt + e.windDx); // else keep 'increasing' the WC
end;
e.windCnt2 := e2.windCnt2;
e2 := e2.nextInAEL;
Expand Down Expand Up @@ -1778,8 +1773,8 @@ procedure TClipperBase.SetWindCountForOpenPathEdge(e: PActive);
else if not IsOpen(e2) then inc(cnt1);
e2 := e2.nextInAEL;
end;
if Odd(cnt1) then e.windCnt := 1 else e.windCnt := 0;
if Odd(cnt2) then e.windCnt2 := 1 else e.windCnt2 := 0;
e.windCnt := Iif(Odd(cnt1), 1, 0);
e.windCnt2 := Iif(Odd(cnt2), 1, 0);
end else
begin
// if FClipType in [ctUnion, ctDifference] then e.WindCnt := e.WindDx;
Expand Down Expand Up @@ -2637,12 +2632,10 @@ function TClipperBase.IntersectEdges(e1, e2: PActive; pt: TPoint64): POutPt;
e2.windCnt := e1WindCnt;
end else
begin
if e1.windCnt + e2.windDx = 0 then
e1.windCnt := -e1.windCnt else
Inc(e1.windCnt, e2.windDx);
if e2.windCnt - e1.windDx = 0 then
e2.windCnt := -e2.windCnt else
Dec(e2.windCnt, e1.windDx);
e1.windCnt := Iif(e1.windCnt + e2.windDx = 0,
-e1.windCnt, e1.windCnt + e2.windDx);
e2.windCnt := Iif(e2.windCnt - e1.windDx = 0,
-e2.windCnt, e2.windCnt - e1.windDx);
end;
end else
begin
Expand Down Expand Up @@ -2909,14 +2902,14 @@ function HorzontalsOverlap(const horz1a, horz1b, horz2a, horz2b: TPoint64): bool
begin
if horz1a.X < horz1b.X then
begin
if horz2a.X < horz2b.X then
Result := HorzOverlapWithLRSet(horz1a, horz1b, horz2a, horz2b) else
Result := HorzOverlapWithLRSet(horz1a, horz1b, horz2b, horz2a);
Result := Iif(horz2a.X < horz2b.X,
HorzOverlapWithLRSet(horz1a, horz1b, horz2a, horz2b),
HorzOverlapWithLRSet(horz1a, horz1b, horz2b, horz2a));
end else
begin
if horz2a.X < horz2b.X then
Result := HorzOverlapWithLRSet(horz1b, horz1a, horz2a, horz2b) else
Result := HorzOverlapWithLRSet(horz1b, horz1a, horz2b, horz2a);
Result := Iif(horz2a.X < horz2b.X,
HorzOverlapWithLRSet(horz1b, horz1a, horz2a, horz2b),
HorzOverlapWithLRSet(horz1b, horz1a, horz2b, horz2a));
end;
end;
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -3175,12 +3168,8 @@ procedure TClipperBase.AddNewIntersectNode(e1, e2: PActive; topY: Int64);
ip := GetClosestPointOnSegment(ip, e2.bot, e2.top)
else
begin
if (ip.Y < topY) then
ip.Y := topY else
ip.Y := fBotY;
if (absDx1 < absDx2) then
ip.X := TopX(e1, ip.Y) else
ip.X := TopX(e2, ip.Y);
ip.Y := Iif(ip.Y < topY, topY , fBotY);
ip.X := Iif(absDx1 < absDx2, TopX(e1, ip.Y), TopX(e2, ip.Y));
end;
end;
new(node);
Expand Down Expand Up @@ -4031,9 +4020,7 @@ function TPolyPathBase.GetLevel: Integer;

function TPolyPathBase.GetIsHole: Boolean;
begin
if not Assigned(Parent) then
Result := false else
Result := not Odd(GetLevel);
Result := Iif(Assigned(Parent), not Odd(GetLevel), false);
end;
//------------------------------------------------------------------------------

Expand Down
Loading

0 comments on commit d47115a

Please sign in to comment.