diff --git a/CPP/Clipper2Lib/include/clipper2/clipper.engine.h b/CPP/Clipper2Lib/include/clipper2/clipper.engine.h index d1d16ff9..00911fbe 100644 --- a/CPP/Clipper2Lib/include/clipper2/clipper.engine.h +++ b/CPP/Clipper2Lib/include/clipper2/clipper.engine.h @@ -321,10 +321,21 @@ namespace Clipper2Lib { Path64 polygon_; public: explicit PolyPath64(PolyPath64* parent = nullptr) : PolyPath(parent) {} + ~PolyPath64() { childs_.resize(0); } - PolyPath64* operator [] (size_t index) const { return childs_[index].get(); } const + + const PolyPath64* operator [] (size_t index) const + { + return childs_[index].get(); + } + + const PolyPath64* Child(size_t index) const + { + return childs_[index].get(); + } + PolyPath64List::const_iterator begin() const { return childs_.cbegin(); } PolyPath64List::const_iterator end() const { return childs_.cend(); } @@ -367,13 +378,21 @@ namespace Clipper2Lib { { inv_scale_ = parent ? parent->inv_scale_ : 1.0; } + ~PolyPathD() { childs_.resize(0); } - PolyPathD* operator [] (size_t index) + + const PolyPathD* operator [] (size_t index) const { return childs_[index].get(); } + + const PolyPathD* Child(size_t index) const + { + return childs_[index].get(); + } + PolyPathDList::const_iterator begin() const { return childs_.cbegin(); } PolyPathDList::const_iterator end() const { return childs_.cend(); } diff --git a/CSharp/Clipper2Lib/Clipper.Engine.cs b/CSharp/Clipper2Lib/Clipper.Engine.cs index 479185c6..c017d29f 100644 --- a/CSharp/Clipper2Lib/Clipper.Engine.cs +++ b/CSharp/Clipper2Lib/Clipper.Engine.cs @@ -3363,12 +3363,15 @@ public object Current }; - public bool IsHole => GetIsHole(); + public bool IsHole + { + get { return GetIsHole(); } + } public PolyPathBase(PolyPathBase? parent = null) { _parent = parent; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int Level() + private int GetLevel() { int result = 0; PolyPathBase? pp = _parent; @@ -3376,15 +3379,22 @@ public int Level() return result; } + public int Level + { + get { return GetLevel(); } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool GetIsHole() { - int lvl = Level(); + int lvl = GetLevel(); return lvl != 0 && (lvl & 1) == 0; } - public int Count => _childs.Count; - + public int Count + { + get { return _childs.Count; } + } internal abstract PolyPathBase AddChild(Path64 p); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -3409,16 +3419,24 @@ internal override PolyPathBase AddChild(Path64 p) return newChild; } - [IndexerName("Child")] public PolyPath64 this[int index] { - get { + get + { if (index < 0 || index >= _childs.Count) throw new InvalidOperationException(); - return (PolyPath64) _childs[index]; + return (PolyPath64) _childs[index]; } } + public PolyPath64 Child(int index) + { + if (index < 0 || index >= _childs.Count) + throw new InvalidOperationException(); + return (PolyPath64) _childs[index]; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public double Area() { diff --git a/Delphi/Clipper2Lib/Clipper.Engine.pas b/Delphi/Clipper2Lib/Clipper.Engine.pas index 177eef79..0f4c8560 100644 --- a/Delphi/Clipper2Lib/Clipper.Engine.pas +++ b/Delphi/Clipper2Lib/Clipper.Engine.pas @@ -311,6 +311,7 @@ TPolyPathBase = class FChildList : TList; function GetChildCnt: Integer; function GetIsHole: Boolean; + function GetLevel: Integer; protected function GetChild(index: Integer): TPolyPathBase; function AddChild(const path: TPath64): TPolyPathBase; virtual; abstract; @@ -323,6 +324,7 @@ TPolyPathBase = class property IsHole: Boolean read GetIsHole; property Count: Integer read GetChildCnt; property Child[index: Integer]: TPolyPathBase read GetChild; default; + property Level: Integer read GetLevel; end; TPolyPath64 = class(TPolyPathBase) @@ -1887,6 +1889,10 @@ procedure TClipperBase.CleanCollinear(outRec: POutRec); op2 := startOp; while true do begin + // trim if collinear AND one of + // a duplicate point OR + // not preserving collinear points OR + // is a 180 degree 'spike' if (CrossProduct(op2.prev.pt, op2.pt, op2.next.pt) = 0) and (PointsEqual(op2.pt,op2.prev.pt) or PointsEqual(op2.pt,op2.next.pt) or @@ -3870,21 +3876,28 @@ function TPolyPathBase.GetChild(index: Integer): TPolyPathBase; end; //------------------------------------------------------------------------------ -function TPolyPathBase.GetIsHole: Boolean; +function TPolyPathBase.GetLevel: Integer; var pp: TPolyPathBase; begin - pp := FParent; - result := assigned(pp); - if not Result then Exit; - while assigned(pp) do + Result := 0; + pp := Parent; + while Assigned(pp) do begin - result := not result; - pp := pp.FParent; + inc(Result); + pp := pp.Parent; end; end; //------------------------------------------------------------------------------ +function TPolyPathBase.GetIsHole: Boolean; +begin + if not Assigned(Parent) then + Result := false else + Result := not Odd(GetLevel); +end; +//------------------------------------------------------------------------------ + function TPolyPathBase.GetChildCnt: Integer; begin Result := FChildList.Count;