Simplify EdgeIterator implementation.
This commit is contained in:
@@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
namespace TriangleNet.Rendering.Text
|
|
||||||
{
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using TriangleNet.Geometry;
|
|
||||||
|
|
||||||
static class EdgeIterator
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Enumerate the edges of the mesh.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="mesh"></param>
|
|
||||||
/// <param name="skipSegments"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// In contrast to the <see cref="TriangleNet.Meshing.Iterators.EdgeIterator"/> this
|
|
||||||
/// method will return objects that include the vertex information (and not only the
|
|
||||||
/// indices).
|
|
||||||
/// </remarks>
|
|
||||||
public static IEnumerable<ISegment> EnumerateEdges(Mesh mesh, bool skipSegments = true)
|
|
||||||
{
|
|
||||||
foreach (var t in mesh.Triangles)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
int nid = t.GetNeighborID(i);
|
|
||||||
|
|
||||||
if ((t.ID < nid) || (nid < 0))
|
|
||||||
{
|
|
||||||
var s = t.GetSegment(i);
|
|
||||||
|
|
||||||
if (skipSegments && s == null)
|
|
||||||
{
|
|
||||||
// Since segments will be processed separately, don't
|
|
||||||
// include them in the enumeration.
|
|
||||||
yield return new Segment(
|
|
||||||
t.GetVertex((i + 1) % 3),
|
|
||||||
t.GetVertex((i + 2) % 3));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (s == null)
|
|
||||||
{
|
|
||||||
yield return new Segment(
|
|
||||||
t.GetVertex((i + 1) % 3),
|
|
||||||
t.GetVertex((i + 2) % 3));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yield return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@ namespace TriangleNet.Rendering.Text
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using TriangleNet;
|
using TriangleNet;
|
||||||
using TriangleNet.Geometry;
|
using TriangleNet.Geometry;
|
||||||
|
using TriangleNet.Meshing.Iterators;
|
||||||
using Color = System.Drawing.Color;
|
using Color = System.Drawing.Color;
|
||||||
using IntPoint = System.Drawing.Point;
|
using IntPoint = System.Drawing.Point;
|
||||||
using IntRectangle = System.Drawing.Rectangle;
|
using IntRectangle = System.Drawing.Rectangle;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace TriangleNet.Rendering.Text
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using TriangleNet;
|
using TriangleNet;
|
||||||
using TriangleNet.Geometry;
|
using TriangleNet.Geometry;
|
||||||
|
using TriangleNet.Meshing.Iterators;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a mesh to an SVG file.
|
/// Writes a mesh to an SVG file.
|
||||||
|
|||||||
@@ -124,11 +124,7 @@ namespace TriangleNet
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var e = new EdgeIterator(this);
|
return new EdgeIterator().EnumerateEdges(this);
|
||||||
while (e.MoveNext())
|
|
||||||
{
|
|
||||||
yield return e.Current;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,89 +13,96 @@ namespace TriangleNet.Meshing.Iterators
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enumerates the edges of a triangulation.
|
/// Enumerates the edges of a triangulation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EdgeIterator : IEnumerator<Edge>
|
public class EdgeIterator
|
||||||
{
|
{
|
||||||
IEnumerator<Triangle> triangles;
|
public IEnumerable<Edge> EnumerateEdges(Mesh mesh)
|
||||||
Otri tri = default(Otri);
|
{
|
||||||
Otri neighbor = default(Otri);
|
Otri tri = default;
|
||||||
Osub sub = default(Osub);
|
Otri neighbor = default;
|
||||||
Edge current;
|
Osub sub = default;
|
||||||
Vertex p1, p2;
|
|
||||||
|
Vertex p1, p2;
|
||||||
|
|
||||||
|
foreach (var t in mesh.triangles)
|
||||||
|
{
|
||||||
|
tri.tri = t;
|
||||||
|
tri.orient = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
tri.Sym(ref neighbor);
|
||||||
|
|
||||||
|
int nid = neighbor.tri.id;
|
||||||
|
|
||||||
|
if ((tri.tri.id < nid) || (nid == Mesh.DUMMY))
|
||||||
|
{
|
||||||
|
p1 = tri.Org();
|
||||||
|
p2 = tri.Dest();
|
||||||
|
|
||||||
|
tri.Pivot(ref sub);
|
||||||
|
|
||||||
|
// Boundary mark of dummysub is 0, so we don't need to worry about that.
|
||||||
|
yield return new Edge(p1.id, p2.id, sub.seg.boundary);
|
||||||
|
}
|
||||||
|
|
||||||
|
tri.orient++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="EdgeIterator" /> class.
|
/// Enumerate the edges of the mesh.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EdgeIterator(Mesh mesh)
|
/// <param name="mesh"></param>
|
||||||
|
/// <param name="skipSegments"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// In contrast to the <see cref="EnumerateEdges(Mesh)"/> this method will return
|
||||||
|
/// objects that include the vertex information (and not only the indices).
|
||||||
|
/// </remarks>
|
||||||
|
public static IEnumerable<ISegment> EnumerateEdges(Mesh mesh, bool skipSegments = true)
|
||||||
{
|
{
|
||||||
triangles = mesh.triangles.GetEnumerator();
|
Otri tri = default;
|
||||||
triangles.MoveNext();
|
Otri neighbor = default;
|
||||||
|
Osub sub = default;
|
||||||
|
|
||||||
tri.tri = triangles.Current;
|
Vertex p1, p2;
|
||||||
tri.orient = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Edge Current
|
bool segments = !skipSegments;
|
||||||
{
|
|
||||||
get { return current; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
foreach (var t in mesh.triangles)
|
||||||
{
|
|
||||||
this.triangles.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
object System.Collections.IEnumerator.Current
|
|
||||||
{
|
|
||||||
get { return current; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
if (tri.tri == null)
|
|
||||||
{
|
{
|
||||||
return false;
|
tri.tri = t;
|
||||||
}
|
tri.orient = 0;
|
||||||
|
|
||||||
current = null;
|
for (int i = 0; i < 3; i++)
|
||||||
|
|
||||||
while (current == null)
|
|
||||||
{
|
|
||||||
if (tri.orient == 3)
|
|
||||||
{
|
{
|
||||||
if (triangles.MoveNext())
|
tri.Sym(ref neighbor);
|
||||||
|
|
||||||
|
int nid = neighbor.tri.id;
|
||||||
|
|
||||||
|
if ((tri.tri.id < nid) || (nid == Mesh.DUMMY))
|
||||||
{
|
{
|
||||||
tri.tri = triangles.Current;
|
p1 = tri.Org();
|
||||||
tri.orient = 0;
|
p2 = tri.Dest();
|
||||||
}
|
|
||||||
else
|
tri.Pivot(ref sub);
|
||||||
{
|
|
||||||
// Finally no more triangles
|
if (sub.seg.hash == Mesh.DUMMY)
|
||||||
return false;
|
{
|
||||||
|
yield return new Segment(p1, p2);
|
||||||
|
}
|
||||||
|
else if (segments)
|
||||||
|
{
|
||||||
|
// Segments might be processed separately, so only
|
||||||
|
// include them if requested.
|
||||||
|
yield return sub.seg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tri.orient++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tri.Sym(ref neighbor);
|
|
||||||
|
|
||||||
if ((tri.tri.id < neighbor.tri.id) || (neighbor.tri.id == Mesh.DUMMY))
|
|
||||||
{
|
|
||||||
p1 = tri.Org();
|
|
||||||
p2 = tri.Dest();
|
|
||||||
|
|
||||||
tri.Pivot(ref sub);
|
|
||||||
|
|
||||||
// Boundary mark of dummysub is 0, so we don't need to worry about that.
|
|
||||||
current = new Edge(p1.id, p2.id, sub.seg.boundary);
|
|
||||||
}
|
|
||||||
|
|
||||||
tri.orient++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
this.triangles.Reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user