diff --git a/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs b/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs
index b0e97cd..0ae494b 100644
--- a/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs
+++ b/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs
@@ -13,23 +13,78 @@ namespace TriangleNet.Meshing.Iterators
///
/// Iterates the region a given triangle belongs to and applies an action
- /// to each connected trianlge in that region. Default action is to set the
- /// region id.
+ /// to each connected trianlge in that region.
///
+ ///
+ /// The default action is to set the region id and area constraint.
+ ///
public class RegionIterator
{
- List viri;
+ List region;
public RegionIterator(Mesh mesh)
{
- this.viri = new List();
+ this.region = new List();
+ }
+
+ ///
+ /// Set the region attribute of all trianlges connected to given triangle.
+ ///
+ /// The triangle seed.
+ /// If non-zero, process all triangles of the
+ /// region that is enclosed by segments with given boundary label.
+ public void Process(Triangle triangle, int boundary = 0)
+ {
+ this.Process(triangle, (tri) =>
+ {
+ // Set the region id and area constraint.
+ tri.label = triangle.label;
+ tri.area = triangle.area;
+ }, boundary);
+ }
+
+ ///
+ /// Process all trianlges connected to given triangle and apply given action.
+ ///
+ /// The seeding triangle.
+ /// The action to apply to each triangle.
+ /// If non-zero, process all triangles of the
+ /// region that is enclosed by segments with given boundary label.
+ public void Process(Triangle triangle, Action action, int boundary = 0)
+ {
+ // Make sure the triangle under consideration still exists.
+ // It may have been eaten by the virus.
+ if (triangle.id == Mesh.DUMMY || Otri.IsDead(triangle))
+ {
+ return;
+ }
+
+ // Add the seeding triangle to the region.
+ region.Add(triangle);
+
+ triangle.infected = true;
+
+ if (boundary == 0)
+ {
+ // Stop at any subsegment.
+ ProcessRegion(action, seg => seg.hash == Mesh.DUMMY);
+ }
+ else
+ {
+ // Stop at segments that have the given boundary label.
+ ProcessRegion(action, seg => seg.boundary != boundary);
+ }
+
+ // Free up memory (virus pool should be empty anyway).
+ region.Clear();
}
///
/// Apply given action to each triangle of selected region.
///
- ///
- void ProcessRegion(Action func)
+ ///
+ ///
+ void ProcessRegion(Action action, Func protector)
{
Otri testtri = default(Otri);
Otri neighbor = default(Otri);
@@ -38,20 +93,14 @@ namespace TriangleNet.Meshing.Iterators
// Loop through all the infected triangles, spreading the attribute
// and/or area constraint to their neighbors, then to their neighbors'
// neighbors.
- for (int i = 0; i < viri.Count; i++)
+ for (int i = 0; i < region.Count; i++)
{
// WARNING: Don't use foreach, viri list gets modified.
- testtri.tri = viri[i];
- // A triangle is marked as infected by messing with one of its pointers
- // to subsegments, setting it to an illegal value. Hence, we have to
- // temporarily uninfect this triangle so that we can examine its
- // adjacent subsegments.
- // TODO: Not true in the C# version (so we could skip this).
- testtri.Uninfect();
+ testtri.tri = region[i];
// Apply function.
- func(testtri.tri);
+ action(testtri.tri);
// Check each of the triangle's three neighbors.
for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
@@ -63,64 +112,24 @@ namespace TriangleNet.Meshing.Iterators
// Make sure the neighbor exists, is not already infected, and
// isn't protected by a subsegment.
if ((neighbor.tri.id != Mesh.DUMMY) && !neighbor.IsInfected()
- && (neighborsubseg.seg.hash == Mesh.DUMMY))
+ && protector(neighborsubseg.seg))
{
// Infect the neighbor.
neighbor.Infect();
// Ensure that the neighbor's neighbors will be infected.
- viri.Add(neighbor.tri);
+ region.Add(neighbor.tri);
}
}
- // Remark the triangle as infected, so it doesn't get added to the
- // virus pool again.
- testtri.Infect();
}
// Uninfect all triangles.
- foreach (var virus in viri)
+ foreach (var virus in region)
{
virus.infected = false;
}
// Empty the virus pool.
- viri.Clear();
- }
-
- ///
- /// Set the region attribute of all trianlges connected to given triangle.
- ///
- public void Process(Triangle triangle)
- {
- // Default action is to just set the region id for all trianlges.
- this.Process(triangle, (tri) =>
- {
- tri.label = triangle.label;
- tri.area = triangle.area;
- });
- }
-
- ///
- /// Process all trianlges connected to given triangle and apply given action.
- ///
- public void Process(Triangle triangle, Action func)
- {
- if (triangle.id != Mesh.DUMMY)
- {
- // Make sure the triangle under consideration still exists.
- // It may have been eaten by the virus.
- if (!Otri.IsDead(triangle))
- {
- // Put one triangle in the virus pool.
- triangle.infected = true;
- viri.Add(triangle);
- // Apply one region's attribute and/or area constraint.
- ProcessRegion(func);
- // The virus pool should be empty now.
- }
- }
-
- // Free up memory (virus pool should be empty anyway).
- viri.Clear();
+ region.Clear();
}
}
}