diff --git a/Triangle.NET/TestApp/FormTopology.cs b/Triangle.NET/TestApp/FormTopology.cs
index c2889be..3600993 100644
--- a/Triangle.NET/TestApp/FormTopology.cs
+++ b/Triangle.NET/TestApp/FormTopology.cs
@@ -22,8 +22,7 @@ namespace MeshExplorer
private void FormTopology_Load(object sender, EventArgs e)
{
- var mesher = new GenericMesher();
- mesh = (Mesh)mesher.StructuredMesh(new Rectangle(0.0, 0.0, 4.0, 4.0), 4, 4);
+ mesh = (Mesh)GenericMesher.StructuredMesh(new Rectangle(0.0, 0.0, 4.0, 4.0), 4, 4);
renderControl.Initialize(mesh);
diff --git a/Triangle.NET/Triangle/Mesh.cs b/Triangle.NET/Triangle/Mesh.cs
index a9cce7a..39a359b 100644
--- a/Triangle.NET/Triangle/Mesh.cs
+++ b/Triangle.NET/Triangle/Mesh.cs
@@ -252,20 +252,23 @@ namespace TriangleNet
this.predicates = predicates;
- this.qualityMesher = new QualityMesher(this, predicates);
-
this.locator = new TriangleLocator(this, predicates);
}
public void Refine(QualityOptions quality)
{
- behavior.MinAngle = quality.MinimumAngle;
- behavior.MaxAngle = quality.MaximumAngle;
+ inelements = triangles.Count;
+ invertices = vertices.Count;
- behavior.MaxArea = quality.MaximumArea;
- behavior.VarArea = quality.VariableArea;
+ if (behavior.Poly)
+ {
+ insegments = behavior.useSegments ? subsegs.Count : hullsize;
+ }
- this.Refine();
+ Reset();
+
+ // Enforce angle and area constraints.
+ qualityMesher.Apply(quality);
}
///
@@ -321,130 +324,14 @@ namespace TriangleNet
}
#region Misc
-
- ///
- /// Triangulate given input data.
- ///
- ///
- internal void ApplyConstraints(IPolygon input, ConstraintOptions options, QualityOptions quality)
- {
- behavior.Poly = input.Segments.Count > 0;
-
- // Copy constraint options
- if (options != null)
- {
- behavior.ConformingDelaunay = options.ConformingDelaunay;
- behavior.Convex = options.Convex;
- behavior.NoBisect = options.SegmentSplitting;
-
- if (behavior.ConformingDelaunay)
- {
- behavior.Quality = true;
- }
- }
-
- // Copy quality options
- if (quality != null)
- {
- behavior.Quality = true;
-
- behavior.MinAngle = quality.MinimumAngle;
- behavior.MaxAngle = quality.MaximumAngle;
- behavior.MaxArea = quality.MaximumArea;
- behavior.UserTest = quality.UserTest;
-
- steinerleft = quality.SteinerPoints == 0 ? -1 : quality.SteinerPoints;
- }
-
- //if (input.EdgeMarkers != null)
- //{
- // behavior.UseBoundaryMarkers = true;
- //}
-
- // TODO: remove
- if (!behavior.Poly)
- {
- // Be careful not to allocate space for element area constraints that
- // will never be assigned any value (other than the default -1.0).
- behavior.VarArea = false;
- }
-
- behavior.useRegions = input.Regions.Count > 0;
-
- // Ensure that no vertex can be mistaken for a triangular bounding
- // box vertex in insertvertex().
- infvertex1 = null;
- infvertex2 = null;
- infvertex3 = null;
-
- // Insert segments, carving holes.
- var mesher = new ConstraintMesher(this, predicates);
-
- if (behavior.useSegments)
- {
- // Segments will be introduced next.
- checksegments = true;
-
- // Insert PSLG segments and/or convex hull segments.
- mesher.FormSkeleton(input);
- }
-
- if (behavior.Poly && (triangles.Count > 0))
- {
- // Copy holes
- foreach (var item in input.Holes)
- {
- holes.Add(item);
- }
-
- // Copy regions
- foreach (var item in input.Regions)
- {
- regions.Add(item);
- }
-
- // Carve out holes and concavities.
- mesher.CarveHoles();
- }
-
- if (behavior.Quality && triangles.Count > 0)
- {
- // Enforce angle and area constraints.
- qualityMesher.EnforceQuality();
- }
- }
///
- /// Refines the current mesh.
+ /// Set QualityMesher for mesh refinement.
///
- internal void Refine()
+ ///
+ internal void SetQualityMesher(QualityMesher qmesher)
{
- inelements = triangles.Count;
- invertices = vertices.Count;
-
- // TODO: Set all vertex types to input (i.e. NOT free)?
-
- if (behavior.Poly)
- {
- insegments = behavior.useSegments ? subsegs.Count : hullsize;
- }
-
- Reset();
-
- // Ensure that no vertex can be mistaken for a triangular bounding
- // box vertex in insertvertex().
- infvertex1 = infvertex2 = infvertex3 = null;
-
- if (behavior.useSegments)
- {
- checksegments = true;
- }
-
- if (triangles.Count > 0)
- {
- // Enforce angle and area constraints.
- qualityMesher.EnforceQuality();
- }
+ qualityMesher = qmesher;
}
internal void CopyTo(Mesh target)
@@ -535,7 +422,7 @@ namespace TriangleNet
// Simple heuristic to check if ids are already set. We assume that if the
// first two vertex ids are distinct, then all input vertices have pairwise
// distinct ids.
- bool userId = (v.ID != points[1].ID);
+ bool userId = (v.id != points[1].id);
foreach (var p in points)
{
diff --git a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs
index 7e83a53..c5af9ec 100644
--- a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs
+++ b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs
@@ -9,10 +9,10 @@ namespace TriangleNet.Meshing
{
using System;
using System.Collections.Generic;
- using TriangleNet.Topology;
using TriangleNet.Geometry;
using TriangleNet.Logging;
using TriangleNet.Meshing.Iterators;
+ using TriangleNet.Topology;
internal class ConstraintMesher
{
@@ -39,12 +39,67 @@ namespace TriangleNet.Meshing
logger = Log.Instance;
}
+
+ ///
+ /// Triangulate given input data.
+ ///
+ ///
+ public void Apply(IPolygon input, ConstraintOptions options)
+ {
+ behavior.Poly = input.Segments.Count > 0;
+
+ // Copy constraint options
+ if (options != null)
+ {
+ behavior.ConformingDelaunay = options.ConformingDelaunay;
+ behavior.Convex = options.Convex;
+ behavior.NoBisect = options.SegmentSplitting;
+
+ if (behavior.ConformingDelaunay)
+ {
+ behavior.Quality = true;
+ }
+ }
+
+ //if (input.EdgeMarkers != null)
+ //{
+ // behavior.UseBoundaryMarkers = true;
+ //}
+
+ behavior.useRegions = input.Regions.Count > 0;
+
+ // Ensure that no vertex can be mistaken for a triangular bounding
+ // box vertex in insertvertex().
+ mesh.infvertex1 = null;
+ mesh.infvertex2 = null;
+ mesh.infvertex3 = null;
+
+ if (behavior.useSegments)
+ {
+ // Segments will be introduced next.
+ mesh.checksegments = true;
+
+ // Insert PSLG segments and/or convex hull segments.
+ FormSkeleton(input);
+ }
+
+ if (behavior.Poly && (mesh.triangles.Count > 0))
+ {
+ // Copy holes and regions
+ mesh.holes.AddRange(input.Holes);
+ mesh.regions.AddRange(input.Regions);
+
+ // Carve out holes and concavities.
+ CarveHoles();
+ }
+ }
+
///
/// Find the holes and infect them. Find the area constraints and infect
/// them. Infect the convex hull. Spread the infection and kill triangles.
/// Spread the area constraints.
///
- public void CarveHoles()
+ private void CarveHoles()
{
Otri searchtri = default(Otri);
Vertex searchorg, searchdest;
@@ -171,7 +226,7 @@ namespace TriangleNet.Meshing
/// Create the segments of a triangulation, including PSLG segments and edges
/// on the convex hull.
///
- public void FormSkeleton(IPolygon input)
+ private void FormSkeleton(IPolygon input)
{
// The segment endpoints.
Vertex p, q;
diff --git a/Triangle.NET/Triangle/Meshing/GenericMesher.cs b/Triangle.NET/Triangle/Meshing/GenericMesher.cs
index cc3b3bb..d7e2dfe 100644
--- a/Triangle.NET/Triangle/Meshing/GenericMesher.cs
+++ b/Triangle.NET/Triangle/Meshing/GenericMesher.cs
@@ -23,7 +23,7 @@ namespace TriangleNet.Meshing
public GenericMesher()
{
- this.predicates = RobustPredicates.Default;
+ this.predicates = new RobustPredicates();
this.triangulator = new Dwyer(this.predicates);
}
@@ -67,7 +67,16 @@ namespace TriangleNet.Meshing
{
var mesh = (Mesh)triangulator.Triangulate(polygon.Points);
- mesh.ApplyConstraints(polygon, options, quality);
+ var cmesher = new ConstraintMesher(mesh, predicates);
+ var qmesher = new QualityMesher(mesh, predicates);
+
+ mesh.SetQualityMesher(qmesher);
+
+ // Insert segments.
+ cmesher.Apply(polygon, options);
+
+ // Refine mesh.
+ qmesher.Apply(quality);
return mesh;
}
@@ -80,7 +89,7 @@ namespace TriangleNet.Meshing
/// Number of segments in x direction.
/// Number of segments in y direction.
/// Mesh
- public IMesh StructuredMesh(double width, double height, int nx, int ny)
+ public static IMesh StructuredMesh(double width, double height, int nx, int ny)
{
if (width <= 0.0)
{
@@ -102,7 +111,7 @@ namespace TriangleNet.Meshing
/// Number of segments in x direction.
/// Number of segments in y direction.
/// Mesh
- public IMesh StructuredMesh(Rectangle bounds, int nx, int ny)
+ public static IMesh StructuredMesh(Rectangle bounds, int nx, int ny)
{
var polygon = new Polygon((nx + 1) * (ny + 1));
diff --git a/Triangle.NET/Triangle/Meshing/QualityMesher.cs b/Triangle.NET/Triangle/Meshing/QualityMesher.cs
index cf6f29f..d566463 100644
--- a/Triangle.NET/Triangle/Meshing/QualityMesher.cs
+++ b/Triangle.NET/Triangle/Meshing/QualityMesher.cs
@@ -45,6 +45,51 @@ namespace TriangleNet.Meshing
newLocation = new NewLocation(mesh, predicates);
}
+ ///
+ /// Triangulate given input data.
+ ///
+ ///
+ public void Apply(QualityOptions quality)
+ {
+ // Copy quality options
+ if (quality != null)
+ {
+ behavior.Quality = true;
+
+ behavior.MinAngle = quality.MinimumAngle;
+ behavior.MaxAngle = quality.MaximumAngle;
+ behavior.MaxArea = quality.MaximumArea;
+ behavior.UserTest = quality.UserTest;
+
+ mesh.steinerleft = quality.SteinerPoints == 0 ? -1 : quality.SteinerPoints;
+ }
+
+ // TODO: remove
+ if (!behavior.Poly)
+ {
+ // Be careful not to allocate space for element area constraints that
+ // will never be assigned any value (other than the default -1.0).
+ behavior.VarArea = false;
+ }
+
+ // Ensure that no vertex can be mistaken for a triangular bounding
+ // box vertex in insertvertex().
+ mesh.infvertex1 = null;
+ mesh.infvertex2 = null;
+ mesh.infvertex3 = null;
+
+ if (behavior.useSegments)
+ {
+ mesh.checksegments = true;
+ }
+
+ if (behavior.Quality && mesh.triangles.Count > 0)
+ {
+ // Enforce angle and area constraints.
+ EnforceQuality();
+ }
+ }
+
///
/// Add a bad subsegment to the queue.
///
@@ -272,13 +317,10 @@ namespace TriangleNet.Meshing
}
// Check whether the user thinks this triangle is too large.
- if (behavior.UserTest != null)
+ if ((behavior.UserTest != null) && behavior.UserTest(testtri.tri, area))
{
- if (behavior.UserTest(testtri.tri, area))
- {
- queue.Enqueue(ref testtri, minedge, tapex, torg, tdest);
- return;
- }
+ queue.Enqueue(ref testtri, minedge, tapex, torg, tdest);
+ return;
}
}
@@ -773,7 +815,7 @@ namespace TriangleNet.Meshing
///
/// Remove all the encroached subsegments and bad triangles from the triangulation.
///
- public void EnforceQuality()
+ private void EnforceQuality()
{
BadTriangle badtri;