Skip to content

Commit

Permalink
Reversed LINQ dependency in C# code
Browse files Browse the repository at this point in the history
  • Loading branch information
AngusJohnson committed Oct 9, 2024
1 parent 907d1fd commit 2b665ac
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 98 deletions.
21 changes: 15 additions & 6 deletions CSharp/Clipper2Lib/Clipper.Core.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 17 September 2024 *
* Date : 10 October 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : Core structures and functions for the Clipper Library *
Expand All @@ -10,7 +10,6 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Clipper2Lib
Expand Down Expand Up @@ -479,7 +478,9 @@ public Path64(int capacity = 0) : base(capacity) { }
public Path64(IEnumerable<Point64> path) : base(path) { }
public override string ToString()
{
string s = this.Aggregate("", (current, p) => current + p.ToString() + ", ");
string s = "";
foreach (Point64 p in this)
s = s + p.ToString() + ", ";
if (s != "") s = s.Remove(s.Length - 2);
return s;
}
Expand All @@ -492,7 +493,10 @@ public Paths64(int capacity = 0) : base(capacity) { }
public Paths64(IEnumerable<Path64> paths) : base(paths) { }
public override string ToString()
{
return this.Aggregate("", (current, p) => current + p + "\n");
string s = "";
foreach (Path64 p in this)
s = s + p + "\n";
return s;
}
}

Expand All @@ -503,7 +507,9 @@ public PathD(int capacity = 0) : base(capacity) { }
public PathD(IEnumerable<PointD> path) : base(path) { }
public string ToString(int precision = 2)
{
string s = this.Aggregate("", (current, p) => current + p.ToString(precision) + ", ");
string s = "";
foreach (PointD p in this)
s = s + p.ToString(precision) + ", ";
if (s != "") s = s.Remove(s.Length - 2);
return s;
}
Expand All @@ -516,7 +522,10 @@ public PathsD(int capacity = 0) : base(capacity) { }
public PathsD(IEnumerable<PathD> paths) : base(paths) { }
public string ToString(int precision = 2)
{
return this.Aggregate("", (current, p) => current + p.ToString(precision) + "\n");
string s = "";
foreach (PathD p in this)
s = s + p.ToString(precision) + "\n";
return s;
}
}

Expand Down
40 changes: 29 additions & 11 deletions CSharp/Clipper2Lib/Clipper.Engine.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 17 September 2024 *
* Date : 10 October 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : This is the main polygon clipping module *
Expand All @@ -13,7 +13,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Clipper2Lib
Expand Down Expand Up @@ -236,7 +235,8 @@ internal static void EnsureCapacity<T>(this List<T> list, int minCapacity)
internal static void AddPathsToVertexList(Paths64 paths, PathType polytype, bool isOpen,
List<LocalMinima> minimaList, List<Vertex> vertexList)
{
int totalVertCnt = paths.Sum(path => path.Count);
int totalVertCnt = 0;
foreach (Path64 path in paths) totalVertCnt += path.Count;
vertexList.EnsureCapacity(vertexList.Count + totalVertCnt);

foreach (Path64 path in paths)
Expand Down Expand Up @@ -2528,7 +2528,9 @@ private static int HorzSegSort(HorzSegment? hs1, HorzSegment? hs2)

private void ConvertHorzSegsToJoins()
{
int k = _horzSegList.Count(UpdateHorzSegment);
int k = 0;
foreach (HorzSegment hs in _horzSegList)
if (UpdateHorzSegment(hs)) k++;
if (k < 2) return;
_horzSegList.Sort(HorzSegSort);

Expand Down Expand Up @@ -3032,8 +3034,10 @@ private bool CheckBounds(OutRec outrec)

private bool CheckSplitOwner(OutRec outrec, List<int>? splits)
{
foreach (OutRec? split in splits!.Select(i => GetRealOutRec(_outrecList[i])).OfType<OutRec>().Where(split => split != outrec && split.recursiveSplit != outrec))
foreach (int i in splits!)
{
OutRec? split = GetRealOutRec(_outrecList[i]);
if (split == null || split == outrec || split.recursiveSplit == outrec) continue;
split.recursiveSplit = outrec; //#599
if (split.splits != null && CheckSplitOwner(outrec, split.splits)) return true;
if (!IsValidOwner(outrec, split) ||
Expand All @@ -3043,7 +3047,6 @@ private bool CheckSplitOwner(OutRec outrec, List<int>? splits)
outrec.owner = split; //found in split
return true;
}

return false;
}
private void RecursiveCheckOwners(OutRec outrec, PolyPathBase polypath)
Expand Down Expand Up @@ -3343,9 +3346,11 @@ public bool Execute(ClipType clipType, FillRule fillRule,
if (!success) return false;

solutionClosed.EnsureCapacity(solClosed64.Count);
solutionClosed.AddRange(solClosed64.Select(path => Clipper.ScalePathD(path, _invScale)));
foreach (Path64 path in solClosed64)
solutionClosed.Add(Clipper.ScalePathD(path, _invScale));
solutionOpen.EnsureCapacity(solOpen64.Count);
solutionOpen.AddRange(solOpen64.Select(path => Clipper.ScalePathD(path, _invScale)));
foreach (Path64 path in solOpen64)
solutionOpen.Add(Clipper.ScalePathD(path, _invScale));

return true;
}
Expand Down Expand Up @@ -3380,7 +3385,8 @@ public bool Execute(ClipType clipType, FillRule fillRule, PolyTreeD polytree, Pa
if (!success) return false;
if (oPaths.Count <= 0) return true;
openPaths.EnsureCapacity(oPaths.Count);
openPaths.AddRange(oPaths.Select(path => Clipper.ScalePathD(path, _invScale)));
foreach (Path64 path in oPaths)
openPaths.Add(Clipper.ScalePathD(path, _invScale));

return true;
}
Expand Down Expand Up @@ -3534,7 +3540,13 @@ public PolyPath64 Child(int index)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public double Area()
{
return (Polygon == null ? 0 : Clipper.Area(Polygon)) + _childs.Cast<PolyPath64>().Sum(child => child.Area());
double result = Polygon == null ? 0 : Clipper.Area(Polygon);
foreach (PolyPathBase polyPathBase in _childs)
{
PolyPath64 child = (PolyPath64) polyPathBase;
result += child.Area();
}
return result;
}
}
public class PolyPathD : PolyPathBase
Expand Down Expand Up @@ -3577,7 +3589,13 @@ public PolyPathD this[int index]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public double Area()
{
return (Polygon == null ? 0 : Clipper.Area(Polygon)) + _childs.Cast<PolyPathD>().Sum(child => child.Area());
double result = Polygon == null ? 0 : Clipper.Area(Polygon);
foreach (PolyPathBase polyPathBase in _childs)
{
PolyPathD child = (PolyPathD) polyPathBase;
result += child.Area();
}
return result;
}
}

Expand Down
11 changes: 6 additions & 5 deletions CSharp/Clipper2Lib/Clipper.Minkowski.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 15 October 2022 *
* Date : 10 October 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2022 *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : Minkowski Sum and Difference *
* License : http://www.boost.org/LICENSE_1_0.txt *
*******************************************************************************/

#nullable enable
using System;
using System.Linq;

namespace Clipper2Lib
{
Expand All @@ -26,11 +25,13 @@ private static Paths64 MinkowskiInternal(Path64 pattern, Path64 path, bool isSum
Path64 path2 = new Path64(patLen);
if (isSum)
{
path2.AddRange(pattern.Select(basePt => pathPt + basePt));
foreach (Point64 basePt in pattern)
path2.Add(pathPt + basePt);
}
else
{
path2.AddRange(pattern.Select(basePt => pathPt - basePt));
foreach (Point64 basePt in pattern)
path2.Add(pathPt - basePt);
}
tmp.Add(path2);
}
Expand Down
27 changes: 19 additions & 8 deletions CSharp/Clipper2Lib/Clipper.Offset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Clipper2Lib
Expand Down Expand Up @@ -141,12 +140,22 @@ public void AddPaths(Paths64 paths, JoinType joinType, EndType endType)

private int CalcSolutionCapacity()
{
return _groupList.Sum(g => (g.endType == EndType.Joined) ? g.inPaths.Count * 2 : g.inPaths.Count);
int result = 0;
foreach (Group g in _groupList)
result += (g.endType == EndType.Joined) ? g.inPaths.Count * 2 : g.inPaths.Count;
return result;
}

internal bool CheckPathsReversed()
{
return (from g in _groupList where g.endType == EndType.Polygon select g.pathsReversed).FirstOrDefault();
bool result = false;
foreach (Group g in _groupList)
if (g.endType == EndType.Polygon)
{
result = g.pathsReversed;
break;
}
return result;
}

private void ExecuteInternal(double delta)
Expand All @@ -157,8 +166,9 @@ private void ExecuteInternal(double delta)
// make sure the offset delta is significant
if (Math.Abs(delta) < 0.5)
{
foreach (Path64 path in _groupList.SelectMany(group => group.inPaths))
_solution.Add(path);
foreach (Group group in _groupList)
foreach (Path64 path in group.inPaths)
_solution.Add(path);
return;
}

Expand Down Expand Up @@ -230,9 +240,10 @@ internal static int GetLowestPathIdx(Paths64 paths)
Point64 botPt = new Point64(long.MaxValue, long.MinValue);
for (int i = 0; i < paths.Count; ++i)
{
foreach (Point64 pt in paths[i].Where(pt => (pt.Y >= botPt.Y) &&
((pt.Y != botPt.Y) || (pt.X < botPt.X))))
{
foreach (Point64 pt in paths[i])
{
if ((pt.Y < botPt.Y) ||
((pt.Y == botPt.Y) && (pt.X >= botPt.X))) continue;
result = i;
botPt.X = pt.X;
botPt.Y = pt.Y;
Expand Down
28 changes: 20 additions & 8 deletions CSharp/Clipper2Lib/Clipper.RectClip.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*******************************************************************************
* Author : Angus Johnson *
* Date : 5 July 2024 *
* Date : 10 October 2024 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2024 *
* Purpose : FAST rectangular clipping *
Expand All @@ -10,7 +10,6 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Clipper2Lib
Expand Down Expand Up @@ -92,8 +91,10 @@ private static bool Path1ContainsPath2(Path64 path1, Path64 path2)
// nb: occasionally, due to rounding, path1 may
// appear (momentarily) inside or outside path2.
int ioCount = 0;
foreach (PointInPolygonResult pip in path2.Select(pt => InternalClipper.PointInPolygon(pt, path1)))
foreach (Point64 pt in path2)
{
PointInPolygonResult pip =
InternalClipper.PointInPolygon(pt, path1);
switch(pip)
{
case PointInPolygonResult.IsInside:
Expand Down Expand Up @@ -636,8 +637,9 @@ private void ExecuteInternal(Path64 path)
if (startLocs.Count > 0)
{
prev = loc;
foreach (Location loc2 in startLocs.Where(loc2 => prev != loc2))
foreach (Location loc2 in startLocs)
{
if (prev == loc2) continue;
AddCorner(ref prev, HeadingClockwise(prev, loc2));
prev = loc2;
}
Expand All @@ -652,8 +654,9 @@ public Paths64 Execute(Paths64 paths)
{
Paths64 result = new Paths64();
if (rect_.IsEmpty()) return result;
foreach (Path64 path in paths.Where(path => path.Count >= 3))
foreach (Path64 path in paths)
{
if (path.Count < 3) continue;
pathBounds_ = Clipper.GetBounds(path);
if (!rect_.Intersects(pathBounds_))
continue; // the path must be completely outside fRect
Expand All @@ -668,7 +671,11 @@ public Paths64 Execute(Paths64 paths)
for (int i = 0; i < 4; ++i)
TidyEdgePair(i, edges_[i * 2], edges_[i * 2 + 1]);

result.AddRange(results_.Select(GetPath).Where(tmp => tmp.Count > 0));
foreach (OutPt2? op in results_)
{
Path64 tmp = GetPath(op);
if (tmp.Count > 0) result.Add(tmp);
}

//clean up after every loop
results_.Clear();
Expand Down Expand Up @@ -955,8 +962,9 @@ internal RectClipLines64(Rect64 rect) : base(rect) { }
{
Paths64 result = new Paths64();
if (rect_.IsEmpty()) return result;
foreach (Path64 path in paths.Where(path => path.Count >= 2))
foreach (Path64 path in paths)
{
if (path.Count < 2) continue;
pathBounds_ = Clipper.GetBounds(path);
if (!rect_.Intersects(pathBounds_))
continue; // the path must be completely outside fRect
Expand All @@ -965,7 +973,11 @@ internal RectClipLines64(Rect64 rect) : base(rect) { }
// fRect, simply by comparing path bounds with fRect.
ExecuteInternal(path);

result.AddRange(results_.Select(GetPath).Where(tmp => tmp.Count > 0));
foreach (OutPt2? op in results_)
{
Path64 tmp = GetPath(op);
if (tmp.Count > 0) result.Add(tmp);
}

//clean up after every loop
results_.Clear();
Expand Down
Loading

0 comments on commit 2b665ac

Please sign in to comment.