Skip to content

Commit 76fc448

Browse files
committed
Fix pooling and allow it to be extended externally.
1 parent bc0468d commit 76fc448

File tree

5 files changed

+405
-255
lines changed

5 files changed

+405
-255
lines changed

LibTessDotNet/Sources/Mesh.cs

Lines changed: 50 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,18 @@ namespace LibTessDotNet.Double
4141
namespace LibTessDotNet
4242
#endif
4343
{
44-
internal class Mesh : MeshUtils.Pooled<Mesh>
44+
internal class Mesh : Pooled<Mesh>
4545
{
4646
internal MeshUtils.Vertex _vHead;
4747
internal MeshUtils.Face _fHead;
4848
internal MeshUtils.Edge _eHead, _eHeadSym;
4949

50-
private readonly List<MeshUtils.EdgePair> _allEdgePairs = new List<MeshUtils.EdgePair>(20000);
51-
52-
public void Init()
50+
public void Init(IPool pool)
5351
{
54-
var v = _vHead = MeshUtils.Vertex.Create();
55-
var f = _fHead = MeshUtils.Face.Create();
52+
var v = _vHead = pool.Get<MeshUtils.Vertex>();
53+
var f = _fHead = pool.Get<MeshUtils.Face>();
5654

57-
var pair = CreateEdgePair();
55+
var pair = MeshUtils.EdgePair.Create(pool);
5856
var e = _eHead = pair._e;
5957
var eSym = _eHeadSym = pair._eSym;
6058

@@ -86,116 +84,40 @@ public void Init()
8684
eSym._activeRegion = null;
8785
}
8886

89-
public override void Reset()
87+
public void Reset(IPool pool)
9088
{
91-
MeshUtils.Face f = _fHead._next;
92-
while (true)
89+
for (MeshUtils.Face f = _fHead, fNext = _fHead; f._next != null; f = fNext)
9390
{
94-
MeshUtils.Face fNext = f._next;
95-
f.Free();
96-
if (f == _fHead) break;
97-
f = fNext;
91+
fNext = f._next;
92+
pool.Return(f);
9893
}
99-
100-
MeshUtils.Vertex v = _vHead._next;
101-
while (true)
94+
for (MeshUtils.Vertex v = _vHead, vNext = _vHead; v._next != null; v = vNext)
10295
{
103-
MeshUtils.Vertex vNext = v._next;
104-
v.Free();
105-
if (v == _vHead) break;
106-
v = vNext;
96+
vNext = v._next;
97+
pool.Return(v);
10798
}
108-
109-
for (int i = 0; i < _allEdgePairs.Count; i++)
99+
for (MeshUtils.Edge e = _eHead, eNext = _eHead; e._next != null; e = eNext)
110100
{
111-
MeshUtils.EdgePair pair = _allEdgePairs[i];
112-
113-
MeshUtils.Edge e = pair._e;
114-
if (!e.IsReturnedToPool()) // (can be Free in KillEdge)
115-
{
116-
e.Free();
117-
}
118-
119-
MeshUtils.Edge eSym = pair._eSym;
120-
if (!eSym.IsReturnedToPool()) // (can be Free in KillEdge)
121-
{
122-
eSym.Free();
123-
}
124-
125-
pair.Free();
126-
}
127-
_allEdgePairs.Clear();
128-
101+
eNext = e._next;
102+
pool.Return(e._Sym);
103+
pool.Return(e);
104+
}
129105
_vHead = null;
130106
_fHead = null;
131107
_eHead = _eHeadSym = null;
132108
}
133109

134-
private MeshUtils.EdgePair CreateEdgePair()
135-
{
136-
var pair = MeshUtils.EdgePair.Create();
137-
pair._e = MeshUtils.Edge.Create();
138-
pair._e._pair = pair;
139-
pair._eSym = MeshUtils.Edge.Create();
140-
pair._eSym._pair = pair;
141-
_allEdgePairs.Add(pair);
142-
return pair;
143-
}
144-
145110
/// <summary>
146111
/// Creates one edge, two vertices and a loop (face).
147112
/// The loop consists of the two new half-edges.
148113
/// </summary>
149-
public MeshUtils.Edge MakeEdge()
114+
public MeshUtils.Edge MakeEdge(IPool pool)
150115
{
151-
var e = MakeEdge(_eHead);
152-
153-
MeshUtils.MakeVertex(e, _vHead);
154-
MeshUtils.MakeVertex(e._Sym, _vHead);
155-
MeshUtils.MakeFace(e, _fHead);
156-
157-
return e;
158-
}
116+
var e = MeshUtils.MakeEdge(pool, _eHead);
159117

160-
/// <summary>
161-
/// MakeEdge creates a new pair of half-edges which form their own loop.
162-
/// No vertex or face structures are allocated, but these must be assigned
163-
/// before the current edge operation is completed.
164-
/// </summary>
165-
private MeshUtils.Edge MakeEdge(MeshUtils.Edge eNext)
166-
{
167-
Debug.Assert(eNext != null);
168-
169-
var pair = CreateEdgePair();
170-
var e = pair._e;
171-
var eSym = pair._eSym;
172-
173-
// Make sure eNext points to the first edge of the edge pair
174-
MeshUtils.Edge.EnsureFirst(ref eNext);
175-
176-
// Insert in circular doubly-linked list before eNext.
177-
// Note that the prev pointer is stored in Sym->next.
178-
var ePrev = eNext._Sym._next;
179-
eSym._next = ePrev;
180-
ePrev._Sym._next = e;
181-
e._next = eNext;
182-
eNext._Sym._next = eSym;
183-
184-
e._Sym = eSym;
185-
e._Onext = e;
186-
e._Lnext = eSym;
187-
e._Org = null;
188-
e._Lface = null;
189-
e._winding = 0;
190-
e._activeRegion = null;
191-
192-
eSym._Sym = e;
193-
eSym._Onext = eSym;
194-
eSym._Lnext = e;
195-
eSym._Org = null;
196-
eSym._Lface = null;
197-
eSym._winding = 0;
198-
eSym._activeRegion = null;
118+
MeshUtils.MakeVertex(pool, e, _vHead);
119+
MeshUtils.MakeVertex(pool, e._Sym, _vHead);
120+
MeshUtils.MakeFace(pool, e, _fHead);
199121

200122
return e;
201123
}
@@ -224,7 +146,7 @@ private MeshUtils.Edge MakeEdge(MeshUtils.Edge eNext)
224146
/// If eDst == eOrg->Onext, the new vertex will have a single edge.
225147
/// If eDst == eOrg->Oprev, the old vertex will have a single edge.
226148
/// </summary>
227-
public void Splice(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
149+
public void Splice(IPool pool, MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
228150
{
229151
if (eOrg == eDst)
230152
{
@@ -236,14 +158,14 @@ public void Splice(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
236158
{
237159
// We are merging two disjoint vertices -- destroy eDst->Org
238160
joiningVertices = true;
239-
MeshUtils.KillVertex(eDst._Org, eOrg._Org);
161+
MeshUtils.KillVertex(pool, eDst._Org, eOrg._Org);
240162
}
241163
bool joiningLoops = false;
242164
if (eDst._Lface != eOrg._Lface)
243165
{
244166
// We are connecting two disjoint loops -- destroy eDst->Lface
245167
joiningLoops = true;
246-
MeshUtils.KillFace(eDst._Lface, eOrg._Lface);
168+
MeshUtils.KillFace(pool, eDst._Lface, eOrg._Lface);
247169
}
248170

249171
// Change the edge structure
@@ -253,14 +175,14 @@ public void Splice(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
253175
{
254176
// We split one vertex into two -- the new vertex is eDst->Org.
255177
// Make sure the old vertex points to a valid half-edge.
256-
MeshUtils.MakeVertex(eDst, eOrg._Org);
178+
MeshUtils.MakeVertex(pool, eDst, eOrg._Org);
257179
eOrg._Org._anEdge = eOrg;
258180
}
259181
if (!joiningLoops)
260182
{
261183
// We split one loop into two -- the new loop is eDst->Lface.
262184
// Make sure the old face points to a valid half-edge.
263-
MeshUtils.MakeFace(eDst, eOrg._Lface);
185+
MeshUtils.MakeFace(pool, eDst, eOrg._Lface);
264186
eOrg._Lface._anEdge = eOrg;
265187
}
266188
}
@@ -272,7 +194,7 @@ public void Splice(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
272194
/// the newly created loop will contain eDel->Dst. If the deletion of eDel
273195
/// would create isolated vertices, those are deleted as well.
274196
/// </summary>
275-
public void Delete(MeshUtils.Edge eDel)
197+
public void Delete(IPool pool, MeshUtils.Edge eDel)
276198
{
277199
var eDelSym = eDel._Sym;
278200

@@ -284,12 +206,12 @@ public void Delete(MeshUtils.Edge eDel)
284206
{
285207
// We are joining two loops into one -- remove the left face
286208
joiningLoops = true;
287-
MeshUtils.KillFace(eDel._Lface, eDel._Rface);
209+
MeshUtils.KillFace(pool, eDel._Lface, eDel._Rface);
288210
}
289211

290212
if (eDel._Onext == eDel)
291213
{
292-
MeshUtils.KillVertex(eDel._Org, null);
214+
MeshUtils.KillVertex(pool, eDel._Org, null);
293215
}
294216
else
295217
{
@@ -302,7 +224,7 @@ public void Delete(MeshUtils.Edge eDel)
302224
if (!joiningLoops)
303225
{
304226
// We are splitting one loop into two -- create a new loop for eDel.
305-
MeshUtils.MakeFace(eDel, eDel._Lface);
227+
MeshUtils.MakeFace(pool, eDel, eDel._Lface);
306228
}
307229
}
308230

@@ -311,8 +233,8 @@ public void Delete(MeshUtils.Edge eDel)
311233

312234
if (eDelSym._Onext == eDelSym)
313235
{
314-
MeshUtils.KillVertex(eDelSym._Org, null);
315-
MeshUtils.KillFace(eDelSym._Lface, null);
236+
MeshUtils.KillVertex(pool, eDelSym._Org, null);
237+
MeshUtils.KillFace(pool, eDelSym._Lface, null);
316238
}
317239
else
318240
{
@@ -323,24 +245,24 @@ public void Delete(MeshUtils.Edge eDel)
323245
}
324246

325247
// Any isolated vertices or faces have already been freed.
326-
MeshUtils.KillEdge(eDel);
248+
MeshUtils.KillEdge(pool, eDel);
327249
}
328250

329251
/// <summary>
330252
/// Creates a new edge such that eNew == eOrg.Lnext and eNew.Dst is a newly created vertex.
331253
/// eOrg and eNew will have the same left face.
332254
/// </summary>
333-
public MeshUtils.Edge AddEdgeVertex(MeshUtils.Edge eOrg)
255+
public MeshUtils.Edge AddEdgeVertex(IPool pool, MeshUtils.Edge eOrg)
334256
{
335-
var eNew = MakeEdge(eOrg);
257+
var eNew = MeshUtils.MakeEdge(pool, eOrg);
336258
var eNewSym = eNew._Sym;
337259

338260
// Connect the new edge appropriately
339261
MeshUtils.Splice(eNew, eOrg._Lnext);
340262

341263
// Set vertex and face information
342264
eNew._Org = eOrg._Dst;
343-
MeshUtils.MakeVertex(eNewSym, eNew._Org);
265+
MeshUtils.MakeVertex(pool, eNewSym, eNew._Org);
344266
eNew._Lface = eNewSym._Lface = eOrg._Lface;
345267

346268
return eNew;
@@ -351,9 +273,9 @@ public MeshUtils.Edge AddEdgeVertex(MeshUtils.Edge eOrg)
351273
/// The new vertex is eOrg.Dst == eNew.Org.
352274
/// eOrg and eNew will have the same left face.
353275
/// </summary>
354-
public MeshUtils.Edge SplitEdge(MeshUtils.Edge eOrg)
276+
public MeshUtils.Edge SplitEdge(IPool pool, MeshUtils.Edge eOrg)
355277
{
356-
var eTmp = AddEdgeVertex(eOrg);
278+
var eTmp = AddEdgeVertex(pool, eOrg);
357279
var eNew = eTmp._Sym;
358280

359281
// Disconnect eOrg from eOrg->Dst and connect it to eNew->Org
@@ -380,17 +302,17 @@ public MeshUtils.Edge SplitEdge(MeshUtils.Edge eOrg)
380302
/// If (eOrg->Lnext == eDst), the old face is reduced to a single edge.
381303
/// If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.
382304
/// </summary>
383-
public MeshUtils.Edge Connect(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
305+
public MeshUtils.Edge Connect(IPool pool, MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
384306
{
385-
var eNew = MakeEdge(eOrg);
307+
var eNew = MeshUtils.MakeEdge(pool, eOrg);
386308
var eNewSym = eNew._Sym;
387309

388310
bool joiningLoops = false;
389311
if (eDst._Lface != eOrg._Lface)
390312
{
391313
// We are connecting two disjoint loops -- destroy eDst->Lface
392314
joiningLoops = true;
393-
MeshUtils.KillFace(eDst._Lface, eOrg._Lface);
315+
MeshUtils.KillFace(pool, eDst._Lface, eOrg._Lface);
394316
}
395317

396318
// Connect the new edge appropriately
@@ -407,7 +329,7 @@ public MeshUtils.Edge Connect(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
407329

408330
if (!joiningLoops)
409331
{
410-
MeshUtils.MakeFace(eNew, eOrg._Lface);
332+
MeshUtils.MakeFace(pool, eNew, eOrg._Lface);
411333
}
412334

413335
return eNew;
@@ -421,7 +343,7 @@ public MeshUtils.Edge Connect(MeshUtils.Edge eOrg, MeshUtils.Edge eDst)
421343
/// An entire mesh can be deleted by zapping its faces, one at a time,
422344
/// in any order. Zapped faces cannot be used in further mesh operations!
423345
/// </summary>
424-
public void ZapFace(MeshUtils.Face fZap)
346+
public void ZapFace(IPool pool, MeshUtils.Face fZap)
425347
{
426348
var eStart = fZap._anEdge;
427349

@@ -439,7 +361,7 @@ public void ZapFace(MeshUtils.Face fZap)
439361

440362
if (e._Onext == e)
441363
{
442-
MeshUtils.KillVertex(e._Org, null);
364+
MeshUtils.KillVertex(pool, e._Org, null);
443365
}
444366
else
445367
{
@@ -450,15 +372,15 @@ public void ZapFace(MeshUtils.Face fZap)
450372
eSym = e._Sym;
451373
if (eSym._Onext == eSym)
452374
{
453-
MeshUtils.KillVertex(eSym._Org, null);
375+
MeshUtils.KillVertex(pool, eSym._Org, null);
454376
}
455377
else
456378
{
457379
// Make sure that eSym._Org points to a valid half-edge
458380
eSym._Org._anEdge = eSym._Onext;
459381
MeshUtils.Splice(eSym, eSym._Oprev);
460382
}
461-
MeshUtils.KillEdge(e);
383+
MeshUtils.KillEdge(pool, e);
462384
}
463385
} while (e != eStart);
464386

@@ -468,10 +390,10 @@ public void ZapFace(MeshUtils.Face fZap)
468390
fNext._prev = fPrev;
469391
fPrev._next = fNext;
470392

471-
fZap.Free();
393+
pool.Return(fZap);
472394
}
473395

474-
public void MergeConvexFaces(int maxVertsPerFace)
396+
public void MergeConvexFaces(IPool pool, int maxVertsPerFace)
475397
{
476398
for (var f = _fHead._next; f != _fHead; f = f._next)
477399
{
@@ -502,7 +424,7 @@ public void MergeConvexFaces(int maxVertsPerFace)
502424
Geom.VertCCW(eSym._Lprev._Org, eSym._Org, eCur._Lnext._Lnext._Org))
503425
{
504426
eNext = eSym._Lnext;
505-
Delete(eSym);
427+
Delete(pool, eSym);
506428
eCur = null;
507429
}
508430
}

0 commit comments

Comments
 (0)