Skip to content

Commit a9de651

Browse files
committed
Improved PolyTree access.
1 parent a8df94a commit a9de651

File tree

3 files changed

+67
-17
lines changed

3 files changed

+67
-17
lines changed

CPP/Clipper2Lib/include/clipper2/clipper.engine.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,21 @@ namespace Clipper2Lib {
321321
Path64 polygon_;
322322
public:
323323
explicit PolyPath64(PolyPath64* parent = nullptr) : PolyPath(parent) {}
324+
324325
~PolyPath64() {
325326
childs_.resize(0);
326327
}
327-
PolyPath64* operator [] (size_t index) const { return childs_[index].get(); } const
328+
329+
const PolyPath64* operator [] (size_t index) const
330+
{
331+
return childs_[index].get();
332+
}
333+
334+
const PolyPath64* Child(size_t index) const
335+
{
336+
return childs_[index].get();
337+
}
338+
328339
PolyPath64List::const_iterator begin() const { return childs_.cbegin(); }
329340
PolyPath64List::const_iterator end() const { return childs_.cend(); }
330341

@@ -367,13 +378,21 @@ namespace Clipper2Lib {
367378
{
368379
inv_scale_ = parent ? parent->inv_scale_ : 1.0;
369380
}
381+
370382
~PolyPathD() {
371383
childs_.resize(0);
372384
}
373-
PolyPathD* operator [] (size_t index)
385+
386+
const PolyPathD* operator [] (size_t index) const
374387
{
375388
return childs_[index].get();
376389
}
390+
391+
const PolyPathD* Child(size_t index) const
392+
{
393+
return childs_[index].get();
394+
}
395+
377396
PolyPathDList::const_iterator begin() const { return childs_.cbegin(); }
378397
PolyPathDList::const_iterator end() const { return childs_.cend(); }
379398

CSharp/Clipper2Lib/Clipper.Engine.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3363,28 +3363,38 @@ public object Current
33633363

33643364
};
33653365

3366-
public bool IsHole => GetIsHole();
3366+
public bool IsHole
3367+
{
3368+
get { return GetIsHole(); }
3369+
}
33673370

33683371
public PolyPathBase(PolyPathBase? parent = null) { _parent = parent; }
33693372

33703373
[MethodImpl(MethodImplOptions.AggressiveInlining)]
3371-
public int Level()
3374+
private int GetLevel()
33723375
{
33733376
int result = 0;
33743377
PolyPathBase? pp = _parent;
33753378
while (pp != null) { ++result; pp = pp._parent; }
33763379
return result;
33773380
}
33783381

3382+
public int Level
3383+
{
3384+
get { return GetLevel(); }
3385+
}
3386+
33793387
[MethodImpl(MethodImplOptions.AggressiveInlining)]
33803388
private bool GetIsHole()
33813389
{
3382-
int lvl = Level();
3390+
int lvl = GetLevel();
33833391
return lvl != 0 && (lvl & 1) == 0;
33843392
}
33853393

3386-
public int Count => _childs.Count;
3387-
3394+
public int Count
3395+
{
3396+
get { return _childs.Count; }
3397+
}
33883398
internal abstract PolyPathBase AddChild(Path64 p);
33893399

33903400
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -3409,16 +3419,24 @@ internal override PolyPathBase AddChild(Path64 p)
34093419
return newChild;
34103420
}
34113421

3412-
[IndexerName("Child")]
34133422
public PolyPath64 this[int index]
34143423
{
3415-
get {
3424+
get
3425+
{
34163426
if (index < 0 || index >= _childs.Count)
34173427
throw new InvalidOperationException();
3418-
return (PolyPath64) _childs[index];
3428+
return (PolyPath64) _childs[index];
34193429
}
34203430
}
34213431

3432+
public PolyPath64 Child(int index)
3433+
{
3434+
if (index < 0 || index >= _childs.Count)
3435+
throw new InvalidOperationException();
3436+
return (PolyPath64) _childs[index];
3437+
}
3438+
3439+
34223440
[MethodImpl(MethodImplOptions.AggressiveInlining)]
34233441
public double Area()
34243442
{

Delphi/Clipper2Lib/Clipper.Engine.pas

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ TPolyPathBase = class
311311
FChildList : TList;
312312
function GetChildCnt: Integer;
313313
function GetIsHole: Boolean;
314+
function GetLevel: Integer;
314315
protected
315316
function GetChild(index: Integer): TPolyPathBase;
316317
function AddChild(const path: TPath64): TPolyPathBase; virtual; abstract;
@@ -323,6 +324,7 @@ TPolyPathBase = class
323324
property IsHole: Boolean read GetIsHole;
324325
property Count: Integer read GetChildCnt;
325326
property Child[index: Integer]: TPolyPathBase read GetChild; default;
327+
property Level: Integer read GetLevel;
326328
end;
327329

328330
TPolyPath64 = class(TPolyPathBase)
@@ -1887,6 +1889,10 @@ procedure TClipperBase.CleanCollinear(outRec: POutRec);
18871889
op2 := startOp;
18881890
while true do
18891891
begin
1892+
// trim if collinear AND one of
1893+
// a duplicate point OR
1894+
// not preserving collinear points OR
1895+
// is a 180 degree 'spike'
18901896
if (CrossProduct(op2.prev.pt, op2.pt, op2.next.pt) = 0) and
18911897
(PointsEqual(op2.pt,op2.prev.pt) or
18921898
PointsEqual(op2.pt,op2.next.pt) or
@@ -3870,21 +3876,28 @@ function TPolyPathBase.GetChild(index: Integer): TPolyPathBase;
38703876
end;
38713877
//------------------------------------------------------------------------------
38723878

3873-
function TPolyPathBase.GetIsHole: Boolean;
3879+
function TPolyPathBase.GetLevel: Integer;
38743880
var
38753881
pp: TPolyPathBase;
38763882
begin
3877-
pp := FParent;
3878-
result := assigned(pp);
3879-
if not Result then Exit;
3880-
while assigned(pp) do
3883+
Result := 0;
3884+
pp := Parent;
3885+
while Assigned(pp) do
38813886
begin
3882-
result := not result;
3883-
pp := pp.FParent;
3887+
inc(Result);
3888+
pp := pp.Parent;
38843889
end;
38853890
end;
38863891
//------------------------------------------------------------------------------
38873892

3893+
function TPolyPathBase.GetIsHole: Boolean;
3894+
begin
3895+
if not Assigned(Parent) then
3896+
Result := false else
3897+
Result := not Odd(GetLevel);
3898+
end;
3899+
//------------------------------------------------------------------------------
3900+
38883901
function TPolyPathBase.GetChildCnt: Integer;
38893902
begin
38903903
Result := FChildList.Count;

0 commit comments

Comments
 (0)