Added public access to Mesh.Behavior,
Removed all Mesh.SetOption(...) stuff git-svn-id: https://triangle.svn.codeplex.com/svn@71809 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
@@ -79,7 +79,7 @@ namespace MeshExplorer
|
||||
|
||||
renderData = new RenderData();
|
||||
}
|
||||
|
||||
|
||||
private void Form1_KeyUp(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.KeyCode)
|
||||
@@ -438,19 +438,19 @@ namespace MeshExplorer
|
||||
|
||||
if (meshControlView.ParamConformDelChecked)
|
||||
{
|
||||
mesh.SetOption(Options.ConformingDelaunay, true);
|
||||
mesh.Behavior.ConformingDelaunay = true;
|
||||
}
|
||||
|
||||
if (meshControlView.ParamSweeplineChecked)
|
||||
{
|
||||
mesh.SetOption(Options.TriangulationAlgorithm, TriangulationAlgorithm.SweepLine);
|
||||
mesh.Behavior.Algorithm = TriangulationAlgorithm.SweepLine;
|
||||
}
|
||||
|
||||
if (meshControlView.ParamQualityChecked)
|
||||
{
|
||||
mesh.SetOption(Options.Quality, true);
|
||||
mesh.Behavior.Quality = true;
|
||||
|
||||
mesh.SetOption(Options.MinAngle, meshControlView.ParamMinAngleValue);
|
||||
mesh.Behavior.MinAngle = meshControlView.ParamMinAngleValue;
|
||||
|
||||
// Ignore area constraints on initial triangulation.
|
||||
|
||||
@@ -459,13 +459,13 @@ namespace MeshExplorer
|
||||
//{
|
||||
// var size = input.Bounds;
|
||||
// double min = Math.Min(size.Width, size.Height);
|
||||
// mesh.SetOption(Options.MaxArea, area * min);
|
||||
// mesh.Behavior.MaxArea, area * min);
|
||||
//}
|
||||
}
|
||||
|
||||
if (meshControlView.ParamConvexChecked)
|
||||
{
|
||||
mesh.SetOption(Options.Convex, true);
|
||||
mesh.Behavior.Convex = true;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -502,10 +502,10 @@ namespace MeshExplorer
|
||||
|
||||
if (area > 0 && area < 1)
|
||||
{
|
||||
mesh.SetOption(Options.MaxArea, area * statisticView.Statistic.LargestArea);
|
||||
mesh.Behavior.MaxArea = area * statisticView.Statistic.LargestArea;
|
||||
}
|
||||
|
||||
mesh.SetOption(Options.MinAngle, meshControlView.ParamMinAngleValue);
|
||||
mesh.Behavior.MinAngle = meshControlView.ParamMinAngleValue;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -8,43 +8,93 @@
|
||||
namespace TriangleNet
|
||||
{
|
||||
using System;
|
||||
using TriangleNet.Log;
|
||||
|
||||
/// <summary>
|
||||
/// Controls the behavior of the meshing software.
|
||||
/// </summary>
|
||||
public class Behavior
|
||||
{
|
||||
#region Class members
|
||||
|
||||
bool poly = false;
|
||||
bool quality = false;
|
||||
bool varArea = false;
|
||||
bool usertest = false;
|
||||
bool convex = false;
|
||||
bool jettison = false;
|
||||
bool boundaryMarkers = true;
|
||||
bool noHoles = false;
|
||||
bool conformDel = false;
|
||||
TriangulationAlgorithm algorithm = TriangulationAlgorithm.Dwyer;
|
||||
|
||||
int noBisect = 0;
|
||||
int steiner = -1;
|
||||
|
||||
double minAngle = 0.0;
|
||||
double maxAngle = 0.0;
|
||||
double maxArea = -1.0;
|
||||
|
||||
internal bool fixedArea = false;
|
||||
internal bool useSegments = true;
|
||||
internal bool useRegions = false;
|
||||
internal double goodAngle = 0.0;
|
||||
internal double maxGoodAngle = 0.0;
|
||||
internal double offconstant = 0.0;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Load behavior defaults.
|
||||
/// Creates an instance of the Behavior class.
|
||||
/// </summary>
|
||||
public Behavior()
|
||||
public Behavior(bool quality = false, double minAngle = 20.0)
|
||||
{
|
||||
Poly = false;
|
||||
Quality = false;
|
||||
VarArea = false;
|
||||
FixedArea = false;
|
||||
Usertest = false;
|
||||
UseRegions = false;
|
||||
Convex = false;
|
||||
Jettison = false;
|
||||
UseBoundaryMarkers = true;
|
||||
NoHoles = false;
|
||||
ConformDel = false;
|
||||
Algorithm = TriangulationAlgorithm.Dwyer;
|
||||
UseSegments = true;
|
||||
if (quality)
|
||||
{
|
||||
this.quality = true;
|
||||
this.minAngle = minAngle;
|
||||
|
||||
NoBisect = 0;
|
||||
Steiner = -1;
|
||||
Update();
|
||||
}
|
||||
}
|
||||
|
||||
MinAngle = 0.0;
|
||||
GoodAngle = 0.0;
|
||||
MaxAngle = 0.0;
|
||||
MaxGoodAngle = 0.0;
|
||||
MaxArea = -1.0;
|
||||
Offconstant = 0.0;
|
||||
/// <summary>
|
||||
/// Update quality options dependencies.
|
||||
/// </summary>
|
||||
private void Update()
|
||||
{
|
||||
this.quality = true;
|
||||
|
||||
Verbose = true;
|
||||
NoExact = false;
|
||||
if (this.minAngle < 0 || this.minAngle > 60)
|
||||
{
|
||||
this.minAngle = 0;
|
||||
this.quality = false;
|
||||
|
||||
SimpleLog.Instance.Warning("Invalid quality option (minimum angle).", "Mesh.Behavior");
|
||||
}
|
||||
|
||||
if ((this.maxAngle != 0.0) && this.maxAngle < 90 || this.maxAngle > 180)
|
||||
{
|
||||
this.maxAngle = 0;
|
||||
this.quality = false;
|
||||
|
||||
SimpleLog.Instance.Warning("Invalid quality option (maximum angle).", "Mesh.Behavior");
|
||||
}
|
||||
|
||||
this.useSegments = this.Poly || this.Quality || this.Convex;
|
||||
this.goodAngle = Math.Cos(this.MinAngle * Math.PI / 180.0);
|
||||
this.maxGoodAngle = Math.Cos(this.MaxAngle * Math.PI / 180.0);
|
||||
|
||||
if (this.goodAngle == 1.0)
|
||||
{
|
||||
this.offconstant = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.offconstant = 0.475 * Math.Sqrt((1.0 + this.goodAngle) / (1.0 - this.goodAngle));
|
||||
}
|
||||
|
||||
this.goodAngle *= this.goodAngle;
|
||||
}
|
||||
|
||||
#region Static properties
|
||||
@@ -63,92 +113,163 @@ namespace TriangleNet
|
||||
|
||||
#region Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Input is a Planar Straight Line Graph.
|
||||
/// </summary>
|
||||
public bool Poly { get; set; }
|
||||
/// <summary>
|
||||
/// Quality mesh generation.
|
||||
/// </summary>
|
||||
public bool Quality { get; set; }
|
||||
/// <summary>
|
||||
/// Apply a maximum triangle area constraint.
|
||||
/// </summary>
|
||||
public bool VarArea { get; set; }
|
||||
/// <summary>
|
||||
/// Apply a maximum triangle area constraint.
|
||||
/// </summary>
|
||||
public bool FixedArea { get; set; }
|
||||
/// <summary>
|
||||
/// Apply a user-defined triangle constraint.
|
||||
/// </summary>
|
||||
public bool Usertest { get; set; }
|
||||
/// <summary>
|
||||
/// Identify triangles in certain regions.
|
||||
/// </summary>
|
||||
public bool UseRegions { get; set; }
|
||||
/// <summary>
|
||||
/// Enclose the convex hull with segments.
|
||||
/// </summary>
|
||||
public bool Convex { get; set; }
|
||||
/// <summary>
|
||||
/// Jettison unused vertices from output.
|
||||
/// </summary>
|
||||
public bool Jettison { get; set; }
|
||||
/// <summary>
|
||||
/// Compute boundary information.
|
||||
/// </summary>
|
||||
public bool UseBoundaryMarkers { get; set; }
|
||||
/// <summary>
|
||||
/// Ignores holes in polygons.
|
||||
/// </summary>
|
||||
public bool NoHoles { get; set; }
|
||||
/// <summary>
|
||||
/// Conforming Delaunay (all triangles are truly Delaunay).
|
||||
/// </summary>
|
||||
public bool ConformDel { get; set; }
|
||||
/// <summary>
|
||||
/// Algorithm to use for triangulation.
|
||||
/// </summary>
|
||||
public TriangulationAlgorithm Algorithm { get; set; }
|
||||
/// <summary>
|
||||
/// Use segments (should not be set manually)
|
||||
/// </summary>
|
||||
public bool UseSegments { get; set; } // TODO: internal set
|
||||
|
||||
/// <summary>
|
||||
/// Suppresses boundary segment splitting.
|
||||
/// </summary>
|
||||
public int NoBisect { get; set; } // <- int !
|
||||
/// <summary>
|
||||
/// Use maximum number of added Steiner points.
|
||||
/// </summary>
|
||||
public int Steiner { get; set; }
|
||||
public bool Quality
|
||||
{
|
||||
get { return quality; }
|
||||
set
|
||||
{
|
||||
quality = value;
|
||||
if (quality)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimum angle constraint.
|
||||
/// </summary>
|
||||
public double MinAngle { get; set; }
|
||||
/// <summary>
|
||||
/// (should not be set manually)
|
||||
/// </summary>
|
||||
public double GoodAngle { get; set; }
|
||||
/// <summary>
|
||||
/// (should not be set manually)
|
||||
/// </summary>
|
||||
public double Offconstant { get; set; }
|
||||
/// <summary>
|
||||
/// Maximum area constraint.
|
||||
/// </summary>
|
||||
public double MaxArea { get; set; }
|
||||
public double MinAngle
|
||||
{
|
||||
get { return minAngle; }
|
||||
set { minAngle = value; Update(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maximum angle constraint.
|
||||
/// </summary>
|
||||
public double MaxAngle { get; set; }
|
||||
public double MaxAngle
|
||||
{
|
||||
get { return maxAngle; }
|
||||
set { maxAngle = value; Update(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (should not be set manually)
|
||||
/// Maximum area constraint.
|
||||
/// </summary>
|
||||
public double MaxGoodAngle { get; set; }
|
||||
public double MaxArea
|
||||
{
|
||||
get { return maxArea; }
|
||||
set
|
||||
{
|
||||
maxArea = value;
|
||||
fixedArea = value > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply a maximum triangle area constraint.
|
||||
/// </summary>
|
||||
public bool VarArea
|
||||
{
|
||||
get { return varArea; }
|
||||
set { varArea = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input is a Planar Straight Line Graph.
|
||||
/// </summary>
|
||||
public bool Poly
|
||||
{
|
||||
get { return poly; }
|
||||
set { poly = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply a user-defined triangle constraint.
|
||||
/// </summary>
|
||||
public bool Usertest
|
||||
{
|
||||
get { return usertest; }
|
||||
set { usertest = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enclose the convex hull with segments.
|
||||
/// </summary>
|
||||
public bool Convex
|
||||
{
|
||||
get { return convex; }
|
||||
set { convex = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conforming Delaunay (all triangles are truly Delaunay).
|
||||
/// </summary>
|
||||
public bool ConformingDelaunay
|
||||
{
|
||||
get { return conformDel; }
|
||||
set { conformDel = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Algorithm to use for triangulation.
|
||||
/// </summary>
|
||||
public TriangulationAlgorithm Algorithm
|
||||
{
|
||||
get { return algorithm; }
|
||||
set { algorithm = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Suppresses boundary segment splitting.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 0 = split segments
|
||||
/// 1 = no new vertices on the boundary
|
||||
/// 2 = prevent all segment splitting, including internal boundaries
|
||||
/// </remarks>
|
||||
public int NoBisect
|
||||
{
|
||||
get { return noBisect; }
|
||||
set
|
||||
{
|
||||
noBisect = value;
|
||||
if (noBisect < 0 || noBisect > 2)
|
||||
{
|
||||
noBisect = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use maximum number of Steiner points.
|
||||
/// </summary>
|
||||
public int SteinerPoints
|
||||
{
|
||||
get { return steiner; }
|
||||
set { steiner = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute boundary information.
|
||||
/// </summary>
|
||||
public bool UseBoundaryMarkers
|
||||
{
|
||||
get { return boundaryMarkers; }
|
||||
set { boundaryMarkers = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignores holes in polygons.
|
||||
/// </summary>
|
||||
public bool NoHoles
|
||||
{
|
||||
get { return noHoles; }
|
||||
set { noHoles = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Jettison unused vertices from output.
|
||||
/// </summary>
|
||||
public bool Jettison
|
||||
{
|
||||
get { return jettison; }
|
||||
set { jettison = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -162,6 +162,7 @@ namespace TriangleNet.Data
|
||||
public double Area
|
||||
{
|
||||
get { return this.area; }
|
||||
set { this.area = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -7,53 +7,6 @@
|
||||
|
||||
namespace TriangleNet
|
||||
{
|
||||
/// <summary>
|
||||
/// Mesh generation options.
|
||||
/// </summary>
|
||||
public enum Options
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimum angle constraint (numeric).
|
||||
/// </summary>
|
||||
MinAngle,
|
||||
/// <summary>
|
||||
/// Maximum angle constraint (numeric).
|
||||
/// </summary>
|
||||
MaxAngle,
|
||||
/// <summary>
|
||||
/// Global maximum area constraint (numeric).
|
||||
/// </summary>
|
||||
MaxArea,
|
||||
/// <summary>
|
||||
/// Maximum number of Steiner points (interger).
|
||||
/// </summary>
|
||||
SteinerPoints,
|
||||
/// <summary>
|
||||
/// No new vertices on the boundary (interger).
|
||||
/// </summary>
|
||||
NoBisect,
|
||||
/// <summary>
|
||||
/// Generate conforming Delaunay triangulations (boolean).
|
||||
/// </summary>
|
||||
ConformingDelaunay,
|
||||
/// <summary>
|
||||
/// Use boundary markers (boolean).
|
||||
/// </summary>
|
||||
BoundaryMarkers,
|
||||
/// <summary>
|
||||
/// Set default values for quality mesh generation (boolean).
|
||||
/// </summary>
|
||||
Quality,
|
||||
/// <summary>
|
||||
/// Create segments on the convex hull (boolean).
|
||||
/// </summary>
|
||||
Convex,
|
||||
/// <summary>
|
||||
/// Algorithm used for triangulation (TriangulationAlgorithm).
|
||||
/// </summary>
|
||||
TriangulationAlgorithm
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Implemented triangulation algorithms.
|
||||
/// </summary>
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace TriangleNet.Geometry
|
||||
/// <summary>
|
||||
/// Triangle area constraint.
|
||||
/// </summary>
|
||||
double Area { get; }
|
||||
double Area { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Region ID the triangle belongs to.
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace TriangleNet.IO
|
||||
{
|
||||
Otri tri = default(Otri);
|
||||
Vertex p1, p2, p3;
|
||||
bool regions = mesh.behavior.UseRegions;
|
||||
bool regions = mesh.behavior.useRegions;
|
||||
|
||||
int j = 0;
|
||||
|
||||
@@ -311,7 +311,7 @@ namespace TriangleNet.IO
|
||||
{
|
||||
// Edge number, indices of two endpoints, and a boundary marker.
|
||||
// If there's no subsegment, the boundary marker is zero.
|
||||
if (behavior.UseSegments)
|
||||
if (behavior.useSegments)
|
||||
{
|
||||
tri.SegPivot(ref checkmark);
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ namespace TriangleNet.IO
|
||||
/// </summary>
|
||||
public double Area
|
||||
{
|
||||
get { return -1; }
|
||||
get { return area; }
|
||||
set { area = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+62
-202
@@ -87,6 +87,14 @@ namespace TriangleNet
|
||||
|
||||
#region Public properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mesh behavior instance.
|
||||
/// </summary>
|
||||
public Behavior Behavior
|
||||
{
|
||||
get { return this.behavior; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mesh bounding box.
|
||||
/// </summary>
|
||||
@@ -166,12 +174,22 @@ namespace TriangleNet
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Mesh" /> class.
|
||||
/// </summary>
|
||||
public Mesh()
|
||||
: this(new Behavior())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Mesh" /> class.
|
||||
/// </summary>
|
||||
public Mesh(Behavior behavior)
|
||||
{
|
||||
this.behavior = behavior;
|
||||
|
||||
logger = SimpleLog.Instance;
|
||||
|
||||
behavior = new Behavior();
|
||||
@@ -253,10 +271,10 @@ namespace TriangleNet
|
||||
|
||||
// Be careful not to add an extra attribute to each element unless the
|
||||
// input supports it (PSLG in, but not refining a preexisting mesh).
|
||||
behavior.UseRegions = false;
|
||||
behavior.useRegions = false;
|
||||
}
|
||||
|
||||
behavior.UseRegions = input.Regions.Count > 0;
|
||||
behavior.useRegions = input.Regions.Count > 0;
|
||||
|
||||
TransferNodes(input);
|
||||
|
||||
@@ -286,10 +304,8 @@ namespace TriangleNet
|
||||
{
|
||||
ResetData();
|
||||
|
||||
if (input.HasSegments)
|
||||
{
|
||||
behavior.Poly = true;
|
||||
}
|
||||
behavior.Poly = input.HasSegments;
|
||||
//behavior.useSegments = input.HasSegments;
|
||||
|
||||
//if (input.EdgeMarkers != null)
|
||||
//{
|
||||
@@ -305,12 +321,12 @@ namespace TriangleNet
|
||||
|
||||
// Be careful not to add an extra attribute to each element unless the
|
||||
// input supports it (PSLG in, but not refining a preexisting mesh).
|
||||
behavior.UseRegions = false;
|
||||
behavior.useRegions = false;
|
||||
}
|
||||
|
||||
behavior.UseRegions = input.Regions.Count > 0;
|
||||
behavior.useRegions = input.Regions.Count > 0;
|
||||
|
||||
steinerleft = behavior.Steiner;
|
||||
steinerleft = behavior.SteinerPoints;
|
||||
|
||||
TransferNodes(input);
|
||||
|
||||
@@ -322,7 +338,7 @@ namespace TriangleNet
|
||||
infvertex2 = null;
|
||||
infvertex3 = null;
|
||||
|
||||
if (behavior.UseSegments)
|
||||
if (behavior.useSegments)
|
||||
{
|
||||
// Segments will be introduced next.
|
||||
checksegments = true;
|
||||
@@ -364,7 +380,7 @@ namespace TriangleNet
|
||||
|
||||
if (behavior.Quality && (triangles.Count > 0))
|
||||
{
|
||||
quality.EnforceQuality(); // Enforce angle and area constraints.
|
||||
quality.EnforceQuality(); // Enforce angle and area constraints.
|
||||
}
|
||||
|
||||
// Calculate the number of edges.
|
||||
@@ -408,13 +424,13 @@ namespace TriangleNet
|
||||
/// <param name="areaConstraint">Global area constraint.</param>
|
||||
public void Refine(double areaConstraint)
|
||||
{
|
||||
behavior.FixedArea = true;
|
||||
behavior.fixedArea = true;
|
||||
behavior.MaxArea = areaConstraint;
|
||||
|
||||
this.Refine();
|
||||
|
||||
// Reset option for sanity
|
||||
behavior.FixedArea = false;
|
||||
behavior.fixedArea = false;
|
||||
behavior.MaxArea = -1.0;
|
||||
}
|
||||
|
||||
@@ -430,7 +446,7 @@ namespace TriangleNet
|
||||
|
||||
if (behavior.Poly)
|
||||
{
|
||||
if (behavior.UseSegments)
|
||||
if (behavior.useSegments)
|
||||
{
|
||||
insegments = subsegs.Count;
|
||||
}
|
||||
@@ -442,7 +458,7 @@ namespace TriangleNet
|
||||
|
||||
Reset();
|
||||
|
||||
steinerleft = behavior.Steiner;
|
||||
steinerleft = behavior.SteinerPoints;
|
||||
|
||||
// Ensure that no vertex can be mistaken for a triangular bounding
|
||||
// box vertex in insertvertex().
|
||||
@@ -450,7 +466,7 @@ namespace TriangleNet
|
||||
infvertex2 = null;
|
||||
infvertex3 = null;
|
||||
|
||||
if (behavior.UseSegments)
|
||||
if (behavior.useSegments)
|
||||
{
|
||||
checksegments = true;
|
||||
}
|
||||
@@ -543,162 +559,6 @@ namespace TriangleNet
|
||||
isDelaunay = quality.CheckDelaunay();
|
||||
}
|
||||
|
||||
#region Options
|
||||
|
||||
/// <summary>
|
||||
/// Set options for mesh generation.
|
||||
/// </summary>
|
||||
/// <param name="option">Mesh gerneration option.</param>
|
||||
/// <param name="value">New option value.</param>
|
||||
public void SetOption(Options option, bool value)
|
||||
{
|
||||
if (option == Options.ConformingDelaunay)
|
||||
{
|
||||
behavior.ConformDel = value;
|
||||
behavior.Quality = value; // TODO: ok?
|
||||
return;
|
||||
}
|
||||
else if (option == Options.BoundaryMarkers)
|
||||
{
|
||||
behavior.UseBoundaryMarkers = value;
|
||||
return;
|
||||
}
|
||||
else if (option == Options.Quality)
|
||||
{
|
||||
behavior.Quality = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
behavior.MinAngle = 20.0;
|
||||
behavior.MaxAngle = 0.0;
|
||||
UpdateOptions();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (option == Options.Convex)
|
||||
{
|
||||
behavior.Convex = value;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.Warning("Invalid option value.", "Mesh.SetOption(bool)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set options for mesh generation.
|
||||
/// </summary>
|
||||
/// <param name="option">Mesh gerneration option.</param>
|
||||
/// <param name="value">New option value.</param>
|
||||
public void SetOption(Options option, double value)
|
||||
{
|
||||
|
||||
if (option == Options.MinAngle)
|
||||
{
|
||||
behavior.MinAngle = value;
|
||||
behavior.Quality = (value >= 0); // TODO: ok?
|
||||
UpdateOptions();
|
||||
return;
|
||||
}
|
||||
else if (option == Options.MaxAngle)
|
||||
{
|
||||
behavior.MaxAngle = value;
|
||||
behavior.Quality = (value >= 0); // TODO: ok?
|
||||
UpdateOptions();
|
||||
return;
|
||||
}
|
||||
else if (option == Options.MaxArea)
|
||||
{
|
||||
behavior.MaxArea = value;
|
||||
behavior.FixedArea = true;
|
||||
behavior.Quality = (value >= 0); // TODO: ok?
|
||||
return;
|
||||
}
|
||||
|
||||
logger.Warning("Invalid option value.", "Mesh.SetOption(double)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set options for mesh generation.
|
||||
/// </summary>
|
||||
/// <param name="option">Mesh gerneration option.</param>
|
||||
/// <param name="value">New option value.</param>
|
||||
public void SetOption(Options option, int value)
|
||||
{
|
||||
if (option == Options.NoBisect)
|
||||
{
|
||||
behavior.NoBisect = value;
|
||||
return;
|
||||
}
|
||||
else if (option == Options.SteinerPoints)
|
||||
{
|
||||
behavior.Steiner = value;
|
||||
return;
|
||||
}
|
||||
else if (option == Options.MinAngle)
|
||||
{
|
||||
behavior.MinAngle = value;
|
||||
behavior.Quality = (value >= 0); // TODO: ok?
|
||||
UpdateOptions();
|
||||
return;
|
||||
}
|
||||
else if (option == Options.MaxAngle)
|
||||
{
|
||||
behavior.MaxAngle = value;
|
||||
behavior.Quality = (value >= 0); // TODO: ok?
|
||||
UpdateOptions();
|
||||
return;
|
||||
}
|
||||
else if (option == Options.MaxArea)
|
||||
{
|
||||
behavior.MaxArea = value;
|
||||
behavior.Quality = (value >= 0); // TODO: ok?
|
||||
behavior.FixedArea = true;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.Warning("Invalid option value.", "Mesh.SetOption(int)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set options for mesh generation.
|
||||
/// </summary>
|
||||
/// <param name="option">Mesh gerneration option.</param>
|
||||
/// <param name="value">New option value.</param>
|
||||
public void SetOption(Options option, TriangulationAlgorithm value)
|
||||
{
|
||||
if (option == Options.TriangulationAlgorithm)
|
||||
{
|
||||
behavior.Algorithm = value;
|
||||
return;
|
||||
}
|
||||
|
||||
logger.Warning("Invalid option value.", "Mesh.SetOption(TriangulationAlgorithm)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps options synchronized.
|
||||
/// </summary>
|
||||
private void UpdateOptions()
|
||||
{
|
||||
behavior.UseSegments = behavior.Poly || behavior.Quality || behavior.Convex;
|
||||
behavior.GoodAngle = Math.Cos(behavior.MinAngle * Math.PI / 180.0);
|
||||
behavior.MaxGoodAngle = Math.Cos(behavior.MaxAngle * Math.PI / 180.0);
|
||||
|
||||
if (behavior.GoodAngle == 1.0)
|
||||
{
|
||||
behavior.Offconstant = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
behavior.Offconstant = 0.475 * Math.Sqrt((1.0 + behavior.GoodAngle) / (1.0 - behavior.GoodAngle));
|
||||
}
|
||||
|
||||
behavior.GoodAngle *= behavior.GoodAngle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
|
||||
/// <summary>
|
||||
@@ -819,7 +679,7 @@ namespace TriangleNet
|
||||
dummytri.neighbors[1].triangle = dummytri;
|
||||
dummytri.neighbors[2].triangle = dummytri;
|
||||
|
||||
if (behavior.UseSegments)
|
||||
if (behavior.useSegments)
|
||||
{
|
||||
// Set up 'dummysub', the omnipresent subsegment pointed to by any
|
||||
// triangle side or subsegment end that isn't attached to a real
|
||||
@@ -872,6 +732,34 @@ namespace TriangleNet
|
||||
this.bounds = data.Bounds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a mapping from vertices to triangles to improve the speed of
|
||||
/// point location for segment insertion.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Traverses all the triangles, and provides each corner of each triangle
|
||||
/// with a pointer to that triangle. Of course, pointers will be overwritten
|
||||
/// by other pointers because (almost) each vertex is a corner of several
|
||||
/// triangles, but in the end every vertex will point to some triangle
|
||||
/// that contains it.
|
||||
/// </remarks>
|
||||
internal void MakeVertexMap()
|
||||
{
|
||||
Otri tri = default(Otri);
|
||||
Vertex triorg;
|
||||
|
||||
foreach (var t in this.triangles.Values)
|
||||
{
|
||||
tri.triangle = t;
|
||||
// Check all three vertices of the triangle.
|
||||
for (tri.orient = 0; tri.orient < 3; tri.orient++)
|
||||
{
|
||||
triorg = tri.Org();
|
||||
triorg.tri = tri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory
|
||||
@@ -2096,34 +1984,6 @@ namespace TriangleNet
|
||||
|
||||
#region Location
|
||||
|
||||
/// <summary>
|
||||
/// Construct a mapping from vertices to triangles to improve the speed of
|
||||
/// point location for segment insertion.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Traverses all the triangles, and provides each corner of each triangle
|
||||
/// with a pointer to that triangle. Of course, pointers will be overwritten
|
||||
/// by other pointers because (almost) each vertex is a corner of several
|
||||
/// triangles, but in the end every vertex will point to some triangle
|
||||
/// that contains it.
|
||||
/// </remarks>
|
||||
internal void MakeVertexMap()
|
||||
{
|
||||
Otri tri = default(Otri);
|
||||
Vertex triorg;
|
||||
|
||||
foreach (var t in this.triangles.Values)
|
||||
{
|
||||
tri.triangle = t;
|
||||
// Check all three vertices of the triangle.
|
||||
for (tri.orient = 0; tri.orient < 3; tri.orient++)
|
||||
{
|
||||
triorg = tri.Org();
|
||||
triorg.tri = tri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a triangle or edge containing a given point.
|
||||
/// </summary>
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace TriangleNet
|
||||
private Point FindNewLocationWithoutMaxAngle(Vertex torg, Vertex tdest, Vertex tapex,
|
||||
ref double xi, ref double eta, bool offcenter, Otri badotri)
|
||||
{
|
||||
double offconstant = behavior.Offconstant;
|
||||
double offconstant = behavior.offconstant;
|
||||
|
||||
// for calculating the distances of the edges
|
||||
double xdo, ydo, xao, yao, xda, yda;
|
||||
@@ -769,7 +769,7 @@ namespace TriangleNet
|
||||
private Point FindNewLocation(Vertex torg, Vertex tdest, Vertex tapex,
|
||||
ref double xi, ref double eta, bool offcenter, Otri badotri)
|
||||
{
|
||||
double offconstant = behavior.Offconstant;
|
||||
double offconstant = behavior.offconstant;
|
||||
|
||||
// for calculating the distances of the edges
|
||||
double xdo, ydo, xao, yao, xda, yda;
|
||||
@@ -2530,7 +2530,7 @@ namespace TriangleNet
|
||||
// minimum angle
|
||||
alpha = behavior.MinAngle * Math.PI / 180.0;
|
||||
// initialize the constants
|
||||
if (behavior.GoodAngle == 1.0)
|
||||
if (behavior.goodAngle == 1.0)
|
||||
{
|
||||
petalcenterconstant = 0;
|
||||
petalradiusconstant = 0;
|
||||
@@ -2701,7 +2701,7 @@ namespace TriangleNet
|
||||
/// IF THERE IS A FEASIBLE INTERSECTION POLYGON, FIND ITS CENTROID AS THE NEW LOCATION
|
||||
FindPolyCentroid(numpolypoints, initialConvexPoly, ref newloc);
|
||||
|
||||
if (behavior.FixedArea)
|
||||
if (behavior.fixedArea)
|
||||
{
|
||||
// numBadTriangle = 0;
|
||||
// for(j= 0; j < numpoints *2-2; j = j+2){
|
||||
@@ -2800,7 +2800,7 @@ namespace TriangleNet
|
||||
cosBeta = Math.Cos(beta);
|
||||
|
||||
// initialize the constants
|
||||
if (behavior.GoodAngle == 1.0)
|
||||
if (behavior.goodAngle == 1.0)
|
||||
{
|
||||
petalcenterconstant = 0;
|
||||
petalradiusconstant = 0;
|
||||
@@ -3293,7 +3293,7 @@ namespace TriangleNet
|
||||
cosAngle = (dist12 + dist23 - dist31) / (2 * Math.Sqrt(dist12) * Math.Sqrt(dist23));
|
||||
// Check whether the angle is smaller than permitted which is 2*minangle!!!
|
||||
//printf("angle: %f 2*minangle = %f\n",acos(cosAngle)*180/PI, 2*acos(Math.Sqrt(b.goodangle))*180/PI);
|
||||
if (Math.Acos(cosAngle) < 2 * Math.Acos(Math.Sqrt(behavior.GoodAngle)))
|
||||
if (Math.Acos(cosAngle) < 2 * Math.Acos(Math.Sqrt(behavior.goodAngle)))
|
||||
{
|
||||
return true;// it is a BAD triangle
|
||||
}
|
||||
@@ -4018,7 +4018,7 @@ namespace TriangleNet
|
||||
|
||||
|
||||
// Check whether the angle is smaller than permitted.
|
||||
if ((angle > behavior.GoodAngle) || (behavior.MaxAngle != 0.00 && maxangle < behavior.MaxGoodAngle))
|
||||
if ((angle > behavior.goodAngle) || (behavior.MaxAngle != 0.00 && maxangle < behavior.maxGoodAngle))
|
||||
{
|
||||
return true;// it is a bad triangle
|
||||
}
|
||||
|
||||
@@ -284,9 +284,9 @@ namespace TriangleNet
|
||||
(eorg.y - eapex.y) * (edest.y - eapex.y);
|
||||
if (dotproduct < 0.0)
|
||||
{
|
||||
if (behavior.ConformDel ||
|
||||
if (behavior.ConformingDelaunay ||
|
||||
(dotproduct * dotproduct >=
|
||||
(2.0 * behavior.GoodAngle - 1.0) * (2.0 * behavior.GoodAngle - 1.0) *
|
||||
(2.0 * behavior.goodAngle - 1.0) * (2.0 * behavior.goodAngle - 1.0) *
|
||||
((eorg.x - eapex.x) * (eorg.x - eapex.x) +
|
||||
(eorg.y - eapex.y) * (eorg.y - eapex.y)) *
|
||||
((edest.x - eapex.x) * (edest.x - eapex.x) +
|
||||
@@ -311,9 +311,9 @@ namespace TriangleNet
|
||||
(eorg.y - eapex.y) * (edest.y - eapex.y);
|
||||
if (dotproduct < 0.0)
|
||||
{
|
||||
if (behavior.ConformDel ||
|
||||
if (behavior.ConformingDelaunay ||
|
||||
(dotproduct * dotproduct >=
|
||||
(2.0 * behavior.GoodAngle - 1.0) * (2.0 * behavior.GoodAngle - 1.0) *
|
||||
(2.0 * behavior.goodAngle - 1.0) * (2.0 * behavior.goodAngle - 1.0) *
|
||||
((eorg.x - eapex.x) * (eorg.x - eapex.x) +
|
||||
(eorg.y - eapex.y) * (eorg.y - eapex.y)) *
|
||||
((edest.x - eapex.x) * (edest.x - eapex.x) +
|
||||
@@ -428,11 +428,11 @@ namespace TriangleNet
|
||||
testtri.Lprev(ref tri1);
|
||||
}
|
||||
|
||||
if (behavior.VarArea || behavior.FixedArea || behavior.Usertest)
|
||||
if (behavior.VarArea || behavior.fixedArea || behavior.Usertest)
|
||||
{
|
||||
// Check whether the area is larger than permitted.
|
||||
area = 0.5 * (dxod * dyda - dyod * dxda);
|
||||
if (behavior.FixedArea && (area > behavior.MaxArea))
|
||||
if (behavior.fixedArea && (area > behavior.MaxArea))
|
||||
{
|
||||
// Add this triangle to the list of bad triangles.
|
||||
queue.Enqueue(ref testtri, minedge, tapex, torg, tdest);
|
||||
@@ -482,7 +482,7 @@ namespace TriangleNet
|
||||
}
|
||||
|
||||
// Check whether the angle is smaller than permitted.
|
||||
if ((angle > behavior.GoodAngle) || (maxangle < behavior.MaxGoodAngle && behavior.MaxAngle != 0.0))
|
||||
if ((angle > behavior.goodAngle) || (maxangle < behavior.maxGoodAngle && behavior.MaxAngle != 0.0))
|
||||
{
|
||||
// Use the rules of Miller, Pav, and Walkington to decide that certain
|
||||
// triangles should not be split, even if they have bad angles.
|
||||
@@ -648,7 +648,7 @@ namespace TriangleNet
|
||||
// If we're using Chew's algorithm (rather than Ruppert's)
|
||||
// to define encroachment, delete free vertices from the
|
||||
// subsegment's diametral circle.
|
||||
if (!behavior.ConformDel && !acuteorg && !acutedest)
|
||||
if (!behavior.ConformingDelaunay && !acuteorg && !acutedest)
|
||||
{
|
||||
eapex = enctri.Apex();
|
||||
while ((eapex.type == VertexType.FreeVertex) &&
|
||||
@@ -678,7 +678,7 @@ namespace TriangleNet
|
||||
acuteorg = acuteorg || acuteorg2;
|
||||
|
||||
// Delete free vertices from the subsegment's diametral circle.
|
||||
if (!behavior.ConformDel && !acuteorg2 && !acutedest2)
|
||||
if (!behavior.ConformingDelaunay && !acuteorg2 && !acutedest2)
|
||||
{
|
||||
eapex = testtri.Org();
|
||||
while ((eapex.type == VertexType.FreeVertex) &&
|
||||
@@ -849,9 +849,9 @@ namespace TriangleNet
|
||||
// for mesh refinement.
|
||||
// TODO: NewLocation doesn't work for refinement. Why? Maybe
|
||||
// reset VertexType?
|
||||
if (behavior.FixedArea || behavior.VarArea)
|
||||
if (behavior.fixedArea || behavior.VarArea)
|
||||
{
|
||||
newloc = Primitives.FindCircumcenter(borg, bdest, bapex, ref xi, ref eta, behavior.Offconstant);
|
||||
newloc = Primitives.FindCircumcenter(borg, bdest, bapex, ref xi, ref eta, behavior.offconstant);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -962,7 +962,7 @@ namespace TriangleNet
|
||||
// triangulation should be (conforming) Delaunay.
|
||||
|
||||
// Next, we worry about enforcing triangle quality.
|
||||
if ((behavior.MinAngle > 0.0) || behavior.VarArea || behavior.FixedArea || behavior.Usertest)
|
||||
if ((behavior.MinAngle > 0.0) || behavior.VarArea || behavior.fixedArea || behavior.Usertest)
|
||||
{
|
||||
// TODO: Reset queue? (Or is it always empty at this point)
|
||||
|
||||
@@ -992,7 +992,7 @@ namespace TriangleNet
|
||||
// and have no low-quality triangles.
|
||||
|
||||
// Might we have run out of Steiner points too soon?
|
||||
if (Behavior.Verbose && behavior.ConformDel && (badsubsegs.Count > 0) && (mesh.steinerleft == 0))
|
||||
if (Behavior.Verbose && behavior.ConformingDelaunay && (badsubsegs.Count > 0) && (mesh.steinerleft == 0))
|
||||
{
|
||||
|
||||
logger.Warning("I ran out of Steiner points, but the mesh has encroached subsegments, "
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace TriangleNet.Smoothing
|
||||
|
||||
public void Smooth()
|
||||
{
|
||||
mesh.SetOption(Options.Quality, false);
|
||||
mesh.behavior.Quality = false;
|
||||
|
||||
// Take a few smoothing rounds.
|
||||
for (int i = 0; i < 5; i++)
|
||||
|
||||
Reference in New Issue
Block a user