Update region iterator.
git-svn-id: https://triangle.svn.codeplex.com/svn@79514 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
@@ -13,23 +13,78 @@ namespace TriangleNet.Meshing.Iterators
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default action is to set the region id and area constraint.
|
||||
/// </remarks>
|
||||
public class RegionIterator
|
||||
{
|
||||
List<Triangle> viri;
|
||||
List<Triangle> region;
|
||||
|
||||
public RegionIterator(Mesh mesh)
|
||||
{
|
||||
this.viri = new List<Triangle>();
|
||||
this.region = new List<Triangle>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the region attribute of all trianlges connected to given triangle.
|
||||
/// </summary>
|
||||
/// <param name="triangle">The triangle seed.</param>
|
||||
/// <param name="boundary">If non-zero, process all triangles of the
|
||||
/// region that is enclosed by segments with given boundary label.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process all trianlges connected to given triangle and apply given action.
|
||||
/// </summary>
|
||||
/// <param name="triangle">The seeding triangle.</param>
|
||||
/// <param name="action">The action to apply to each triangle.</param>
|
||||
/// <param name="boundary">If non-zero, process all triangles of the
|
||||
/// region that is enclosed by segments with given boundary label.</param>
|
||||
public void Process(Triangle triangle, Action<Triangle> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply given action to each triangle of selected region.
|
||||
/// </summary>
|
||||
/// <param name="func"></param>
|
||||
void ProcessRegion(Action<Triangle> func)
|
||||
/// <param name="action"></param>
|
||||
/// <param name="protector"></param>
|
||||
void ProcessRegion(Action<Triangle> action, Func<SubSegment, bool> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the region attribute of all trianlges connected to given triangle.
|
||||
/// </summary>
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process all trianlges connected to given triangle and apply given action.
|
||||
/// </summary>
|
||||
public void Process(Triangle triangle, Action<Triangle> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user