diff --git a/Triangle.NET/TestApp/FormMain.cs b/Triangle.NET/TestApp/FormMain.cs index 555a21d..8846c48 100644 --- a/Triangle.NET/TestApp/FormMain.cs +++ b/Triangle.NET/TestApp/FormMain.cs @@ -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 { diff --git a/Triangle.NET/Triangle/Behavior.cs b/Triangle.NET/Triangle/Behavior.cs index 979f60f..8d4c87a 100644 --- a/Triangle.NET/Triangle/Behavior.cs +++ b/Triangle.NET/Triangle/Behavior.cs @@ -8,43 +8,93 @@ namespace TriangleNet { using System; + using TriangleNet.Log; /// /// Controls the behavior of the meshing software. /// 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 + /// - /// Load behavior defaults. + /// Creates an instance of the Behavior class. /// - 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; + /// + /// Update quality options dependencies. + /// + 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 - /// - /// Input is a Planar Straight Line Graph. - /// - public bool Poly { get; set; } /// /// Quality mesh generation. /// - public bool Quality { get; set; } - /// - /// Apply a maximum triangle area constraint. - /// - public bool VarArea { get; set; } - /// - /// Apply a maximum triangle area constraint. - /// - public bool FixedArea { get; set; } - /// - /// Apply a user-defined triangle constraint. - /// - public bool Usertest { get; set; } - /// - /// Identify triangles in certain regions. - /// - public bool UseRegions { get; set; } - /// - /// Enclose the convex hull with segments. - /// - public bool Convex { get; set; } - /// - /// Jettison unused vertices from output. - /// - public bool Jettison { get; set; } - /// - /// Compute boundary information. - /// - public bool UseBoundaryMarkers { get; set; } - /// - /// Ignores holes in polygons. - /// - public bool NoHoles { get; set; } - /// - /// Conforming Delaunay (all triangles are truly Delaunay). - /// - public bool ConformDel { get; set; } - /// - /// Algorithm to use for triangulation. - /// - public TriangulationAlgorithm Algorithm { get; set; } - /// - /// Use segments (should not be set manually) - /// - public bool UseSegments { get; set; } // TODO: internal set - - /// - /// Suppresses boundary segment splitting. - /// - public int NoBisect { get; set; } // <- int ! - /// - /// Use maximum number of added Steiner points. - /// - public int Steiner { get; set; } + public bool Quality + { + get { return quality; } + set + { + quality = value; + if (quality) + { + Update(); + } + } + } /// /// Minimum angle constraint. /// - public double MinAngle { get; set; } - /// - /// (should not be set manually) - /// - public double GoodAngle { get; set; } - /// - /// (should not be set manually) - /// - public double Offconstant { get; set; } - /// - /// Maximum area constraint. - /// - public double MaxArea { get; set; } + public double MinAngle + { + get { return minAngle; } + set { minAngle = value; Update(); } + } + /// /// Maximum angle constraint. /// - public double MaxAngle { get; set; } + public double MaxAngle + { + get { return maxAngle; } + set { maxAngle = value; Update(); } + } + /// - /// (should not be set manually) + /// Maximum area constraint. /// - public double MaxGoodAngle { get; set; } + public double MaxArea + { + get { return maxArea; } + set + { + maxArea = value; + fixedArea = value > 0; + } + } + + /// + /// Apply a maximum triangle area constraint. + /// + public bool VarArea + { + get { return varArea; } + set { varArea = value; } + } + + /// + /// Input is a Planar Straight Line Graph. + /// + public bool Poly + { + get { return poly; } + set { poly = value; } + } + + /// + /// Apply a user-defined triangle constraint. + /// + public bool Usertest + { + get { return usertest; } + set { usertest = value; } + } + + /// + /// Enclose the convex hull with segments. + /// + public bool Convex + { + get { return convex; } + set { convex = value; } + } + + /// + /// Conforming Delaunay (all triangles are truly Delaunay). + /// + public bool ConformingDelaunay + { + get { return conformDel; } + set { conformDel = value; } + } + + /// + /// Algorithm to use for triangulation. + /// + public TriangulationAlgorithm Algorithm + { + get { return algorithm; } + set { algorithm = value; } + } + + /// + /// Suppresses boundary segment splitting. + /// + /// + /// 0 = split segments + /// 1 = no new vertices on the boundary + /// 2 = prevent all segment splitting, including internal boundaries + /// + public int NoBisect + { + get { return noBisect; } + set + { + noBisect = value; + if (noBisect < 0 || noBisect > 2) + { + noBisect = 0; + } + } + } + + /// + /// Use maximum number of Steiner points. + /// + public int SteinerPoints + { + get { return steiner; } + set { steiner = value; } + } + + /// + /// Compute boundary information. + /// + public bool UseBoundaryMarkers + { + get { return boundaryMarkers; } + set { boundaryMarkers = value; } + } + + /// + /// Ignores holes in polygons. + /// + public bool NoHoles + { + get { return noHoles; } + set { noHoles = value; } + } + + /// + /// Jettison unused vertices from output. + /// + public bool Jettison + { + get { return jettison; } + set { jettison = value; } + } #endregion } diff --git a/Triangle.NET/Triangle/Data/Triangle.cs b/Triangle.NET/Triangle/Data/Triangle.cs index 2777590..82ddf4b 100644 --- a/Triangle.NET/Triangle/Data/Triangle.cs +++ b/Triangle.NET/Triangle/Data/Triangle.cs @@ -162,6 +162,7 @@ namespace TriangleNet.Data public double Area { get { return this.area; } + set { this.area = value; } } /// diff --git a/Triangle.NET/Triangle/Enums.cs b/Triangle.NET/Triangle/Enums.cs index 0668d17..fc094bc 100644 --- a/Triangle.NET/Triangle/Enums.cs +++ b/Triangle.NET/Triangle/Enums.cs @@ -7,53 +7,6 @@ namespace TriangleNet { - /// - /// Mesh generation options. - /// - public enum Options - { - /// - /// Minimum angle constraint (numeric). - /// - MinAngle, - /// - /// Maximum angle constraint (numeric). - /// - MaxAngle, - /// - /// Global maximum area constraint (numeric). - /// - MaxArea, - /// - /// Maximum number of Steiner points (interger). - /// - SteinerPoints, - /// - /// No new vertices on the boundary (interger). - /// - NoBisect, - /// - /// Generate conforming Delaunay triangulations (boolean). - /// - ConformingDelaunay, - /// - /// Use boundary markers (boolean). - /// - BoundaryMarkers, - /// - /// Set default values for quality mesh generation (boolean). - /// - Quality, - /// - /// Create segments on the convex hull (boolean). - /// - Convex, - /// - /// Algorithm used for triangulation (TriangulationAlgorithm). - /// - TriangulationAlgorithm - }; - /// /// Implemented triangulation algorithms. /// diff --git a/Triangle.NET/Triangle/Geometry/ITriangle.cs b/Triangle.NET/Triangle/Geometry/ITriangle.cs index 75d9201..bde827a 100644 --- a/Triangle.NET/Triangle/Geometry/ITriangle.cs +++ b/Triangle.NET/Triangle/Geometry/ITriangle.cs @@ -77,7 +77,7 @@ namespace TriangleNet.Geometry /// /// Triangle area constraint. /// - double Area { get; } + double Area { get; set; } /// /// Region ID the triangle belongs to. diff --git a/Triangle.NET/Triangle/IO/FileWriter.cs b/Triangle.NET/Triangle/IO/FileWriter.cs index 1d7b2ed..b13f6d5 100644 --- a/Triangle.NET/Triangle/IO/FileWriter.cs +++ b/Triangle.NET/Triangle/IO/FileWriter.cs @@ -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); diff --git a/Triangle.NET/Triangle/IO/InputTriangle.cs b/Triangle.NET/Triangle/IO/InputTriangle.cs index 68b6e0e..626c356 100644 --- a/Triangle.NET/Triangle/IO/InputTriangle.cs +++ b/Triangle.NET/Triangle/IO/InputTriangle.cs @@ -102,7 +102,8 @@ namespace TriangleNet.IO /// public double Area { - get { return -1; } + get { return area; } + set { area = value; } } /// diff --git a/Triangle.NET/Triangle/Mesh.cs b/Triangle.NET/Triangle/Mesh.cs index c8312b7..5b8e00a 100644 --- a/Triangle.NET/Triangle/Mesh.cs +++ b/Triangle.NET/Triangle/Mesh.cs @@ -87,6 +87,14 @@ namespace TriangleNet #region Public properties + /// + /// Gets the mesh behavior instance. + /// + public Behavior Behavior + { + get { return this.behavior; } + } + /// /// Gets the mesh bounding box. /// @@ -166,12 +174,22 @@ namespace TriangleNet } #endregion - + /// /// Initializes a new instance of the class. /// public Mesh() + : this(new Behavior()) { + } + + /// + /// Initializes a new instance of the class. + /// + 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 /// Global area constraint. 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 - - /// - /// Set options for mesh generation. - /// - /// Mesh gerneration option. - /// New option value. - 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)"); - } - - /// - /// Set options for mesh generation. - /// - /// Mesh gerneration option. - /// New option value. - 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)"); - } - - /// - /// Set options for mesh generation. - /// - /// Mesh gerneration option. - /// New option value. - 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)"); - } - - /// - /// Set options for mesh generation. - /// - /// Mesh gerneration option. - /// New option value. - public void SetOption(Options option, TriangulationAlgorithm value) - { - if (option == Options.TriangulationAlgorithm) - { - behavior.Algorithm = value; - return; - } - - logger.Warning("Invalid option value.", "Mesh.SetOption(TriangulationAlgorithm)"); - } - - /// - /// Keeps options synchronized. - /// - 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 /// @@ -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; } + /// + /// Construct a mapping from vertices to triangles to improve the speed of + /// point location for segment insertion. + /// + /// + /// 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. + /// + 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 - /// - /// Construct a mapping from vertices to triangles to improve the speed of - /// point location for segment insertion. - /// - /// - /// 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. - /// - 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; - } - } - } - /// /// Find a triangle or edge containing a given point. /// diff --git a/Triangle.NET/Triangle/NewLocation.cs b/Triangle.NET/Triangle/NewLocation.cs index 9ffb8d0..4018ba0 100644 --- a/Triangle.NET/Triangle/NewLocation.cs +++ b/Triangle.NET/Triangle/NewLocation.cs @@ -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 } diff --git a/Triangle.NET/Triangle/Quality.cs b/Triangle.NET/Triangle/Quality.cs index d47fa60..a70d8a8 100644 --- a/Triangle.NET/Triangle/Quality.cs +++ b/Triangle.NET/Triangle/Quality.cs @@ -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, " diff --git a/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs b/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs index 1a19466..8f82731 100644 --- a/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs +++ b/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs @@ -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++)