@@ -145,6 +145,7 @@ internal enum HorzPosition { Bottom, Middle, Top }
145145 internal class OutRec
146146 {
147147 public int idx ;
148+ public int outPtCount ;
148149 public OutRec ? owner ;
149150 public Active ? frontEdge ;
150151 public Active ? backEdge ;
@@ -355,13 +356,15 @@ public class ClipperBase
355356 private FillRule _fillrule ;
356357 private Active ? _actives ;
357358 private Active ? _sel ;
359+ private Stack < Active > _freeActives ;
358360 private readonly List < LocalMinima > _minimaList ;
359361 private readonly List < IntersectNode > _intersectList ;
360362 private readonly VertexPoolList _vertexList ;
361- private readonly List < OutRec > _outrecList ;
363+ private readonly OutRecPoolList _outrecList ;
362364 private readonly List < long > _scanlineList ;
363365 private readonly List < HorzSegment > _horzSegList ;
364- private readonly List < HorzJoin > _horzJoinList ;
366+ private readonly HorzJoinPoolList _horzJoinList ;
367+ private readonly OutPtPoolList _outPtPool ;
365368 private int _currentLocMin ;
366369 private long _currentBotY ;
367370 private bool _isSortedMinimaList ;
@@ -383,10 +386,12 @@ public ClipperBase()
383386 _minimaList = new List < LocalMinima > ( ) ;
384387 _intersectList = new List < IntersectNode > ( ) ;
385388 _vertexList = new VertexPoolList ( ) ;
386- _outrecList = new List < OutRec > ( ) ;
389+ _outrecList = new OutRecPoolList ( ) ;
387390 _scanlineList = new List < long > ( ) ;
388391 _horzSegList = new List < HorzSegment > ( ) ;
389- _horzJoinList = new List < HorzJoin > ( ) ;
392+ _horzJoinList = new HorzJoinPoolList ( ) ;
393+ _outPtPool = new OutPtPoolList ( ) ;
394+ _freeActives = new Stack < Active > ( ) ;
390395 PreserveCollinear = true ;
391396 }
392397
@@ -760,6 +765,8 @@ protected void ClearSolutionOnly()
760765 _outrecList . Clear ( ) ;
761766 _horzSegList . Clear ( ) ;
762767 _horzJoinList . Clear ( ) ;
768+ _outPtPool . Clear ( ) ;
769+ _freeActives . Clear ( ) ;
763770 }
764771
765772 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -1164,16 +1171,14 @@ private void InsertLocalMinimaIntoAEL(long botY)
11641171 }
11651172 else
11661173 {
1167- leftBound = new Active
1168- {
1169- bot = localMinima . vertex . pt ,
1170- curX = localMinima . vertex . pt . X ,
1171- windDx = - 1 ,
1172- vertexTop = localMinima . vertex . prev ,
1173- top = localMinima . vertex . prev ! . pt ,
1174- outrec = null ,
1175- localMin = localMinima
1176- } ;
1174+ leftBound = NewActive ( ) ;
1175+ leftBound . bot = localMinima . vertex . pt ;
1176+ leftBound . curX = localMinima . vertex . pt . X ;
1177+ leftBound . windDx = - 1 ;
1178+ leftBound . vertexTop = localMinima . vertex . prev ;
1179+ leftBound . top = localMinima . vertex . prev ! . pt ;
1180+ leftBound . outrec = null ;
1181+ leftBound . localMin = localMinima ;
11771182 SetDx ( leftBound ) ;
11781183 }
11791184
@@ -1184,16 +1189,14 @@ private void InsertLocalMinimaIntoAEL(long botY)
11841189 }
11851190 else
11861191 {
1187- rightBound = new Active
1188- {
1189- bot = localMinima . vertex . pt ,
1190- curX = localMinima . vertex . pt . X ,
1191- windDx = 1 ,
1192- vertexTop = localMinima . vertex . next , // i.e. ascending
1193- top = localMinima . vertex . next ! . pt ,
1194- outrec = null ,
1195- localMin = localMinima
1196- } ;
1192+ rightBound = NewActive ( ) ;
1193+ rightBound . bot = localMinima . vertex . pt ;
1194+ rightBound . curX = localMinima . vertex . pt . X ;
1195+ rightBound . windDx = 1 ;
1196+ rightBound . vertexTop = localMinima . vertex . next ; // i.e. ascending
1197+ rightBound . top = localMinima . vertex . next ! . pt ;
1198+ rightBound . outrec = null ;
1199+ rightBound . localMin = localMinima ;
11971200 SetDx ( rightBound ) ;
11981201 }
11991202
@@ -1333,7 +1336,7 @@ private OutPt AddLocalMinPoly(Active ae1, Active ae2, Point64 pt, bool isNew = f
13331336 }
13341337 }
13351338
1336- OutPt op = new OutPt ( pt , outrec ) ;
1339+ OutPt op = _outPtPool . Add ( pt , outrec ) ;
13371340 outrec . pts = op ;
13381341 return op ;
13391342 }
@@ -1427,6 +1430,7 @@ private static void JoinOutrecPaths(Active ae1, Active ae2)
14271430 ae2 . outrec . frontEdge = null ;
14281431 ae2 . outrec . backEdge = null ;
14291432 ae2 . outrec . pts = null ;
1433+ ae1 . outrec . outPtCount += ae2 . outrec . outPtCount ;
14301434 SetOwner ( ae2 . outrec , ae1 . outrec ) ;
14311435
14321436 if ( IsOpenEnd ( ae1 ) )
@@ -1441,7 +1445,7 @@ private static void JoinOutrecPaths(Active ae1, Active ae2)
14411445 }
14421446
14431447 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1444- private static OutPt AddOutPt ( Active ae , Point64 pt )
1448+ private OutPt AddOutPt ( Active ae , Point64 pt )
14451449 {
14461450
14471451 // Outrec.OutPts: a circular doubly-linked-list of POutPt where ...
@@ -1459,7 +1463,7 @@ private static OutPt AddOutPt(Active ae, Point64 pt)
14591463 return opBack ;
14601464 }
14611465
1462- OutPt newOp = new OutPt ( pt , outrec ) ;
1466+ OutPt newOp = _outPtPool . Add ( pt , outrec ) ;
14631467 opBack . prev = newOp ;
14641468 newOp . prev = opFront ;
14651469 newOp . next = opBack ;
@@ -1471,11 +1475,9 @@ private static OutPt AddOutPt(Active ae, Point64 pt)
14711475 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
14721476 private OutRec NewOutRec ( )
14731477 {
1474- OutRec result = new OutRec
1475- {
1476- idx = _outrecList . Count
1477- } ;
1478- _outrecList . Add ( result ) ;
1478+ int idx = _outrecList . Count ;
1479+ OutRec result = _outrecList . Add ( ) ;
1480+ result . idx = idx ;
14791481 return result ;
14801482 }
14811483
@@ -1496,7 +1498,7 @@ private OutPt StartOpenPath(Active ae, Point64 pt)
14961498 }
14971499
14981500 ae . outrec = outrec ;
1499- OutPt op = new OutPt ( pt , outrec ) ;
1501+ OutPt op = _outPtPool . Add ( pt , outrec ) ;
15001502 outrec . pts = op ;
15011503 return op ;
15021504 }
@@ -1812,6 +1814,45 @@ private void DeleteFromAEL(Active ae)
18121814 _actives = next ;
18131815 if ( next != null ) next . prevInAEL = prev ;
18141816 // delete &ae;
1817+ PoolDeletedActive ( ae ) ;
1818+ }
1819+
1820+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1821+ private void PoolDeletedActive ( Active ae )
1822+ {
1823+ //clear refs to allow GC
1824+ ae . bot = new Point64 ( ) ;
1825+ ae . top = new Point64 ( ) ;
1826+ ae . dx = 0.0 ;
1827+ ae . windCount = 0 ;
1828+ ae . windCount2 = 0 ;
1829+ ae . outrec = null ;
1830+ ae . prevInAEL = null ;
1831+ ae . nextInAEL = null ;
1832+ ae . prevInSEL = null ;
1833+ ae . nextInSEL = null ;
1834+ ae . jump = null ;
1835+ ae . vertexTop = null ;
1836+ ae . localMin = new LocalMinima ( ) ;
1837+ ae . isLeftBound = false ;
1838+ ae . joinWith = JoinWith . None ;
1839+ _freeActives . Push ( ae ) ;
1840+ }
1841+
1842+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1843+ private Active NewActive ( )
1844+ {
1845+ Active ae ;
1846+ if ( _freeActives . Count == 0 )
1847+ {
1848+ ae = new Active ( ) ;
1849+ }
1850+ else
1851+ {
1852+ //recycle active from free list
1853+ ae = _freeActives . Pop ( ) ;
1854+ }
1855+ return ae ;
18151856 }
18161857
18171858 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -2497,9 +2538,9 @@ private static bool UpdateHorzSegment(HorzSegment hs)
24972538 }
24982539
24992540 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
2500- private static OutPt DuplicateOp ( OutPt op , bool insert_after )
2541+ private OutPt DuplicateOp ( OutPt op , bool insert_after )
25012542 {
2502- OutPt result = new OutPt ( op . pt , op . outrec ) ;
2543+ OutPt result = _outPtPool . Add ( op . pt , op . outrec ) ;
25032544 if ( insert_after )
25042545 {
25052546 result . next = op . next ;
@@ -2556,10 +2597,9 @@ private void ConvertHorzSegsToJoins()
25562597 while ( hs2 . leftOp . prev . pt . Y == curr_y &&
25572598 hs2 . leftOp . prev . pt . X <= hs1 . leftOp . pt . X )
25582599 ( hs2 ) . leftOp = ( hs2 ) . leftOp . prev ;
2559- HorzJoin join = new HorzJoin (
2600+ HorzJoin join = _horzJoinList . Add (
25602601 DuplicateOp ( ( hs1 ) . leftOp , true ) ,
25612602 DuplicateOp ( ( hs2 ) . leftOp , false ) ) ;
2562- _horzJoinList . Add ( join ) ;
25632603 }
25642604 else
25652605 {
@@ -2569,10 +2609,9 @@ private void ConvertHorzSegsToJoins()
25692609 while ( hs2 . leftOp . next ! . pt . Y == curr_y &&
25702610 hs2 . leftOp . next . pt . X <= ( hs1 ) . leftOp . pt . X )
25712611 hs2 . leftOp = ( hs2 ) . leftOp . next ;
2572- HorzJoin join = new HorzJoin (
2612+ HorzJoin join = _horzJoinList . Add (
25732613 DuplicateOp ( ( hs2 ) . leftOp , true ) ,
25742614 DuplicateOp ( ( hs1 ) . leftOp , false ) ) ;
2575- _horzJoinList . Add ( join ) ;
25762615 }
25772616 }
25782617 }
@@ -2879,7 +2918,9 @@ private void DoSplitOp(OutRec outrec, OutPt splitOp)
28792918 }
28802919 else
28812920 {
2882- OutPt newOp2 = new OutPt ( ip , outrec ) { prev = prevOp , next = nextNextOp } ;
2921+ OutPt newOp2 = _outPtPool . Add ( ip , outrec ) ;
2922+ newOp2 . prev = prevOp ;
2923+ newOp2 . next = nextNextOp ;
28832924 nextNextOp . prev = newOp2 ;
28842925 prevOp . next = newOp2 ;
28852926 }
@@ -2897,7 +2938,9 @@ private void DoSplitOp(OutRec outrec, OutPt splitOp)
28972938 splitOp . outrec = newOutRec ;
28982939 splitOp . next . outrec = newOutRec ;
28992940
2900- OutPt newOp = new OutPt ( ip , newOutRec ) { prev = splitOp . next , next = splitOp } ;
2941+ OutPt newOp = _outPtPool . Add ( ip , newOutRec ) ;
2942+ newOp . prev = splitOp . next ;
2943+ newOp . next = splitOp ;
29012944 newOutRec . pts = newOp ;
29022945 splitOp . prev = newOp ;
29032946 splitOp . next . next = newOp ;
@@ -3004,7 +3047,7 @@ protected bool BuildPaths(Paths64 solutionClosed, Paths64 solutionOpen)
30043047 OutRec outrec = _outrecList [ i ++ ] ;
30053048 if ( outrec . pts == null ) continue ;
30063049
3007- Path64 path = new Path64 ( ) ;
3050+ Path64 path = new Path64 ( outrec . outPtCount ) ;
30083051 if ( outrec . isOpen )
30093052 {
30103053 if ( BuildPath ( outrec . pts , ReverseSolution , true , path ) )
@@ -3104,7 +3147,7 @@ protected void BuildTree(PolyPathBase polytree, Paths64 solutionOpen)
31043147
31053148 if ( outrec . isOpen )
31063149 {
3107- Path64 open_path = new Path64 ( ) ;
3150+ Path64 open_path = new Path64 ( outrec . outPtCount ) ;
31083151 if ( BuildPath ( outrec . pts , ReverseSolution , true , open_path ) )
31093152 solutionOpen . Add ( open_path ) ;
31103153 continue ;
0 commit comments