diff --git a/Triangle.NET/Triangle/IO/FileProcessor.cs b/Triangle.NET/Triangle/IO/FileProcessor.cs
index d8add9c..d2f1b70 100644
--- a/Triangle.NET/Triangle/IO/FileProcessor.cs
+++ b/Triangle.NET/Triangle/IO/FileProcessor.cs
@@ -73,6 +73,7 @@ namespace TriangleNet.IO
if (format != null && format.IsSupported(filename))
{
format.Write(polygon, filename);
+ return;
}
}
@@ -113,6 +114,7 @@ namespace TriangleNet.IO
if (format != null && format.IsSupported(filename))
{
format.Write(mesh, filename);
+ return;
}
}
diff --git a/Triangle.NET/Triangle/IO/TriangleWriter.cs b/Triangle.NET/Triangle/IO/TriangleWriter.cs
index 2beaa48..acdb2f2 100644
--- a/Triangle.NET/Triangle/IO/TriangleWriter.cs
+++ b/Triangle.NET/Triangle/IO/TriangleWriter.cs
@@ -367,7 +367,7 @@ namespace TriangleNet.IO
for (tri.orient = 0; tri.orient < 3; tri.orient++)
{
tri.Sym(ref trisym);
- if ((tri.tri.id < trisym.tri.id) || (trisym.tri.id == Triangle.EmptyID))
+ if ((tri.tri.id < trisym.tri.id) || (trisym.tri.id == Mesh.DUMMY))
{
p1 = tri.Org();
p2 = tri.Dest();
@@ -380,7 +380,7 @@ namespace TriangleNet.IO
{
tri.Pivot(ref checkmark);
- if (checkmark.seg == Segment.Empty)
+ if (checkmark.seg.hash == Mesh.DUMMY)
{
writer.WriteLine("{0} {1} {2} {3}", index, p1.id, p2.id, 0);
}
@@ -393,7 +393,7 @@ namespace TriangleNet.IO
else
{
writer.WriteLine("{0} {1} {2} {3}", index, p1.id, p2.id,
- trisym.tri.id == Triangle.EmptyID ? "1" : "0");
+ trisym.tri.id == Mesh.DUMMY ? "1" : "0");
}
}
else
@@ -522,12 +522,12 @@ namespace TriangleNet.IO
for (tri.orient = 0; tri.orient < 3; tri.orient++)
{
tri.Sym(ref trisym);
- if ((tri.tri.id < trisym.tri.id) || (trisym.tri.id == Triangle.EmptyID))
+ if ((tri.tri.id < trisym.tri.id) || (trisym.tri.id == Mesh.DUMMY))
{
// Find the number of this triangle (and Voronoi vertex).
p1 = tri.tri.id;
- if (trisym.tri.id == Triangle.EmptyID)
+ if (trisym.tri.id == Mesh.DUMMY)
{
torg = tri.Org();
tdest = tri.Dest();
diff --git a/Triangle.NET/Triangle/Mesh.cs b/Triangle.NET/Triangle/Mesh.cs
index 19684ab..021208b 100644
--- a/Triangle.NET/Triangle/Mesh.cs
+++ b/Triangle.NET/Triangle/Mesh.cs
@@ -156,11 +156,75 @@ namespace TriangleNet
#endregion
+ #region "Outer space" variables
+
+ internal const int DUMMY = -1;
+
+ // The triangle that fills "outer space," called 'dummytri', is pointed to
+ // by every triangle and subsegment on a boundary (be it outer or inner) of
+ // the triangulation. Also, 'dummytri' points to one of the triangles on
+ // the convex hull (until the holes and concavities are carved), making it
+ // possible to find a starting triangle for point location.
+
+ // 'dummytri' and 'dummysub' are generally required to fulfill only a few
+ // invariants: their vertices must remain NULL and 'dummytri' must always
+ // be bonded (at offset zero) to some triangle on the convex hull of the
+ // mesh, via a boundary edge. Otherwise, the connections of 'dummytri' and
+ // 'dummysub' may change willy-nilly. This makes it possible to avoid
+ // writing a good deal of special-case code (in the edge flip, for example)
+ // for dealing with the boundary of the mesh, places where no subsegment is
+ // present, and so forth. Other entities are frequently bonded to
+ // 'dummytri' and 'dummysub' as if they were real mesh entities, with no
+ // harm done.
+
+ internal Triangle dummytri;
+
+ // Set up 'dummysub', the omnipresent subsegment pointed to by any
+ // triangle side or subsegment end that isn't attached to a real
+ // subsegment.
+
+ internal Segment dummysub;
+
+ private void Initialize()
+ {
+ dummysub = new Segment();
+ dummysub.hash = DUMMY;
+
+ // Initialize the two adjoining subsegments to be the omnipresent
+ // subsegment. These will eventually be changed by various bonding
+ // operations, but their values don't really matter, as long as they
+ // can legally be dereferenced.
+ dummysub.subsegs[0].seg = dummysub;
+ dummysub.subsegs[1].seg = dummysub;
+
+ // Set up 'dummytri', the 'triangle' that occupies "outer space."
+ dummytri = new Triangle();
+ dummytri.hash = dummytri.id = DUMMY;
+
+ // Initialize the three adjoining triangles to be "outer space." These
+ // will eventually be changed by various bonding operations, but their
+ // values don't really matter, as long as they can legally be
+ // dereferenced.
+ dummytri.neighbors[0].tri = dummytri;
+ dummytri.neighbors[1].tri = dummytri;
+ dummytri.neighbors[2].tri = dummytri;
+
+ // Initialize the three adjoining subsegments of 'dummytri' to be
+ // the omnipresent subsegment.
+ dummytri.subsegs[0].seg = dummysub;
+ dummytri.subsegs[1].seg = dummysub;
+ dummytri.subsegs[2].seg = dummysub;
+ }
+
+ #endregion
+
///
/// Initializes a new instance of the class.
///
public Mesh()
{
+ Initialize();
+
logger = Log.Instance;
behavior = new Behavior();
@@ -590,8 +654,16 @@ namespace TriangleNet
internal void MakeTriangle(ref Otri newotri)
{
Triangle tri = new Triangle();
- tri.hash = this.hash_tri++;
- tri.id = tri.hash;
+
+ tri.hash = tri.id = this.hash_tri++;
+
+ tri.subsegs[0].seg = dummysub;
+ tri.subsegs[1].seg = dummysub;
+ tri.subsegs[2].seg = dummysub;
+
+ tri.neighbors[0].tri = dummytri;
+ tri.neighbors[1].tri = dummytri;
+ tri.neighbors[2].tri = dummytri;
newotri.tri = tri;
newotri.orient = 0;
@@ -606,8 +678,15 @@ namespace TriangleNet
internal void MakeSegment(ref Osub newsubseg)
{
Segment seg = new Segment();
+
seg.hash = this.hash_seg++;
+ seg.subsegs[0].seg = dummysub;
+ seg.subsegs[1].seg = dummysub;
+
+ seg.triangles[0].tri = dummytri;
+ seg.triangles[1].tri = dummytri;
+
newsubseg.seg = seg;
newsubseg.orient = 0;
@@ -702,12 +781,13 @@ namespace TriangleNet
{
// Find the location of the vertex to be inserted. Check if a good
// starting triangle has already been provided by the caller.
- if (searchtri.tri.id == Triangle.EmptyID)
+ if (searchtri.tri.id == DUMMY)
{
// Find a boundary triangle.
- horiz.tri = Triangle.Empty;
+ horiz.tri = dummytri;
horiz.orient = 0;
horiz.Sym();
+
// Search for a triangle containing 'newvertex'.
intersect = locator.Locate(newvertex, ref horiz);
}
@@ -741,7 +821,7 @@ namespace TriangleNet
{
// Check whether the vertex falls on a subsegment.
horiz.Pivot(ref brokensubseg);
- if (brokensubseg.seg != Segment.Empty)
+ if (brokensubseg.seg.hash != DUMMY)
{
// The vertex falls on a subsegment, and hence will not be inserted.
if (segmentflaws)
@@ -752,7 +832,7 @@ namespace TriangleNet
// This subsegment may be split only if it is an
// internal boundary.
horiz.Sym(ref testtri);
- enq = testtri.tri.id != Triangle.EmptyID;
+ enq = testtri.tri.id != DUMMY;
}
if (enq)
{
@@ -779,7 +859,7 @@ namespace TriangleNet
botright.Sym(ref botrcasing);
horiz.Sym(ref topright);
// Is there a second triangle? (Or does this edge lie on a boundary?)
- mirrorflag = topright.tri.id != Triangle.EmptyID;
+ mirrorflag = topright.tri.id != DUMMY;
if (mirrorflag)
{
topright.Lnext();
@@ -835,18 +915,18 @@ namespace TriangleNet
{
botright.Pivot(ref botrsubseg);
- if (botrsubseg.seg != Segment.Empty)
+ if (botrsubseg.seg.hash != DUMMY)
{
- botright.SegDissolve();
+ botright.SegDissolve(dummysub);
newbotright.SegBond(ref botrsubseg);
}
if (mirrorflag)
{
topright.Pivot(ref toprsubseg);
- if (toprsubseg.seg != Segment.Empty)
+ if (toprsubseg.seg.hash != DUMMY)
{
- topright.SegDissolve();
+ topright.SegDissolve(dummysub);
newtopright.SegBond(ref toprsubseg);
}
}
@@ -942,15 +1022,15 @@ namespace TriangleNet
if (checksegments)
{
botleft.Pivot(ref botlsubseg);
- if (botlsubseg.seg != Segment.Empty)
+ if (botlsubseg.seg.hash != DUMMY)
{
- botleft.SegDissolve();
+ botleft.SegDissolve(dummysub);
newbotleft.SegBond(ref botlsubseg);
}
botright.Pivot(ref botrsubseg);
- if (botrsubseg.seg != Segment.Empty)
+ if (botrsubseg.seg.hash != DUMMY)
{
- botright.SegDissolve();
+ botright.SegDissolve(dummysub);
newbotright.SegBond(ref botrsubseg);
}
}
@@ -992,7 +1072,7 @@ namespace TriangleNet
{
// Check for a subsegment, which cannot be flipped.
horiz.Pivot(ref checksubseg);
- if (checksubseg.seg != Segment.Empty)
+ if (checksubseg.seg.hash != DUMMY)
{
// The edge is a subsegment and cannot be flipped.
doflip = false;
@@ -1012,7 +1092,7 @@ namespace TriangleNet
{
// Check if the edge is a boundary edge.
horiz.Sym(ref top);
- if (top.tri.id == Triangle.EmptyID)
+ if (top.tri.id == DUMMY)
{
// The edge is a boundary edge and cannot be flipped.
doflip = false;
@@ -1083,33 +1163,33 @@ namespace TriangleNet
botleft.Pivot(ref botlsubseg);
botright.Pivot(ref botrsubseg);
topright.Pivot(ref toprsubseg);
- if (toplsubseg.seg == Segment.Empty)
+ if (toplsubseg.seg.hash == DUMMY)
{
- topright.SegDissolve();
+ topright.SegDissolve(dummysub);
}
else
{
topright.SegBond(ref toplsubseg);
}
- if (botlsubseg.seg == Segment.Empty)
+ if (botlsubseg.seg.hash == DUMMY)
{
- topleft.SegDissolve();
+ topleft.SegDissolve(dummysub);
}
else
{
topleft.SegBond(ref botlsubseg);
}
- if (botrsubseg.seg == Segment.Empty)
+ if (botrsubseg.seg.hash == DUMMY)
{
- botleft.SegDissolve();
+ botleft.SegDissolve(dummysub);
}
else
{
botleft.SegBond(ref botrsubseg);
}
- if (toprsubseg.seg == Segment.Empty)
+ if (toprsubseg.seg.hash == DUMMY)
{
- botright.SegDissolve();
+ botright.SegDissolve(dummysub);
}
else
{
@@ -1175,7 +1255,7 @@ namespace TriangleNet
// Check for finishing a complete revolution about the new vertex, or
// falling outside of the triangulation. The latter will happen when
// a vertex is inserted at a boundary.
- if ((leftvertex == first) || (testtri.tri.id == Triangle.EmptyID))
+ if ((leftvertex == first) || (testtri.tri.id == DUMMY))
{
// We're done. Return a triangle whose origin is the new vertex.
horiz.Lnext(ref searchtri);
@@ -1221,7 +1301,7 @@ namespace TriangleNet
}
// Check if there's already a subsegment here.
tri.Pivot(ref newsubseg);
- if (newsubseg.seg == Segment.Empty)
+ if (newsubseg.seg.hash == DUMMY)
{
// Make new subsegment and initialize its vertices.
MakeSegment(ref newsubseg);
@@ -1306,7 +1386,7 @@ namespace TriangleNet
// SELF CHECK
- //if (top.triangle.id == Triangle.EmptyID)
+ //if (top.triangle.id == DUMMY)
//{
// logger.Error("Attempt to flip on boundary.", "Mesh.Flip()");
// flipedge.LnextSelf();
@@ -1349,36 +1429,36 @@ namespace TriangleNet
botright.Pivot(ref botrsubseg);
topright.Pivot(ref toprsubseg);
- if (toplsubseg.seg == Segment.Empty)
+ if (toplsubseg.seg.hash == DUMMY)
{
- topright.SegDissolve();
+ topright.SegDissolve(dummysub);
}
else
{
topright.SegBond(ref toplsubseg);
}
- if (botlsubseg.seg == Segment.Empty)
+ if (botlsubseg.seg.hash == DUMMY)
{
- topleft.SegDissolve();
+ topleft.SegDissolve(dummysub);
}
else
{
topleft.SegBond(ref botlsubseg);
}
- if (botrsubseg.seg == Segment.Empty)
+ if (botrsubseg.seg.hash == DUMMY)
{
- botleft.SegDissolve();
+ botleft.SegDissolve(dummysub);
}
else
{
botleft.SegBond(ref botrsubseg);
}
- if (toprsubseg.seg == Segment.Empty)
+ if (toprsubseg.seg.hash == DUMMY)
{
- botright.SegDissolve();
+ botright.SegDissolve(dummysub);
}
else
{
@@ -1451,33 +1531,33 @@ namespace TriangleNet
botleft.Pivot(ref botlsubseg);
botright.Pivot(ref botrsubseg);
topright.Pivot(ref toprsubseg);
- if (toplsubseg.seg == Segment.Empty)
+ if (toplsubseg.seg.hash == DUMMY)
{
- botleft.SegDissolve();
+ botleft.SegDissolve(dummysub);
}
else
{
botleft.SegBond(ref toplsubseg);
}
- if (botlsubseg.seg == Segment.Empty)
+ if (botlsubseg.seg.hash == DUMMY)
{
- botright.SegDissolve();
+ botright.SegDissolve(dummysub);
}
else
{
botright.SegBond(ref botlsubseg);
}
- if (botrsubseg.seg == Segment.Empty)
+ if (botrsubseg.seg.hash == DUMMY)
{
- topright.SegDissolve();
+ topright.SegDissolve(dummysub);
}
else
{
topright.SegBond(ref botrsubseg);
}
- if (toprsubseg.seg == Segment.Empty)
+ if (toprsubseg.seg.hash == DUMMY)
{
- topleft.SegDissolve();
+ topleft.SegDissolve(dummysub);
}
else
{
@@ -1677,12 +1757,12 @@ namespace TriangleNet
deltri.Bond(ref leftcasing);
deltriright.Bond(ref rightcasing);
lefttri.Pivot(ref leftsubseg);
- if (leftsubseg.seg != Segment.Empty)
+ if (leftsubseg.seg.hash != DUMMY)
{
deltri.SegBond(ref leftsubseg);
}
righttri.Pivot(ref rightsubseg);
- if (rightsubseg.seg != Segment.Empty)
+ if (rightsubseg.seg.hash != DUMMY)
{
deltriright.SegBond(ref rightsubseg);
}
@@ -1775,7 +1855,7 @@ namespace TriangleNet
TriangleDealloc(botright.tri);
fliptri.Sym(ref gluetri);
- if (gluetri.tri.id != Triangle.EmptyID)
+ if (gluetri.tri.id != DUMMY)
{
gluetri.Lnext();
gluetri.Dnext(ref topright);
diff --git a/Triangle.NET/Triangle/MeshValidator.cs b/Triangle.NET/Triangle/MeshValidator.cs
index e990a9f..59c8dd8 100644
--- a/Triangle.NET/Triangle/MeshValidator.cs
+++ b/Triangle.NET/Triangle/MeshValidator.cs
@@ -50,7 +50,8 @@ namespace TriangleNet
{
if (Log.Verbose)
{
- logger.Warning("Triangle is flat or inverted.", "MeshValidator.IsConsistent()");
+ logger.Warning(String.Format("Triangle is flat or inverted (ID {0}).", t.id),
+ "MeshValidator.IsConsistent()");
}
horrors++;
@@ -59,7 +60,7 @@ namespace TriangleNet
// Find the neighboring triangle on this edge.
tri.Sym(ref oppotri);
- if (oppotri.tri.id != Triangle.EmptyID)
+ if (oppotri.tri.id != Mesh.DUMMY)
{
// Check that the triangle's neighbor knows it's a neighbor.
oppotri.Sym(ref oppooppotri);
@@ -168,7 +169,7 @@ namespace TriangleNet
// adjoining triangle whose pointer is larger (to ensure that
// each pair isn't tested twice).
shouldbedelaunay = (loop.tri.id < oppotri.tri.id) &&
- !Otri.IsDead(oppotri.tri) && (oppotri.tri.id != Triangle.EmptyID) &&
+ !Otri.IsDead(oppotri.tri) && (oppotri.tri.id != Mesh.DUMMY) &&
(org != inf1) && (org != inf2) && (org != inf3) &&
(dest != inf1) && (dest != inf2) && (dest != inf3) &&
(apex != inf1) && (apex != inf2) && (apex != inf3) &&
@@ -180,7 +181,7 @@ namespace TriangleNet
// constrained, so no local Delaunay test should be done.
loop.Pivot(ref opposubseg);
- if (opposubseg.seg != Segment.Empty)
+ if (opposubseg.seg.hash != Mesh.DUMMY)
{
shouldbedelaunay = false;
}
diff --git a/Triangle.NET/Triangle/Meshing/Algorithm/Dwyer.cs b/Triangle.NET/Triangle/Meshing/Algorithm/Dwyer.cs
index 7338901..1a0da2a 100644
--- a/Triangle.NET/Triangle/Meshing/Algorithm/Dwyer.cs
+++ b/Triangle.NET/Triangle/Meshing/Algorithm/Dwyer.cs
@@ -860,7 +860,8 @@ namespace TriangleNet.Meshing.Algorithm
// Find an edge on the convex hull to start point location from.
startghost.Lprev(ref searchedge);
searchedge.Sym();
- Triangle.Empty.neighbors[0] = searchedge;
+ mesh.dummytri.neighbors[0] = searchedge;
+
// Remove the bounding box and count the convex hull edges.
startghost.Copy(ref dissolveedge);
hullsize = 0;
@@ -876,7 +877,7 @@ namespace TriangleNet.Meshing.Algorithm
if (noPoly)
{
// Watch out for the case where all the input vertices are collinear.
- if (dissolveedge.tri.id != Triangle.EmptyID)
+ if (dissolveedge.tri.id != Mesh.DUMMY)
{
markorg = dissolveedge.Org();
if (markorg.mark == 0)
@@ -886,7 +887,7 @@ namespace TriangleNet.Meshing.Algorithm
}
}
// Remove a bounding triangle from a convex hull triangle.
- dissolveedge.Dissolve();
+ dissolveedge.Dissolve(mesh.dummytri);
// Find the next bounding triangle.
deadtriangle.Sym(ref dissolveedge);
diff --git a/Triangle.NET/Triangle/Meshing/Algorithm/Incremental.cs b/Triangle.NET/Triangle/Meshing/Algorithm/Incremental.cs
index 4b6cf6f..d03527f 100644
--- a/Triangle.NET/Triangle/Meshing/Algorithm/Incremental.cs
+++ b/Triangle.NET/Triangle/Meshing/Algorithm/Incremental.cs
@@ -35,7 +35,7 @@ namespace TriangleNet.Meshing.Algorithm
foreach (var v in mesh.vertices.Values)
{
- starttri.tri = Triangle.Empty;
+ starttri.tri = mesh.dummytri;
Osub tmp = default(Osub);
if (mesh.InsertVertex(v, ref starttri, ref tmp, false, false) == InsertVertexResult.Duplicate)
{
@@ -85,12 +85,14 @@ namespace TriangleNet.Meshing.Algorithm
// Create the bounding box.
mesh.MakeTriangle(ref inftri);
+
inftri.SetOrg(mesh.infvertex1);
inftri.SetDest(mesh.infvertex2);
inftri.SetApex(mesh.infvertex3);
+
// Link dummytri to the bounding box so we can always find an
// edge to begin searching (point location) from.
- Triangle.Empty.neighbors[0] = inftri;
+ mesh.dummytri.neighbors[0] = inftri;
}
///
@@ -115,9 +117,10 @@ namespace TriangleNet.Meshing.Algorithm
bool noPoly = !mesh.behavior.Poly;
// Find a boundary triangle.
- nextedge.tri = Triangle.Empty;
+ nextedge.tri = mesh.dummytri;
nextedge.orient = 0;
nextedge.Sym();
+
// Mark a place to stop.
nextedge.Lprev(ref finaledge);
nextedge.Lnext();
@@ -130,7 +133,7 @@ namespace TriangleNet.Meshing.Algorithm
// adjacent to the first one.
nextedge.Lnext(ref checkedge);
checkedge.Sym();
- if (checkedge.tri.id == Triangle.EmptyID)
+ if (checkedge.tri.id == Mesh.DUMMY)
{
// Go on to the next triangle. There are only three boundary
// triangles, and this next triangle cannot be the third one,
@@ -138,9 +141,11 @@ namespace TriangleNet.Meshing.Algorithm
searchedge.Lprev();
searchedge.Sym();
}
+
// Find a new boundary edge to search from, as the current search
// edge lies on a bounding box triangle and will be deleted.
- Triangle.Empty.neighbors[0] = searchedge;
+ mesh.dummytri.neighbors[0] = searchedge;
+
hullsize = -2;
while (!nextedge.Equal(finaledge))
{
@@ -155,7 +160,7 @@ namespace TriangleNet.Meshing.Algorithm
// vertices are collinear, and thus all the triangles are part of
// the bounding box. Otherwise, the setvertexmark() call below
// will cause a bad pointer reference.
- if (dissolveedge.tri.id != Triangle.EmptyID)
+ if (dissolveedge.tri.id != Mesh.DUMMY)
{
markorg = dissolveedge.Org();
if (markorg.mark == 0)
@@ -165,18 +170,19 @@ namespace TriangleNet.Meshing.Algorithm
}
}
// Disconnect the bounding box triangle from the mesh triangle.
- dissolveedge.Dissolve();
+ dissolveedge.Dissolve(mesh.dummytri);
nextedge.Lnext(ref deadtriangle);
deadtriangle.Sym(ref nextedge);
// Get rid of the bounding box triangle.
mesh.TriangleDealloc(deadtriangle.tri);
// Do we need to turn the corner?
- if (nextedge.tri.id == Triangle.EmptyID)
+ if (nextedge.tri.id == Mesh.DUMMY)
{
// Turn the corner.
dissolveedge.Copy(ref nextedge);
}
}
+
mesh.TriangleDealloc(finaledge.tri);
return hullsize;
diff --git a/Triangle.NET/Triangle/Meshing/Algorithm/SweepLine.cs b/Triangle.NET/Triangle/Meshing/Algorithm/SweepLine.cs
index b8b3fe7..1ff2c2f 100644
--- a/Triangle.NET/Triangle/Meshing/Algorithm/SweepLine.cs
+++ b/Triangle.NET/Triangle/Meshing/Algorithm/SweepLine.cs
@@ -698,10 +698,12 @@ namespace TriangleNet.Meshing.Algorithm
bool noPoly = !mesh.behavior.Poly;
+ var dummytri = mesh.dummytri;
+
// Find an edge on the convex hull to start point location from.
startghost.Lprev(ref searchedge);
searchedge.Sym();
- Triangle.Empty.neighbors[0] = searchedge;
+ dummytri.neighbors[0] = searchedge;
// Remove the bounding box and count the convex hull edges.
startghost.Copy(ref dissolveedge);
hullsize = 0;
@@ -717,7 +719,7 @@ namespace TriangleNet.Meshing.Algorithm
if (noPoly)
{
// Watch out for the case where all the input vertices are collinear.
- if (dissolveedge.tri.id != Triangle.EmptyID)
+ if (dissolveedge.tri.id != Mesh.DUMMY)
{
markorg = dissolveedge.Org();
if (markorg.mark == 0)
@@ -727,7 +729,7 @@ namespace TriangleNet.Meshing.Algorithm
}
}
// Remove a bounding triangle from a convex hull triangle.
- dissolveedge.Dissolve();
+ dissolveedge.Dissolve(dummytri);
// Find the next bounding triangle.
deadtriangle.Sym(ref dissolveedge);
diff --git a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs
index 5a3f1b9..9d2dc92 100644
--- a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs
+++ b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs
@@ -48,6 +48,8 @@ namespace TriangleNet.Meshing
Triangle[] regionTris = null;
+ var dummytri = mesh.dummytri;
+
if (!mesh.behavior.Convex)
{
// Mark as infected any unprotected triangles on the boundary.
@@ -64,7 +66,7 @@ namespace TriangleNet.Meshing
if (mesh.bounds.Contains(hole))
{
// Start searching from some triangle on the outer boundary.
- searchtri.tri = Triangle.Empty;
+ searchtri.tri = dummytri;
searchtri.orient = 0;
searchtri.Sym();
// Ensure that the hole is to the left of this boundary edge;
@@ -101,12 +103,12 @@ namespace TriangleNet.Meshing
// Find the starting triangle for each region.
foreach (var region in mesh.regions)
{
- regionTris[i] = Triangle.Empty;
+ regionTris[i] = dummytri;
// Ignore region points that aren't within the bounds of the mesh.
if (mesh.bounds.Contains(region.point))
{
// Start searching from some triangle on the outer boundary.
- searchtri.tri = Triangle.Empty;
+ searchtri.tri = dummytri;
searchtri.orient = 0;
searchtri.Sym();
// Ensure that the region point is to the left of this boundary
@@ -144,7 +146,7 @@ namespace TriangleNet.Meshing
for (int i = 0; i < regionTris.Length; i++)
{
- if (regionTris[i].id != Triangle.EmptyID)
+ if (regionTris[i].id != Mesh.DUMMY)
{
// Make sure the triangle under consideration still exists.
// It may have been eaten by the virus.
@@ -260,10 +262,14 @@ namespace TriangleNet.Meshing
Osub hullsubseg = default(Osub);
Vertex horg, hdest;
+ var dummytri = mesh.dummytri;
+ var dummysub = mesh.dummysub;
+
// Find a triangle handle on the hull.
- hulltri.tri = Triangle.Empty;
+ hulltri.tri = dummytri;
hulltri.orient = 0;
hulltri.Sym();
+
// Remember where we started so we know when to stop.
hulltri.Copy(ref starttri);
// Go once counterclockwise around the convex hull.
@@ -274,7 +280,7 @@ namespace TriangleNet.Meshing
{
// Is the triangle protected by a subsegment?
hulltri.Pivot(ref hullsubseg);
- if (hullsubseg.seg == Segment.Empty)
+ if (hullsubseg.seg.hash == Mesh.DUMMY)
{
// The triangle is not protected; infect it.
if (!hulltri.IsInfected())
@@ -305,7 +311,7 @@ namespace TriangleNet.Meshing
// To find the next hull edge, go clockwise around the next vertex.
hulltri.Lnext();
hulltri.Oprev(ref nexttri);
- while (nexttri.tri.id != Triangle.EmptyID)
+ while (nexttri.tri.id != Mesh.DUMMY)
{
nexttri.Copy(ref hulltri);
hulltri.Oprev(ref nexttri);
@@ -337,6 +343,9 @@ namespace TriangleNet.Meshing
Vertex testvertex;
Vertex norg, ndest;
+ var dummysub = mesh.dummysub;
+ var dummytri = mesh.dummytri;
+
bool killorg;
// Loop through all the infected triangles, spreading the virus to
@@ -361,27 +370,27 @@ namespace TriangleNet.Meshing
// Check for a subsegment between the triangle and its neighbor.
testtri.Pivot(ref neighborsubseg);
// Check if the neighbor is nonexistent or already infected.
- if ((neighbor.tri.id == Triangle.EmptyID) || neighbor.IsInfected())
+ if ((neighbor.tri.id == Mesh.DUMMY) || neighbor.IsInfected())
{
- if (neighborsubseg.seg != Segment.Empty)
+ if (neighborsubseg.seg.hash != Mesh.DUMMY)
{
// There is a subsegment separating the triangle from its
// neighbor, but both triangles are dying, so the subsegment
// dies too.
mesh.SubsegDealloc(neighborsubseg.seg);
- if (neighbor.tri.id != Triangle.EmptyID)
+ if (neighbor.tri.id != Mesh.DUMMY)
{
// Make sure the subsegment doesn't get deallocated again
// later when the infected neighbor is visited.
neighbor.Uninfect();
- neighbor.SegDissolve();
+ neighbor.SegDissolve(dummysub);
neighbor.Infect();
}
}
}
else
{ // The neighbor exists and is not infected.
- if (neighborsubseg.seg == Segment.Empty)
+ if (neighborsubseg.seg.hash == Mesh.DUMMY)
{
// There is no subsegment protecting the neighbor, so
// the neighbor becomes infected.
@@ -393,7 +402,7 @@ namespace TriangleNet.Meshing
{
// The neighbor is protected by a subsegment.
// Remove this triangle from the subsegment.
- neighborsubseg.TriDissolve();
+ neighborsubseg.TriDissolve(dummytri);
// The subsegment becomes a boundary. Set markers accordingly.
if (neighborsubseg.seg.boundary == 0)
{
@@ -436,7 +445,7 @@ namespace TriangleNet.Meshing
// Walk counterclockwise about the vertex.
testtri.Onext(ref neighbor);
// Stop upon reaching a boundary or the starting triangle.
- while ((neighbor.tri.id != Triangle.EmptyID) &&
+ while ((neighbor.tri.id != Mesh.DUMMY) &&
(!neighbor.Equal(testtri)))
{
if (neighbor.IsInfected())
@@ -453,12 +462,12 @@ namespace TriangleNet.Meshing
neighbor.Onext();
}
// If we reached a boundary, we must walk clockwise as well.
- if (neighbor.tri.id == Triangle.EmptyID)
+ if (neighbor.tri.id == Mesh.DUMMY)
{
// Walk clockwise about the vertex.
testtri.Oprev(ref neighbor);
// Stop upon reaching a boundary.
- while (neighbor.tri.id != Triangle.EmptyID)
+ while (neighbor.tri.id != Mesh.DUMMY)
{
if (neighbor.IsInfected())
{
@@ -488,7 +497,7 @@ namespace TriangleNet.Meshing
for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
{
testtri.Sym(ref neighbor);
- if (neighbor.tri.id == Triangle.EmptyID)
+ if (neighbor.tri.id == Mesh.DUMMY)
{
// There is no neighboring triangle on this edge, so this edge
// is a boundary edge. This triangle is being deleted, so this
@@ -498,7 +507,7 @@ namespace TriangleNet.Meshing
else
{
// Disconnect the triangle from its neighbor.
- neighbor.Dissolve();
+ neighbor.Dissolve(dummytri);
// There is a neighboring triangle on this edge, so this edge
// becomes a boundary edge when this triangle is deleted.
mesh.hullsize++;
@@ -554,7 +563,7 @@ namespace TriangleNet.Meshing
// 'searchtri' faces directly away from 'searchpoint'. We could go left
// or right. Ask whether it's a triangle or a boundary on the left.
searchtri.Onext(ref checktri);
- if (checktri.tri.id == Triangle.EmptyID)
+ if (checktri.tri.id == Mesh.DUMMY)
{
leftflag = false;
}
@@ -567,7 +576,7 @@ namespace TriangleNet.Meshing
{
// Turn left until satisfied.
searchtri.Onext();
- if (searchtri.tri.id == Triangle.EmptyID)
+ if (searchtri.tri.id == Mesh.DUMMY)
{
logger.Error("Unable to find a triangle on path.", "Mesh.FindDirection().1");
throw new Exception("Unable to find a triangle on path.");
@@ -581,7 +590,7 @@ namespace TriangleNet.Meshing
{
// Turn right until satisfied.
searchtri.Oprev();
- if (searchtri.tri.id == Triangle.EmptyID)
+ if (searchtri.tri.id == Mesh.DUMMY)
{
logger.Error("Unable to find a triangle on path.", "Mesh.FindDirection().2");
throw new Exception("Unable to find a triangle on path.");
@@ -630,6 +639,8 @@ namespace TriangleNet.Meshing
Vertex newvertex;
InsertVertexResult success;
+ var dummysub = mesh.dummysub;
+
double ex, ey;
double tx, ty;
double etx, ety;
@@ -690,18 +701,18 @@ namespace TriangleNet.Meshing
// Divide the segment into two, and correct the segment endpoints.
splitsubseg.Sym();
splitsubseg.Pivot(ref opposubseg);
- splitsubseg.Dissolve();
- opposubseg.Dissolve();
+ splitsubseg.Dissolve(dummysub);
+ opposubseg.Dissolve(dummysub);
do
{
splitsubseg.SetSegOrg(newvertex);
splitsubseg.Next();
- } while (splitsubseg.seg != Segment.Empty);
+ } while (splitsubseg.seg.hash != Mesh.DUMMY);
do
{
opposubseg.SetSegOrg(newvertex);
opposubseg.Next();
- } while (opposubseg.seg != Segment.Empty);
+ } while (opposubseg.seg.hash != Mesh.DUMMY);
// Inserting the vertex may have caused edge flips. We wish to rediscover
// the edge connecting endpoint1 to the new intersection vertex.
@@ -789,7 +800,7 @@ namespace TriangleNet.Meshing
searchtri.Lnext(ref crosstri);
crosstri.Pivot(ref crosssubseg);
// Check for a crossing segment.
- if (crosssubseg.seg == Segment.Empty)
+ if (crosssubseg.seg.hash == Mesh.DUMMY)
{
return false;
}
@@ -850,12 +861,12 @@ namespace TriangleNet.Meshing
fixuptri.Lnext(ref neartri);
neartri.Sym(ref fartri);
// Check if the edge opposite the origin of fixuptri can be flipped.
- if (fartri.tri.id == Triangle.EmptyID)
+ if (fartri.tri.id == Mesh.DUMMY)
{
return;
}
neartri.Pivot(ref faredge);
- if (faredge.seg != Segment.Empty)
+ if (faredge.seg.hash != Mesh.DUMMY)
{
return;
}
@@ -1027,7 +1038,7 @@ namespace TriangleNet.Meshing
}
// Check for two intersecting segments.
fixuptri.Pivot(ref crosssubseg);
- if (crosssubseg.seg == Segment.Empty)
+ if (crosssubseg.seg.hash == Mesh.DUMMY)
{
mesh.Flip(ref fixuptri); // May create inverted triangle at left.
}
@@ -1067,6 +1078,8 @@ namespace TriangleNet.Meshing
Otri searchtri1 = default(Otri), searchtri2 = default(Otri);
Vertex checkvertex = null;
+ var dummytri = mesh.dummytri;
+
// Find a triangle whose origin is the segment's first endpoint.
searchtri1 = endpoint1.tri;
if (searchtri1.tri != null)
@@ -1077,7 +1090,7 @@ namespace TriangleNet.Meshing
if (checkvertex != endpoint1)
{
// Find a boundary triangle to search from.
- searchtri1.tri = Triangle.Empty;
+ searchtri1.tri = dummytri;
searchtri1.orient = 0;
searchtri1.Sym();
// Search for the segment's first endpoint by point location.
@@ -1111,7 +1124,7 @@ namespace TriangleNet.Meshing
if (checkvertex != endpoint2)
{
// Find a boundary triangle to search from.
- searchtri2.tri = Triangle.Empty;
+ searchtri2.tri = dummytri;
searchtri2.orient = 0;
searchtri2.Sym();
// Search for the segment's second endpoint by point location.
@@ -1148,7 +1161,7 @@ namespace TriangleNet.Meshing
Otri starttri = default(Otri);
// Find a triangle handle on the hull.
- hulltri.tri = Triangle.Empty;
+ hulltri.tri = mesh.dummytri;
hulltri.orient = 0;
hulltri.Sym();
// Remember where we started so we know when to stop.
@@ -1161,7 +1174,7 @@ namespace TriangleNet.Meshing
// To find the next hull edge, go clockwise around the next vertex.
hulltri.Lnext();
hulltri.Oprev(ref nexttri);
- while (nexttri.tri.id != Triangle.EmptyID)
+ while (nexttri.tri.id != Mesh.DUMMY)
{
nexttri.Copy(ref hulltri);
hulltri.Oprev(ref nexttri);
diff --git a/Triangle.NET/Triangle/Meshing/Converter.cs b/Triangle.NET/Triangle/Meshing/Converter.cs
index 6e286ef..34b9370 100644
--- a/Triangle.NET/Triangle/Meshing/Converter.cs
+++ b/Triangle.NET/Triangle/Meshing/Converter.cs
@@ -106,7 +106,7 @@ namespace TriangleNet.Meshing
for (i = 0; i < mesh.vertices.Count; i++)
{
Otri tmp = default(Otri);
- tmp.tri = Triangle.Empty;
+ tmp.tri = mesh.dummytri;
vertexarray[i] = new List(3);
vertexarray[i].Add(tmp);
}
@@ -164,7 +164,7 @@ namespace TriangleNet.Meshing
checktri = nexttri;
- if (checktri.tri.id != Triangle.EmptyID)
+ if (checktri.tri.id != Mesh.DUMMY)
{
tdest = tri.Dest();
tapex = tri.Apex();
@@ -192,7 +192,7 @@ namespace TriangleNet.Meshing
nexttri = vertexarray[aroundvertex][index];
checktri = nexttri;
- } while (checktri.tri.id != Triangle.EmptyID);
+ } while (checktri.tri.id != Mesh.DUMMY);
}
}
@@ -276,7 +276,7 @@ namespace TriangleNet.Meshing
// occurrence of a triangle on a list can (and does) represent
// an edge. In this way, most edges are represented twice, and
// every triangle-subsegment bond is represented once.
- while (notfound && (checktri.tri.id != Triangle.EmptyID))
+ while (notfound && (checktri.tri.id != Mesh.DUMMY))
{
checkdest = checktri.Dest();
@@ -289,7 +289,7 @@ namespace TriangleNet.Meshing
checktri.SegBond(ref subseg);
// Check if this is a boundary edge.
checktri.Sym(ref checkneighbor);
- if (checkneighbor.tri.id == Triangle.EmptyID)
+ if (checkneighbor.tri.id == Mesh.DUMMY)
{
// The next line doesn't insert a subsegment (because there's
// already one there), but it sets the boundary markers of
@@ -321,16 +321,16 @@ namespace TriangleNet.Meshing
nexttri = vertexarray[i][index];
checktri = nexttri;
- while (checktri.tri.id != Triangle.EmptyID)
+ while (checktri.tri.id != Mesh.DUMMY)
{
// Find the next triangle in the stack before this
// information gets overwritten.
index--;
nexttri = vertexarray[i][index];
// No adjacent subsegment. (This overwrites the stack info.)
- checktri.SegDissolve();
+ checktri.SegDissolve(mesh.dummysub);
checktri.Sym(ref checkneighbor);
- if (checkneighbor.tri.id == Triangle.EmptyID)
+ if (checkneighbor.tri.id == Mesh.DUMMY)
{
mesh.InsertSubseg(ref checktri, 1);
hullsize++;
diff --git a/Triangle.NET/Triangle/Meshing/Iterators/EdgeIterator.cs b/Triangle.NET/Triangle/Meshing/Iterators/EdgeIterator.cs
index b8b7c09..ebacb1a 100644
--- a/Triangle.NET/Triangle/Meshing/Iterators/EdgeIterator.cs
+++ b/Triangle.NET/Triangle/Meshing/Iterators/EdgeIterator.cs
@@ -76,7 +76,7 @@ namespace TriangleNet.Meshing.Iterators
tri.Sym(ref neighbor);
- if ((tri.tri.id < neighbor.tri.id) || (neighbor.tri.id == Triangle.EmptyID))
+ if ((tri.tri.id < neighbor.tri.id) || (neighbor.tri.id == Mesh.DUMMY))
{
p1 = tri.Org();
p2 = tri.Dest();
diff --git a/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs b/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs
index e1f1cb1..d2edeb1 100644
--- a/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs
+++ b/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs
@@ -66,8 +66,8 @@ namespace TriangleNet.Meshing.Iterators
testtri.Pivot(ref neighborsubseg);
// Make sure the neighbor exists, is not already infected, and
// isn't protected by a subsegment.
- if ((neighbor.tri.id != Triangle.EmptyID) && !neighbor.IsInfected()
- && (neighborsubseg.seg == Segment.Empty))
+ if ((neighbor.tri.id != Mesh.DUMMY) && !neighbor.IsInfected()
+ && (neighborsubseg.seg.hash == Mesh.DUMMY))
{
// Infect the neighbor.
neighbor.Infect();
@@ -104,7 +104,7 @@ namespace TriangleNet.Meshing.Iterators
///
public void Process(Triangle triangle, Action func)
{
- if (triangle.id != Triangle.EmptyID)
+ if (triangle.id != Mesh.DUMMY)
{
// Make sure the triangle under consideration still exists.
// It may have been eaten by the virus.
diff --git a/Triangle.NET/Triangle/Meshing/QualityMesher.cs b/Triangle.NET/Triangle/Meshing/QualityMesher.cs
index 6b4984c..00625eb 100644
--- a/Triangle.NET/Triangle/Meshing/QualityMesher.cs
+++ b/Triangle.NET/Triangle/Meshing/QualityMesher.cs
@@ -90,7 +90,7 @@ namespace TriangleNet.Meshing
// Check one neighbor of the subsegment.
testsubseg.Pivot(ref neighbortri);
// Does the neighbor exist, or is this a boundary edge?
- if (neighbortri.tri.id != Triangle.EmptyID)
+ if (neighbortri.tri.id != Mesh.DUMMY)
{
sides++;
// Find a vertex opposite this subsegment.
@@ -120,7 +120,7 @@ namespace TriangleNet.Meshing
testsubseg.Sym(ref testsym);
testsym.Pivot(ref neighbortri);
// Does the neighbor exist, or is this a boundary edge?
- if (neighbortri.tri.id != Triangle.EmptyID)
+ if (neighbortri.tri.id != Mesh.DUMMY)
{
sides++;
// Find the other vertex opposite this subsegment.
@@ -319,7 +319,7 @@ namespace TriangleNet.Meshing
// Check if both points lie in a common segment. If they do, the
// skinny triangle is enqueued to be split as usual.
tri1.Pivot(ref testsub);
- if (testsub.seg == Segment.Empty)
+ if (testsub.seg.hash == Mesh.DUMMY)
{
// No common segment. Find a subsegment that contains 'torg'.
tri1.Copy(ref tri2);
@@ -327,7 +327,7 @@ namespace TriangleNet.Meshing
{
tri1.Oprev();
tri1.Pivot(ref testsub);
- } while (testsub.seg == Segment.Empty);
+ } while (testsub.seg.hash == Mesh.DUMMY);
// Find the endpoints of the containing segment.
org1 = testsub.SegOrg();
dest1 = testsub.SegDest();
@@ -336,7 +336,7 @@ namespace TriangleNet.Meshing
{
tri2.Dnext();
tri2.Pivot(ref testsub);
- } while (testsub.seg == Segment.Empty);
+ } while (testsub.seg.hash == Mesh.DUMMY);
// Find the endpoints of the containing segment.
org2 = testsub.SegOrg();
dest2 = testsub.SegDest();
@@ -459,11 +459,11 @@ namespace TriangleNet.Meshing
currentenc.Pivot(ref enctri);
enctri.Lnext(ref testtri);
testtri.Pivot(ref testsh);
- acuteorg = testsh.seg != Segment.Empty;
+ acuteorg = testsh.seg.hash != Mesh.DUMMY;
// Is the destination shared with another segment?
testtri.Lnext();
testtri.Pivot(ref testsh);
- acutedest = testsh.seg != Segment.Empty;
+ acutedest = testsh.seg.hash != Mesh.DUMMY;
// If we're using Chew's algorithm (rather than Ruppert's)
// to define encroachment, delete free vertices from the
@@ -484,17 +484,17 @@ namespace TriangleNet.Meshing
// Now, check the other side of the segment, if there's a triangle there.
enctri.Sym(ref testtri);
- if (testtri.tri.id != Triangle.EmptyID)
+ if (testtri.tri.id != Mesh.DUMMY)
{
// Is the destination shared with another segment?
testtri.Lnext();
testtri.Pivot(ref testsh);
- acutedest2 = testsh.seg != Segment.Empty;
+ acutedest2 = testsh.seg.hash != Mesh.DUMMY;
acutedest = acutedest || acutedest2;
// Is the origin shared with another segment?
testtri.Lnext();
testtri.Pivot(ref testsh);
- acuteorg2 = testsh.seg != Segment.Empty;
+ acuteorg2 = testsh.seg.hash != Mesh.DUMMY;
acuteorg = acuteorg || acuteorg2;
// Delete free vertices from the subsegment's diametral circle.
diff --git a/Triangle.NET/Triangle/NewLocation.cs b/Triangle.NET/Triangle/NewLocation.cs
index 0315424..68138a0 100644
--- a/Triangle.NET/Triangle/NewLocation.cs
+++ b/Triangle.NET/Triangle/NewLocation.cs
@@ -2364,7 +2364,7 @@ namespace TriangleNet
badotri.Sym(ref neighbor);
// check if it is the one we are looking for by checking the corners
// first check if the neighbor is nonexistent, since it can be on the border
- if (neighbor.tri.id != Triangle.EmptyID)
+ if (neighbor.tri.id != Mesh.DUMMY)
{
// then check if two wanted corners are also in this triangle
// take the vertices of the candidate neighbor
diff --git a/Triangle.NET/Triangle/Sampler.cs b/Triangle.NET/Triangle/Sampler.cs
index aaa4de3..bc94aca 100644
--- a/Triangle.NET/Triangle/Sampler.cs
+++ b/Triangle.NET/Triangle/Sampler.cs
@@ -16,19 +16,24 @@ namespace TriangleNet
///
class Sampler
{
- static Random rand = new Random(DateTime.Now.Millisecond);
+ // Empirically chosen factor.
+ private const int samplefactor = 11;
+
+ private Random rand;
// Number of random samples for point location (at least 1).
- int samples = 1;
+ private int samples = 1;
// Number of triangles in mesh.
- int triangleCount = 0;
-
- // Empirically chosen factor.
- static int samplefactor = 11;
+ private int triangleCount = 0;
// Keys of the triangle dictionary.
- int[] keys;
+ private int[] keys;
+
+ public Sampler()
+ {
+ this.rand = new Random(110503);
+ }
///
/// Reset the sampler.
diff --git a/Triangle.NET/Triangle/Topology/DCEL/Face.cs b/Triangle.NET/Triangle/Topology/DCEL/Face.cs
index 14b4217..76cb6a7 100644
--- a/Triangle.NET/Triangle/Topology/DCEL/Face.cs
+++ b/Triangle.NET/Triangle/Topology/DCEL/Face.cs
@@ -79,11 +79,16 @@ namespace TriangleNet.Topology.DCEL
this.generator = generator;
this.edge = edge;
this.bounded = true;
+
+ if (generator != null)
+ {
+ this.id = generator.ID;
+ }
}
public override string ToString()
{
- return string.Format("F-ID {0}", generator == null ? id : generator.id);
+ return string.Format("F-ID {0}", id);
}
}
}
diff --git a/Triangle.NET/Triangle/Topology/Osub.cs b/Triangle.NET/Triangle/Topology/Osub.cs
index 640b5aa..3a82522 100644
--- a/Triangle.NET/Triangle/Topology/Osub.cs
+++ b/Triangle.NET/Triangle/Topology/Osub.cs
@@ -213,9 +213,9 @@ namespace TriangleNet.Topology
///
/// Note that the other subsegment will still think it's
/// connected to this subsegment.
- internal void Dissolve()
+ internal void Dissolve(Segment dummy)
{
- seg.subsegs[orient].seg = Segment.Empty;
+ seg.subsegs[orient].seg = dummy;
}
///
@@ -229,9 +229,9 @@ namespace TriangleNet.Topology
///
/// Dissolve a bond (from the subsegment side).
///
- internal void TriDissolve()
+ internal void TriDissolve(Triangle dummy)
{
- seg.triangles[orient].tri = Triangle.Empty;
+ seg.triangles[orient].tri = dummy;
}
///
diff --git a/Triangle.NET/Triangle/Topology/Otri.cs b/Triangle.NET/Triangle/Topology/Otri.cs
index 6a193b0..51544f8 100644
--- a/Triangle.NET/Triangle/Topology/Otri.cs
+++ b/Triangle.NET/Triangle/Topology/Otri.cs
@@ -396,9 +396,9 @@ namespace TriangleNet.Topology
/// this triangle. Usually, however, the other triangle is being deleted
/// entirely, or bonded to another triangle, so it doesn't matter.
///
- internal void Dissolve()
+ internal void Dissolve(Triangle dummy)
{
- tri.neighbors[orient].tri = Triangle.Empty;
+ tri.neighbors[orient].tri = dummy;
tri.neighbors[orient].orient = 0;
}
@@ -454,9 +454,9 @@ namespace TriangleNet.Topology
///
/// Dissolve a bond (from the triangle side).
///
- internal void SegDissolve()
+ internal void SegDissolve(Segment dummy)
{
- tri.subsegs[orient].seg = Segment.Empty;
+ tri.subsegs[orient].seg = dummy;
}
///
diff --git a/Triangle.NET/Triangle/Topology/Segment.cs b/Triangle.NET/Triangle/Topology/Segment.cs
index a7afdea..3cbb21b 100644
--- a/Triangle.NET/Triangle/Topology/Segment.cs
+++ b/Triangle.NET/Triangle/Topology/Segment.cs
@@ -15,29 +15,6 @@ namespace TriangleNet.Topology
///
public class Segment : ISegment
{
- #region Static initialization of "omnipresent" subsegment
-
- // Set up 'dummysub', the omnipresent subsegment pointed to by any
- // triangle side or subsegment end that isn't attached to a real
- // subsegment.
-
- internal static readonly Segment Empty;
-
- static Segment()
- {
- Empty = new Segment();
- Empty.hash = -1;
-
- // Initialize the two adjoining subsegments to be the omnipresent
- // subsegment. These will eventually be changed by various bonding
- // operations, but their values don't really matter, as long as they
- // can legally be dereferenced.
- Empty.subsegs[0].seg = Empty;
- Empty.subsegs[1].seg = Empty;
- }
-
- #endregion
-
// Hash for dictionary. Will be set by mesh instance.
internal int hash;
@@ -48,22 +25,18 @@ namespace TriangleNet.Topology
public Segment()
{
- // Initialize the two adjoining subsegments to be the omnipresent
- // subsegment.
- subsegs = new Osub[2];
- subsegs[0].seg = Empty;
- subsegs[1].seg = Empty;
-
// Four NULL vertices.
vertices = new Vertex[4];
- // Initialize the two adjoining triangles to be "outer space."
- triangles = new Otri[2];
- triangles[0].tri = Triangle.Empty;
- triangles[1].tri = Triangle.Empty;
-
// Set the boundary marker to zero.
boundary = 0;
+
+ // Initialize the two adjoining subsegments to be the omnipresent
+ // subsegment.
+ subsegs = new Osub[2];
+
+ // Initialize the two adjoining triangles to be "outer space."
+ triangles = new Otri[2];
}
#region Public properties
@@ -107,7 +80,7 @@ namespace TriangleNet.Topology
///
public ITriangle GetTriangle(int index)
{
- return triangles[index].tri.id == Triangle.EmptyID ? null : triangles[index].tri;
+ return triangles[index].tri.hash == Mesh.DUMMY ? null : triangles[index].tri;
}
public override int GetHashCode()
diff --git a/Triangle.NET/Triangle/Topology/Triangle.cs b/Triangle.NET/Triangle/Topology/Triangle.cs
index 4bcee8f..d92e5d8 100644
--- a/Triangle.NET/Triangle/Topology/Triangle.cs
+++ b/Triangle.NET/Triangle/Topology/Triangle.cs
@@ -15,61 +15,6 @@ namespace TriangleNet.Topology
///
public class Triangle : ITriangle
{
- #region Static initialization of "Outer Space" triangle
-
- // The triangle that fills "outer space," called 'dummytri', is pointed to
- // by every triangle and subsegment on a boundary (be it outer or inner) of
- // the triangulation. Also, 'dummytri' points to one of the triangles on
- // the convex hull (until the holes and concavities are carved), making it
- // possible to find a starting triangle for point location.
-
- // 'dummytri' and 'dummysub' are generally required to fulfill only a few
- // invariants: their vertices must remain NULL and 'dummytri' must always
- // be bonded (at offset zero) to some triangle on the convex hull of the
- // mesh, via a boundary edge. Otherwise, the connections of 'dummytri' and
- // 'dummysub' may change willy-nilly. This makes it possible to avoid
- // writing a good deal of special-case code (in the edge flip, for example)
- // for dealing with the boundary of the mesh, places where no subsegment is
- // present, and so forth. Other entities are frequently bonded to
- // 'dummytri' and 'dummysub' as if they were real mesh entities, with no
- // harm done.
-
- internal const int EmptyID = -1;
-
- internal static readonly Triangle Empty;
-
- ///
- /// Initializes the dummytri (Triangle.Empty).
- ///
- static Triangle()
- {
- // Set up 'dummytri', the 'triangle' that occupies "outer space."
- Empty = new Triangle();
- Empty.hash = Empty.id = EmptyID;
-
- // Initialize the three adjoining triangles to be "outer space." These
- // will eventually be changed by various bonding operations, but their
- // values don't really matter, as long as they can legally be
- // dereferenced.
- Empty.neighbors[0].tri = Empty;
- Empty.neighbors[1].tri = Empty;
- Empty.neighbors[2].tri = Empty;
-
- if (Segment.Empty == null)
- {
- // In case the static Segment constructor hasn't been called yet.
- Empty.subsegs[0].seg = new Segment();
- }
-
- // Initialize the three adjoining subsegments of 'dummytri' to be
- // the omnipresent subsegment.
- Empty.subsegs[0].seg = Segment.Empty;
- Empty.subsegs[1].seg = Segment.Empty;
- Empty.subsegs[2].seg = Segment.Empty;
- }
-
- #endregion
-
// Hash for dictionary. Will be set by mesh instance.
internal int hash;
@@ -93,15 +38,9 @@ namespace TriangleNet.Topology
// Initialize the three adjoining subsegments to be the omnipresent subsegment.
subsegs = new Osub[3];
- subsegs[0].seg = Segment.Empty;
- subsegs[1].seg = Segment.Empty;
- subsegs[2].seg = Segment.Empty;
// Initialize the three adjoining triangles to be "outer space".
neighbors = new Otri[3];
- neighbors[0].tri = Empty;
- neighbors[1].tri = Empty;
- neighbors[2].tri = Empty;
// area = -1.0;
}
@@ -185,7 +124,7 @@ namespace TriangleNet.Topology
/// The neigbbor opposite of vertex with given index.
public ITriangle GetNeighbor(int index)
{
- return neighbors[index].tri.id == EmptyID ? null : neighbors[index].tri;
+ return neighbors[index].tri.hash == Mesh.DUMMY ? null : neighbors[index].tri;
}
///
@@ -195,7 +134,7 @@ namespace TriangleNet.Topology
/// The segment opposite of vertex with given index.
public ISegment GetSegment(int index)
{
- return subsegs[index].seg == Segment.Empty ? null : subsegs[index].seg;
+ return subsegs[index].seg.hash == Mesh.DUMMY ? null : subsegs[index].seg;
}
///
diff --git a/Triangle.NET/Triangle/TriangleLocator.cs b/Triangle.NET/Triangle/TriangleLocator.cs
index 1c7535c..7e0cdfd 100644
--- a/Triangle.NET/Triangle/TriangleLocator.cs
+++ b/Triangle.NET/Triangle/TriangleLocator.cs
@@ -196,7 +196,7 @@ namespace TriangleNet
{
// Check for walking through a subsegment.
backtracktri.Pivot(ref checkedge);
- if (checkedge.seg != Segment.Empty)
+ if (checkedge.seg.hash != Mesh.DUMMY)
{
// Go back to the last triangle.
backtracktri.Copy(ref searchtri);
@@ -204,7 +204,7 @@ namespace TriangleNet
}
}
// Check for walking right out of the triangulation.
- if (searchtri.tri.id == Triangle.EmptyID)
+ if (searchtri.tri.id == Mesh.DUMMY)
{
// Go back to the last triangle.
backtracktri.Copy(ref searchtri);
diff --git a/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs b/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs
index 7aa4a4f..5196c25 100644
--- a/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs
+++ b/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs
@@ -177,7 +177,7 @@ namespace TriangleNet.Voronoi.Legacy
e.orient = 0;
e.Pivot(ref f);
- if (f.tri.id != Triangle.EmptyID && !f.tri.infected)
+ if (f.tri.id != Mesh.DUMMY && !f.tri.infected)
{
triangles.Push(f.tri);
}
@@ -185,7 +185,7 @@ namespace TriangleNet.Voronoi.Legacy
e.Sym();
e.Pivot(ref f);
- if (f.tri.id != Triangle.EmptyID && !f.tri.infected)
+ if (f.tri.id != Mesh.DUMMY && !f.tri.infected)
{
triangles.Push(f.tri);
}
@@ -216,7 +216,7 @@ namespace TriangleNet.Voronoi.Legacy
// if f0 is finite and tagged non-blind & the common edge
// between f and f0 is unconstrained then
- if (f0.tri.id != Triangle.EmptyID && !f0.tri.infected && sub1.seg == Segment.Empty)
+ if (f0.tri.id != Mesh.DUMMY && !f0.tri.infected && sub1.seg.hash == Mesh.DUMMY)
{
// Push f0 into triangles.
triangles.Push(f0.tri);
@@ -413,10 +413,10 @@ namespace TriangleNet.Voronoi.Legacy
f_init.Oprev(ref f_prev);
// Is the border to the left?
- if (f_prev.tri.id != Triangle.EmptyID)
+ if (f_prev.tri.id != Mesh.DUMMY)
{
// Go clockwise until we reach the border (or the initial triangle)
- while (f_prev.tri.id != Triangle.EmptyID && !f_prev.Equal(f_init))
+ while (f_prev.tri.id != Mesh.DUMMY && !f_prev.Equal(f_init))
{
f_prev.Copy(ref f);
f_prev.Oprev();
@@ -426,7 +426,7 @@ namespace TriangleNet.Voronoi.Legacy
f.Onext(ref f_next);
}
- if (f_prev.tri.id == Triangle.EmptyID)
+ if (f_prev.tri.id == Mesh.DUMMY)
{
// For vertices on the domain boundaray, add the vertex. For
// internal boundaries don't add it.
@@ -452,7 +452,7 @@ namespace TriangleNet.Voronoi.Legacy
// Call Lffnext the line going through the circumcenters of f and f_next
cc_f = this.points[f.tri.id];
- if (f_next.tri.id == Triangle.EmptyID)
+ if (f_next.tri.id == Mesh.DUMMY)
{
if (!f.tri.infected)
{
diff --git a/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs b/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs
index 50f5cf0..8f0333b 100644
--- a/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs
+++ b/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs
@@ -156,11 +156,11 @@ namespace TriangleNet.Voronoi.Legacy
f_init.Onext(ref f_next);
// Check if f_init lies on the boundary of the triangulation.
- if (f_next.tri.id == Triangle.EmptyID)
+ if (f_next.tri.id == Mesh.DUMMY)
{
f_init.Oprev(ref f_prev);
- if (f_prev.tri.id != Triangle.EmptyID)
+ if (f_prev.tri.id != Mesh.DUMMY)
{
f_init.Copy(ref f_next);
// Move one triangle clockwise
@@ -170,7 +170,7 @@ namespace TriangleNet.Voronoi.Legacy
}
// Go counterclockwise until we reach the border or the initial triangle.
- while (f_next.tri.id != Triangle.EmptyID)
+ while (f_next.tri.id != Mesh.DUMMY)
{
// Add circumcenter of current triangle
vpoints.Add(points[f.tri.id]);
@@ -228,7 +228,7 @@ namespace TriangleNet.Voronoi.Legacy
f_init.Copy(ref f);
f.Oprev(ref f_prev);
- while (f_prev.tri.id != Triangle.EmptyID)
+ while (f_prev.tri.id != Mesh.DUMMY)
{
vpoints.Add(points[f_prev.tri.id]);
region.AddNeighbor(f_prev.tri.id, regions[f_prev.Apex().id]);