More code reorganization (7)
git-svn-id: https://triangle.svn.codeplex.com/svn@77331 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
+15
-128
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -321,130 +324,14 @@ namespace TriangleNet
|
||||
}
|
||||
|
||||
#region Misc
|
||||
|
||||
/// <summary>
|
||||
/// Triangulate given input data.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refines the current mesh.
|
||||
/// Set QualityMesher for mesh refinement.
|
||||
/// </summary>
|
||||
internal void Refine()
|
||||
/// <param name="qmesher"></param>
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Triangulate given input data.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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.
|
||||
/// </summary>
|
||||
public void FormSkeleton(IPolygon input)
|
||||
private void FormSkeleton(IPolygon input)
|
||||
{
|
||||
// The segment endpoints.
|
||||
Vertex p, q;
|
||||
|
||||
@@ -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
|
||||
/// <param name="nx">Number of segments in x direction.</param>
|
||||
/// <param name="ny">Number of segments in y direction.</param>
|
||||
/// <returns>Mesh</returns>
|
||||
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
|
||||
/// <param name="nx">Number of segments in x direction.</param>
|
||||
/// <param name="ny">Number of segments in y direction.</param>
|
||||
/// <returns>Mesh</returns>
|
||||
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));
|
||||
|
||||
|
||||
@@ -45,6 +45,51 @@ namespace TriangleNet.Meshing
|
||||
newLocation = new NewLocation(mesh, predicates);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triangulate given input data.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a bad subsegment to the queue.
|
||||
/// </summary>
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Remove all the encroached subsegments and bad triangles from the triangulation.
|
||||
/// </summary>
|
||||
public void EnforceQuality()
|
||||
private void EnforceQuality()
|
||||
{
|
||||
BadTriangle badtri;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user