Simplify EdgeIterator implementation.

This commit is contained in:
wo80
2022-02-14 21:44:03 +01:00
parent 541e0b4e61
commit 5500ecc166
5 changed files with 78 additions and 132 deletions
@@ -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;
}
}
}
}
}
}
}
}
+1 -1
View File
@@ -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;
+1
View File
@@ -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.
+1 -5
View 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;
}
} }
} }
+67 -60
View File
@@ -13,70 +13,28 @@ 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;
/// <summary> foreach (var t in mesh.triangles)
/// Initializes a new instance of the <see cref="EdgeIterator" /> class.
/// </summary>
public EdgeIterator(Mesh mesh)
{ {
triangles = mesh.triangles.GetEnumerator(); tri.tri = t;
triangles.MoveNext();
tri.tri = triangles.Current;
tri.orient = 0; tri.orient = 0;
}
public Edge Current for (int i = 0; i < 3; i++)
{ {
get { return current; }
}
public void Dispose()
{
this.triangles.Dispose();
}
object System.Collections.IEnumerator.Current
{
get { return current; }
}
public bool MoveNext()
{
if (tri.tri == null)
{
return false;
}
current = null;
while (current == null)
{
if (tri.orient == 3)
{
if (triangles.MoveNext())
{
tri.tri = triangles.Current;
tri.orient = 0;
}
else
{
// Finally no more triangles
return false;
}
}
tri.Sym(ref neighbor); tri.Sym(ref neighbor);
if ((tri.tri.id < neighbor.tri.id) || (neighbor.tri.id == Mesh.DUMMY)) int nid = neighbor.tri.id;
if ((tri.tri.id < nid) || (nid == Mesh.DUMMY))
{ {
p1 = tri.Org(); p1 = tri.Org();
p2 = tri.Dest(); p2 = tri.Dest();
@@ -84,18 +42,67 @@ namespace TriangleNet.Meshing.Iterators
tri.Pivot(ref sub); tri.Pivot(ref sub);
// Boundary mark of dummysub is 0, so we don't need to worry about that. // 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); yield return new Edge(p1.id, p2.id, sub.seg.boundary);
} }
tri.orient++; tri.orient++;
} }
}
return true;
} }
public void Reset() /// <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="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)
{ {
this.triangles.Reset(); Otri tri = default;
Otri neighbor = default;
Osub sub = default;
Vertex p1, p2;
bool segments = !skipSegments;
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);
if (sub.seg.hash == Mesh.DUMMY)
{
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++;
}
}
} }
} }
} }