More code reorganization (2)

git-svn-id: https://triangle.svn.codeplex.com/svn@75022 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
SND\wo80_cp
2014-05-29 19:06:09 +00:00
parent 7384b5fd07
commit faa7d4df47
37 changed files with 227 additions and 258 deletions
+6 -9
View File
@@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TriangleNet.Log;
using TriangleNet;
using TriangleNet.Logging;
namespace MeshExplorer
{
@@ -19,7 +16,7 @@ namespace MeshExplorer
public void AddItem(string message, bool warning)
{
ILog<SimpleLogItem> log = SimpleLog.Instance;
ILog<LogItem> log = Log.Instance;
if (warning)
{
@@ -35,7 +32,7 @@ namespace MeshExplorer
{
listLog.Items.Clear();
ILog<SimpleLogItem> log = SimpleLog.Instance;
ILog<LogItem> log = Log.Instance;
foreach (var item in log.Data)
{
@@ -43,7 +40,7 @@ namespace MeshExplorer
}
}
private ListViewItem CreateListViewItem(SimpleLogItem item)
private ListViewItem CreateListViewItem(LogItem item)
{
ListViewItem lvi = new ListViewItem(new string[] { item.Message, item.Info });
@@ -81,7 +78,7 @@ namespace MeshExplorer
if (ModifierKeys == Keys.Control)
{
listLog.Items.Clear();
SimpleLog.Instance.Clear();
Log.Instance.Clear();
}
}
}
+9 -9
View File
@@ -8,7 +8,7 @@ using MeshExplorer.IO;
using MeshRenderer.Core;
using TriangleNet;
using TriangleNet.Geometry;
using TriangleNet.Log;
using TriangleNet.Logging;
using TriangleNet.Tools;
namespace MeshExplorer
@@ -552,13 +552,13 @@ namespace MeshExplorer
{
if (mesh == null || settings.ExceptionThrown) return;
bool tmp = Behavior.Verbose;
Behavior.Verbose = true;
bool tmp = Log.Verbose;
Log.Verbose = true;
mesh.Renumber(NodeNumbering.CuthillMcKee);
ShowLog();
Behavior.Verbose = tmp;
Log.Verbose = tmp;
}
private void Smooth()
@@ -736,23 +736,23 @@ namespace MeshExplorer
{
if (mesh != null)
{
bool save = Behavior.Verbose;
bool save = Log.Verbose;
Behavior.Verbose = true;
Log.Verbose = true;
bool isConsistent = MeshValidator.IsConsistent(mesh);
bool isDelaunay = MeshValidator.IsDelaunay(mesh);
Behavior.Verbose = save;
Log.Verbose = save;
if (isConsistent)
{
SimpleLog.Instance.Info("Mesh topology appears to be consistent.");
Log.Instance.Info("Mesh topology appears to be consistent.");
}
if (isDelaunay)
{
SimpleLog.Instance.Info("Mesh is (conforming) Delaunay.");
Log.Instance.Info("Mesh is (conforming) Delaunay.");
}
ShowLog();
+1 -1
View File
@@ -10,7 +10,7 @@ namespace MeshExplorer.IO
using System.IO;
using System.Text;
using TriangleNet;
using TriangleNet.Data;
using TriangleNet.Geometry;
/// <summary>
/// Writes a mesh to an SVG file.
+3 -8
View File
@@ -9,7 +9,7 @@ namespace TriangleNet
{
using System;
using TriangleNet.Geometry;
using TriangleNet.Log;
using TriangleNet.Logging;
/// <summary>
/// Controls the behavior of the meshing software.
@@ -72,7 +72,7 @@ namespace TriangleNet
this.minAngle = 0;
this.quality = false;
SimpleLog.Instance.Warning("Invalid quality option (minimum angle).", "Mesh.Behavior");
Log.Instance.Warning("Invalid quality option (minimum angle).", "Mesh.Behavior");
}
if ((this.maxAngle != 0.0) && this.maxAngle < 90 || this.maxAngle > 180)
@@ -80,7 +80,7 @@ namespace TriangleNet
this.maxAngle = 0;
this.quality = false;
SimpleLog.Instance.Warning("Invalid quality option (maximum angle).", "Mesh.Behavior");
Log.Instance.Warning("Invalid quality option (maximum angle).", "Mesh.Behavior");
}
this.useSegments = this.Poly || this.Quality || this.Convex;
@@ -106,11 +106,6 @@ namespace TriangleNet
/// </summary>
public static bool NoExact { get; set; }
/// <summary>
/// Log detailed information.
/// </summary>
public static bool Verbose { get; set; }
#endregion
#region Public properties
+6 -16
View File
@@ -8,9 +8,7 @@
namespace TriangleNet.Data
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
/// <summary>
/// A queue used to store encroached subsegments.
@@ -21,25 +19,17 @@ namespace TriangleNet.Data
/// </remarks>
class BadSubseg
{
private static int hashSeed = 0;
internal int Hash;
public Osub encsubseg; // An encroached subsegment.
public Vertex subsegorg, subsegdest; // Its two vertices.
public BadSubseg()
{
this.Hash = hashSeed++;
}
public Osub subseg; // An encroached subsegment.
public Vertex org, dest; // Its two vertices.
public override int GetHashCode()
{
return this.Hash;
return subseg.seg.hash;
}
public override string ToString()
{
return String.Format("B-SID {0}", encsubseg.seg.hash);
return String.Format("B-SID {0}", subseg.seg.hash);
}
};
}
}
@@ -5,10 +5,9 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet
namespace TriangleNet.Data
{
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Geometry;
/// <summary>
/// A (priority) queue for bad triangles.
@@ -20,7 +19,7 @@ namespace TriangleNet
/// </remarks>
class BadTriQueue
{
static readonly double SQRT2 = 1.4142135623730950488016887242096980785696718753769480732;
const double SQRT2 = 1.4142135623730950488016887242096980785696718753769480732;
public int Count { get { return this.count; } }
@@ -135,12 +134,12 @@ namespace TriangleNet
else
{
// Add the bad triangle to the end of an already nonempty queue.
queuetail[queuenumber].nexttriang = badtri;
queuetail[queuenumber].next = badtri;
}
// Maintain a pointer to the last triangle of the queue.
queuetail[queuenumber] = badtri;
// Newly enqueued bad triangle has no successor in the queue.
badtri.nexttriang = null;
badtri.next = null;
}
/// <summary>
@@ -158,9 +157,9 @@ namespace TriangleNet
newbad.poortri = enqtri;
newbad.key = minedge;
newbad.triangapex = enqapex;
newbad.triangorg = enqorg;
newbad.triangdest = enqdest;
newbad.apex = enqapex;
newbad.org = enqorg;
newbad.dest = enqdest;
Enqueue(newbad);
}
@@ -182,7 +181,7 @@ namespace TriangleNet
// Find the first triangle of the highest-priority queue.
BadTriangle result = queuefront[firstnonemptyq];
// Remove the triangle from the queue.
queuefront[firstnonemptyq] = result.nexttriang;
queuefront[firstnonemptyq] = result.next;
// If this queue is now empty, note the new highest-priority
// nonempty queue.
if (result == queuetail[firstnonemptyq])
+3 -12
View File
@@ -8,9 +8,7 @@
namespace TriangleNet.Data
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
/// <summary>
/// A queue used to store bad triangles.
@@ -22,18 +20,11 @@ namespace TriangleNet.Data
/// </remarks>
class BadTriangle
{
public static int OTID = 0;
public int ID = 0;
public Otri poortri; // A skinny or too-large triangle.
public double key; // cos^2 of smallest (apical) angle.
public Vertex triangorg, triangdest, triangapex; // Its three vertices.
public BadTriangle nexttriang; // Pointer to next bad triangle.
public Vertex org, dest, apex; // Its three vertices.
public BadTriangle next; // Pointer to next bad triangle.
public BadTriangle()
{
ID = OTID++;
}
public override string ToString()
{
return String.Format("B-TID {0}", poortri.triangle.hash);
+1 -3
View File
@@ -8,9 +8,7 @@
namespace TriangleNet.Data
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
/// <summary>
/// An oriented subsegment.
+1 -3
View File
@@ -8,9 +8,7 @@
namespace TriangleNet.Data
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
/// <summary>
/// An oriented triangle.
-3
View File
@@ -8,9 +8,6 @@
namespace TriangleNet.Data
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
/// <summary>
@@ -6,15 +6,11 @@
namespace TriangleNet.Geometry
{
using TriangleNet.Data;
/// <summary>
/// Interface for segment geometry.
/// </summary>
public interface ISegment : IEdge
{
#region Public properties
/// <summary>
/// Gets the segments endpoint.
/// </summary>
@@ -26,7 +22,5 @@ namespace TriangleNet.Geometry
/// </summary>
/// <param name="index">The triangle index (0 or 1).</param>
ITriangle GetTriangle(int index);
#endregion
}
}
+13 -3
View File
@@ -20,8 +20,9 @@ namespace TriangleNet.Geometry
/// Initializes a new instance of the <see cref="Rectangle" /> class.
/// </summary>
public Rectangle()
: this(double.MaxValue, double.MaxValue, -double.MaxValue, -double.MaxValue)
{
this.xmin = this.ymin = double.MaxValue;
this.xmax = this.ymax = -double.MaxValue;
}
public Rectangle(Rectangle other)
@@ -109,8 +110,7 @@ namespace TriangleNet.Geometry
/// <summary>
/// Expand rectangle to include given point.
/// </summary>
/// <param name="x">X coordinate.</param>
/// <param name="p">Y coordinate.</param>
/// <param name="p">Point.</param>
public void Expand(Point p)
{
xmin = Math.Min(xmin, p.x);
@@ -153,12 +153,22 @@ namespace TriangleNet.Geometry
return ((pt.x >= xmin) && (pt.x <= xmax) && (pt.y >= ymin) && (pt.y <= ymax));
}
/// <summary>
/// Check if given rectangle is inside bounding box.
/// </summary>
/// <param name="other">Rectangle to check.</param>
/// <returns>Return true, if bounding box contains given rectangle.</returns>
public bool Contains(Rectangle other)
{
return (xmin <= other.Left && other.Right <= xmax
&& ymin <= other.Bottom && other.Top <= ymax);
}
/// <summary>
/// Check if given rectangle intersects bounding box.
/// </summary>
/// <param name="other">Rectangle to check.</param>
/// <returns>Return true, if given rectangle intersects bounding box.</returns>
public bool Intersects(Rectangle other)
{
return (other.Left < xmax && xmin < other.Right
@@ -5,13 +5,10 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Data
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
using TriangleNet.Data;
/// <summary>
/// The vertex data structure.
+11 -11
View File
@@ -11,7 +11,7 @@ namespace TriangleNet.IO
using System.IO;
using System.Globalization;
using TriangleNet.Data;
using TriangleNet.Log;
using TriangleNet.Logging;
using TriangleNet.Geometry;
using System.Collections.Generic;
@@ -385,17 +385,17 @@ namespace TriangleNet.IO
if ((end1 < 0) || (end1 >= invertices))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("Invalid first endpoint of segment.",
Log.Instance.Warning("Invalid first endpoint of segment.",
"MeshReader.ReadPolyfile()");
}
}
else if ((end2 < 0) || (end2 >= invertices))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("Invalid second endpoint of segment.",
Log.Instance.Warning("Invalid second endpoint of segment.",
"MeshReader.ReadPolyfile()");
}
}
@@ -521,7 +521,7 @@ namespace TriangleNet.IO
if (attributes > 1)
{
SimpleLog.Instance.Warning("Triangle attributes not supported.", "FileReader.Read");
Log.Instance.Warning("Triangle attributes not supported.", "FileReader.Read");
}
triangles = new List<ITriangle>(intriangles);
@@ -593,7 +593,7 @@ namespace TriangleNet.IO
if (int.Parse(line[0]) != intriangles)
{
SimpleLog.Instance.Warning("Number of area constraints doesn't match number of triangles.",
Log.Instance.Warning("Number of area constraints doesn't match number of triangles.",
"ReadAreaFile()");
return null;
}
@@ -684,17 +684,17 @@ namespace TriangleNet.IO
if ((end1 < 0) || (end1 >= invertices))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("Invalid first endpoint of segment.",
Log.Instance.Warning("Invalid first endpoint of segment.",
"MeshReader.ReadPolyfile()");
}
}
else if ((end2 < 0) || (end2 >= invertices))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("Invalid second endpoint of segment.",
Log.Instance.Warning("Invalid second endpoint of segment.",
"MeshReader.ReadPolyfile()");
}
}
+1 -1
View File
@@ -485,7 +485,7 @@ namespace TriangleNet.IO
torg = tri.Org();
tdest = tri.Dest();
tapex = tri.Apex();
circumcenter = Primitives.FindCircumcenter(torg, tdest, tapex, ref xi, ref eta);
circumcenter = RobustPredicates.FindCircumcenter(torg, tdest, tapex, ref xi, ref eta);
// X and y coordinates.
writer.Write("{0} {1} {2}", index, circumcenter.X.ToString(nfi),
@@ -4,12 +4,10 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Log
namespace TriangleNet
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Logging;
/// <summary>
/// A simple logger, which logs messages to a List.
@@ -17,23 +15,28 @@ namespace TriangleNet.Log
/// <remarks>Using singleton pattern as proposed by Jon Skeet.
/// http://csharpindepth.com/Articles/General/Singleton.aspx
/// </remarks>
public sealed class SimpleLog : ILog<SimpleLogItem>
public sealed class Log : ILog<LogItem>
{
private List<SimpleLogItem> log = new List<SimpleLogItem>();
/// <summary>
/// Log detailed information.
/// </summary>
public static bool Verbose { get; set; }
private List<LogItem> log = new List<LogItem>();
private LogLevel level = LogLevel.Info;
#region Singleton pattern
private static readonly SimpleLog instance = new SimpleLog();
private static readonly Log instance = new Log();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static SimpleLog() { }
static Log() { }
private SimpleLog() { }
private Log() { }
public static ILog<SimpleLogItem> Instance
public static ILog<LogItem> Instance
{
get
{
@@ -43,7 +46,7 @@ namespace TriangleNet.Log
#endregion
public void Add(SimpleLogItem item)
public void Add(LogItem item)
{
log.Add(item);
}
@@ -55,20 +58,20 @@ namespace TriangleNet.Log
public void Info(string message)
{
log.Add(new SimpleLogItem(LogLevel.Info, message));
log.Add(new LogItem(LogLevel.Info, message));
}
public void Warning(string message, string location)
{
log.Add(new SimpleLogItem(LogLevel.Warning, message, location));
log.Add(new LogItem(LogLevel.Warning, message, location));
}
public void Error(string message, string location)
{
log.Add(new SimpleLogItem(LogLevel.Error, message, location));
log.Add(new LogItem(LogLevel.Error, message, location));
}
public IList<SimpleLogItem> Data
public IList<LogItem> Data
{
get { return log; }
}
@@ -4,12 +4,9 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Log
namespace TriangleNet.Logging
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public enum LogLevel
{
@@ -4,12 +4,9 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Log
namespace TriangleNet.Logging
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// A basic log item interface.
@@ -4,17 +4,14 @@
// </copyright>
// -----------------------------------------------------------------------
namespace TriangleNet.Log
namespace TriangleNet.Logging
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// Represents an item stored in the log.
/// </summary>
public class SimpleLogItem : ILogItem
public class LogItem : ILogItem
{
DateTime time;
LogLevel level;
@@ -41,11 +38,11 @@ namespace TriangleNet.Log
get { return info; }
}
public SimpleLogItem(LogLevel level, string message)
public LogItem(LogLevel level, string message)
: this(level, message, "")
{ }
public SimpleLogItem(LogLevel level, string message, string info)
public LogItem(LogLevel level, string message, string info)
{
this.time = DateTime.Now;
this.level = level;
+11 -11
View File
@@ -11,7 +11,7 @@ namespace TriangleNet
using System.Collections.Generic;
using System.Linq;
using TriangleNet.Data;
using TriangleNet.Log;
using TriangleNet.Logging;
using TriangleNet.IO;
using TriangleNet.Meshing;
using TriangleNet.Meshing.Algorithm;
@@ -26,7 +26,7 @@ namespace TriangleNet
{
#region Variables
ILog<SimpleLogItem> logger;
ILog<LogItem> logger;
QualityMesher quality;
@@ -188,7 +188,7 @@ namespace TriangleNet
{
this.behavior = behavior;
logger = SimpleLog.Instance;
logger = Log.Instance;
behavior = new Behavior();
@@ -205,7 +205,7 @@ namespace TriangleNet
locator = new TriangleLocator(this);
Primitives.ExactInit();
RobustPredicates.ExactInit();
if (dummytri == null)
{
@@ -858,9 +858,9 @@ namespace TriangleNet
{
// Add the subsegment to the list of encroached subsegments.
encroached = new BadSubseg();
encroached.encsubseg = brokensubseg;
encroached.subsegorg = brokensubseg.Org();
encroached.subsegdest = brokensubseg.Dest();
encroached.subseg = brokensubseg;
encroached.org = brokensubseg.Org();
encroached.dest = brokensubseg.Dest();
quality.AddBadSubseg(encroached);
}
@@ -1133,7 +1133,7 @@ namespace TriangleNet
// the boundary of the triangulation. 'farvertex' might be
// infinite as well, but trust me, this same condition should
// be applied.
doflip = Primitives.CounterClockwise(newvertex, rightvertex, farvertex) > 0.0;
doflip = RobustPredicates.CounterClockwise(newvertex, rightvertex, farvertex) > 0.0;
}
else if ((rightvertex == infvertex1) ||
(rightvertex == infvertex2) ||
@@ -1143,7 +1143,7 @@ namespace TriangleNet
// the boundary of the triangulation. 'farvertex' might be
// infinite as well, but trust me, this same condition should
// be applied.
doflip = Primitives.CounterClockwise(farvertex, leftvertex, newvertex) > 0.0;
doflip = RobustPredicates.CounterClockwise(farvertex, leftvertex, newvertex) > 0.0;
}
else if ((farvertex == infvertex1) ||
(farvertex == infvertex2) ||
@@ -1156,7 +1156,7 @@ namespace TriangleNet
else
{
// Test whether the edge is locally Delaunay.
doflip = Primitives.InCircle(leftvertex, newvertex, rightvertex, farvertex) > 0.0;
doflip = RobustPredicates.InCircle(leftvertex, newvertex, rightvertex, farvertex) > 0.0;
}
if (doflip)
{
@@ -1686,7 +1686,7 @@ namespace TriangleNet
testtri.OnextSelf();
testvertex = testtri.Dest();
// Is this a better vertex?
if (Primitives.InCircle(leftbasevertex, rightbasevertex, bestvertex, testvertex) > 0.0)
if (RobustPredicates.InCircle(leftbasevertex, rightbasevertex, bestvertex, testvertex) > 0.0)
{
testtri.Copy(ref besttri);
bestvertex = testvertex;
+15 -15
View File
@@ -9,7 +9,7 @@ namespace TriangleNet
{
using System;
using TriangleNet.Data;
using TriangleNet.Log;
using TriangleNet.Geometry;
public static class MeshValidator
{
@@ -25,7 +25,7 @@ namespace TriangleNet
int horrors;
bool saveexact;
var logger = SimpleLog.Instance;
var logger = Log.Instance;
// Temporarily turn on exact arithmetic if it's off.
saveexact = Behavior.NoExact;
@@ -47,11 +47,11 @@ namespace TriangleNet
// Only test for inversion once.
// Test if the triangle is flat or inverted.
triapex = tri.Apex();
if (Primitives.CounterClockwise(triorg, tridest, triapex) <= 0.0)
if (RobustPredicates.CounterClockwise(triorg, tridest, triapex) <= 0.0)
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("Triangle is flat or inverted.", "Quality.CheckMesh()");
logger.Warning("Triangle is flat or inverted.", "MeshValidator.IsConsistent()");
}
horrors++;
@@ -66,10 +66,10 @@ namespace TriangleNet
oppotri.Sym(ref oppooppotri);
if ((tri.triangle != oppooppotri.triangle) || (tri.orient != oppooppotri.orient))
{
if (tri.triangle == oppooppotri.triangle && Behavior.Verbose)
if (tri.triangle == oppooppotri.triangle && Log.Verbose)
{
logger.Warning("Asymmetric triangle-triangle bond: (Right triangle, wrong orientation)",
"Quality.CheckMesh()");
"MeshValidator.IsConsistent()");
}
horrors++;
@@ -80,10 +80,10 @@ namespace TriangleNet
oppodest = oppotri.Dest();
if ((triorg != oppodest) || (tridest != oppoorg))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("Mismatched edge coordinates between two triangles.",
"Quality.CheckMesh()");
"MeshValidator.IsConsistent()");
}
horrors++;
@@ -96,10 +96,10 @@ namespace TriangleNet
mesh.MakeVertexMap();
foreach (var v in mesh.vertices.Values)
{
if (v.tri.triangle == null && Behavior.Verbose)
if (v.tri.triangle == null && Log.Verbose)
{
logger.Warning("Vertex (ID " + v.id + ") not connected to mesh (duplicate input vertex?)",
"Quality.CheckMesh()");
"MeshValidator.IsConsistent()");
}
}
@@ -140,7 +140,7 @@ namespace TriangleNet
int horrors;
bool saveexact;
var logger = SimpleLog.Instance;
var logger = Log.Instance;
// Temporarily turn on exact arithmetic if it's off.
saveexact = Behavior.NoExact;
@@ -190,12 +190,12 @@ namespace TriangleNet
if (shouldbedelaunay)
{
if (Primitives.NonRegular(org, dest, apex, oppoapex) > 0.0)
if (RobustPredicates.NonRegular(org, dest, apex, oppoapex) > 0.0)
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning(String.Format("Non-regular pair of triangles found (IDs {0}/{1}).",
loop.triangle.id, oppotri.triangle.id), "Quality.CheckDelaunay()");
loop.triangle.id, oppotri.triangle.id), "MeshValidator.IsDelaunay()");
}
horrors++;
@@ -9,7 +9,8 @@ namespace TriangleNet.Meshing.Algorithm
{
using System;
using TriangleNet.Data;
using TriangleNet.Log;
using TriangleNet.Geometry;
using TriangleNet.Logging;
/// <summary>
/// Builds a delaunay triangulation using the divide-and-conquer algorithm.
@@ -45,7 +46,8 @@ namespace TriangleNet.Meshing.Algorithm
class Dwyer
{
static Random rand = new Random(DateTime.Now.Millisecond);
bool useDwyer = true;
public bool UseDwyer = true;
Vertex[] sortarray;
Mesh mesh;
@@ -314,7 +316,7 @@ namespace TriangleNet.Meshing.Algorithm
innerrightorg = innerright.Org();
innerrightapex = innerright.Apex();
// Special treatment for horizontal cuts.
if (useDwyer && (axis == 1))
if (UseDwyer && (axis == 1))
{
farleftpt = farleft.Org();
farleftapex = farleft.Apex();
@@ -363,7 +365,7 @@ namespace TriangleNet.Meshing.Algorithm
{
changemade = false;
// Make innerleftdest the "bottommost" vertex of the left hull.
if (Primitives.CounterClockwise(innerleftdest, innerleftapex, innerrightorg) > 0.0)
if (RobustPredicates.CounterClockwise(innerleftdest, innerleftapex, innerrightorg) > 0.0)
{
innerleft.LprevSelf();
innerleft.SymSelf();
@@ -372,7 +374,7 @@ namespace TriangleNet.Meshing.Algorithm
changemade = true;
}
// Make innerrightorg the "bottommost" vertex of the right hull.
if (Primitives.CounterClockwise(innerrightapex, innerrightorg, innerleftdest) > 0.0)
if (RobustPredicates.CounterClockwise(innerrightapex, innerrightorg, innerleftdest) > 0.0)
{
innerright.LnextSelf();
innerright.SymSelf();
@@ -420,8 +422,8 @@ namespace TriangleNet.Meshing.Algorithm
// because even though the left triangulation might seem finished now,
// moving up on the right triangulation might reveal a new vertex of
// the left triangulation. And vice-versa.)
leftfinished = Primitives.CounterClockwise(upperleft, lowerleft, lowerright) <= 0.0;
rightfinished = Primitives.CounterClockwise(upperright, lowerleft, lowerright) <= 0.0;
leftfinished = RobustPredicates.CounterClockwise(upperleft, lowerleft, lowerright) <= 0.0;
rightfinished = RobustPredicates.CounterClockwise(upperright, lowerleft, lowerright) <= 0.0;
if (leftfinished && rightfinished)
{
// Create the top new bounding triangle.
@@ -437,7 +439,7 @@ namespace TriangleNet.Meshing.Algorithm
nextedge.Bond(ref leftcand);
// Special treatment for horizontal cuts.
if (useDwyer && (axis == 1))
if (UseDwyer && (axis == 1))
{
farleftpt = farleft.Org();
farleftapex = farleft.Apex();
@@ -478,7 +480,7 @@ namespace TriangleNet.Meshing.Algorithm
if (nextapex != null)
{
// Check whether the edge is Delaunay.
badedge = Primitives.InCircle(lowerleft, lowerright, upperleft, nextapex) > 0.0;
badedge = RobustPredicates.InCircle(lowerleft, lowerright, upperleft, nextapex) > 0.0;
while (badedge)
{
// Eliminate the edge with an edge flip. As a result, the
@@ -508,7 +510,7 @@ namespace TriangleNet.Meshing.Algorithm
if (nextapex != null)
{
// Check whether the edge is Delaunay.
badedge = Primitives.InCircle(lowerleft, lowerright, upperleft, nextapex) > 0.0;
badedge = RobustPredicates.InCircle(lowerleft, lowerright, upperleft, nextapex) > 0.0;
}
else
{
@@ -530,7 +532,7 @@ namespace TriangleNet.Meshing.Algorithm
if (nextapex != null)
{
// Check whether the edge is Delaunay.
badedge = Primitives.InCircle(lowerleft, lowerright, upperright, nextapex) > 0.0;
badedge = RobustPredicates.InCircle(lowerleft, lowerright, upperright, nextapex) > 0.0;
while (badedge)
{
// Eliminate the edge with an edge flip. As a result, the
@@ -560,7 +562,7 @@ namespace TriangleNet.Meshing.Algorithm
if (nextapex != null)
{
// Check whether the edge is Delaunay.
badedge = Primitives.InCircle(lowerleft, lowerright, upperright, nextapex) > 0.0;
badedge = RobustPredicates.InCircle(lowerleft, lowerright, upperright, nextapex) > 0.0;
}
else
{
@@ -571,7 +573,7 @@ namespace TriangleNet.Meshing.Algorithm
}
}
if (leftfinished || (!rightfinished &&
(Primitives.InCircle(upperleft, lowerleft, lowerright, upperright) > 0.0)))
(RobustPredicates.InCircle(upperleft, lowerleft, lowerright, upperright) > 0.0)))
{
// Knit the triangulations, adding an edge from 'lowerleft'
// to 'upperright'.
@@ -660,7 +662,7 @@ namespace TriangleNet.Meshing.Algorithm
mesh.MakeTriangle(ref tri1);
mesh.MakeTriangle(ref tri2);
mesh.MakeTriangle(ref tri3);
area = Primitives.CounterClockwise(sortarray[left], sortarray[left + 1], sortarray[left + 2]);
area = RobustPredicates.CounterClockwise(sortarray[left], sortarray[left + 1], sortarray[left + 2]);
if (area == 0.0)
{
// Three collinear vertices; the triangulation is two edges.
@@ -858,9 +860,9 @@ namespace TriangleNet.Meshing.Algorithm
if ((sortarray[i].x == sortarray[j].x)
&& (sortarray[i].y == sortarray[j].y))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning(
Log.Instance.Warning(
String.Format("A duplicate vertex appeared and was ignored (ID {0}).", sortarray[j].hash),
"DivConquer.DivconqDelaunay()");
}
@@ -874,7 +876,7 @@ namespace TriangleNet.Meshing.Algorithm
}
}
i++;
if (useDwyer)
if (UseDwyer)
{
// Re-sort the array of vertices to accommodate alternating cuts.
divider = i >> 1;
@@ -8,7 +8,7 @@
namespace TriangleNet.Meshing.Algorithm
{
using TriangleNet.Data;
using TriangleNet.Log;
using TriangleNet.Logging;
using TriangleNet.Geometry;
/// <summary>
@@ -165,9 +165,9 @@ namespace TriangleNet.Meshing.Algorithm
Osub tmp = default(Osub);
if (mesh.InsertVertex(v, ref starttri, ref tmp, false, false) == InsertVertexResult.Duplicate)
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("A duplicate vertex appeared and was ignored.",
Log.Instance.Warning("A duplicate vertex appeared and was ignored.",
"Incremental.IncrementalDelaunay()");
}
v.type = VertexType.UndeadVertex;
@@ -11,7 +11,7 @@ namespace TriangleNet.Meshing.Algorithm
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Geometry;
using TriangleNet.Log;
using TriangleNet.Logging;
using TriangleNet.Tools;
/// <summary>
@@ -381,7 +381,7 @@ namespace TriangleNet.Meshing.Algorithm
Point searchpoint = new Point(); // TODO: mesh.nextras
Otri dummytri = default(Otri);
ccwabc = Primitives.CounterClockwise(pa, pb, pc);
ccwabc = RobustPredicates.CounterClockwise(pa, pb, pc);
xac = pa.x - pc.x;
yac = pa.y - pc.y;
xbc = pb.x - pc.x;
@@ -571,7 +571,7 @@ namespace TriangleNet.Meshing.Algorithm
{
if (heapsize == 0)
{
SimpleLog.Instance.Error("Input vertices are all identical.", "SweepLine.Triangulate()");
Log.Instance.Error("Input vertices are all identical.", "SweepLine.Triangulate()");
throw new Exception("Input vertices are all identical.");
}
secondvertex = eventheap[0].vertexEvent;
@@ -580,9 +580,9 @@ namespace TriangleNet.Meshing.Algorithm
if ((firstvertex.x == secondvertex.x) &&
(firstvertex.y == secondvertex.y))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("A duplicate vertex appeared and was ignored (ID " + secondvertex.id + ").",
Log.Instance.Warning("A duplicate vertex appeared and was ignored (ID " + secondvertex.id + ").",
"SweepLine.Triangulate().1");
}
secondvertex.type = VertexType.UndeadVertex;
@@ -636,9 +636,9 @@ namespace TriangleNet.Meshing.Algorithm
if ((nextvertex.x == lastvertex.x) &&
(nextvertex.y == lastvertex.y))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Warning("A duplicate vertex appeared and was ignored (ID " + nextvertex.id + ").",
Log.Instance.Warning("A duplicate vertex appeared and was ignored (ID " + nextvertex.id + ").",
"SweepLine.Triangulate().2");
}
nextvertex.type = VertexType.UndeadVertex;
@@ -700,7 +700,7 @@ namespace TriangleNet.Meshing.Algorithm
leftvertex = farlefttri.Apex();
midvertex = lefttri.Dest();
rightvertex = lefttri.Apex();
lefttest = Primitives.CounterClockwise(leftvertex, midvertex, rightvertex);
lefttest = RobustPredicates.CounterClockwise(leftvertex, midvertex, rightvertex);
if (lefttest > 0.0)
{
newevent = new SweepEvent();
@@ -715,7 +715,7 @@ namespace TriangleNet.Meshing.Algorithm
leftvertex = righttri.Apex();
midvertex = righttri.Org();
rightvertex = farrighttri.Apex();
righttest = Primitives.CounterClockwise(leftvertex, midvertex, rightvertex);
righttest = RobustPredicates.CounterClockwise(leftvertex, midvertex, rightvertex);
if (righttest > 0.0)
{
newevent = new SweepEvent();
@@ -11,7 +11,7 @@ namespace TriangleNet.Meshing
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Geometry;
using TriangleNet.Log;
using TriangleNet.Logging;
using TriangleNet.Tools;
internal class ConstraintMesher
@@ -22,7 +22,7 @@ namespace TriangleNet.Meshing
List<Triangle> viri;
ILog<SimpleLogItem> logger;
ILog<LogItem> logger;
public ConstraintMesher(Mesh mesh)
{
@@ -32,7 +32,7 @@ namespace TriangleNet.Meshing
this.viri = new List<Triangle>();
logger = SimpleLog.Instance;
logger = Log.Instance;
}
/// <summary>
@@ -72,7 +72,7 @@ namespace TriangleNet.Meshing
// falls within the starting triangle.
searchorg = searchtri.Org();
searchdest = searchtri.Dest();
if (Primitives.CounterClockwise(searchorg, searchdest, hole) > 0.0)
if (RobustPredicates.CounterClockwise(searchorg, searchdest, hole) > 0.0)
{
// Find a triangle that contains the hole.
intersect = mesh.locator.Locate(hole, ref searchtri);
@@ -114,7 +114,7 @@ namespace TriangleNet.Meshing
// region point falls within the starting triangle.
searchorg = searchtri.Org();
searchdest = searchtri.Dest();
if (Primitives.CounterClockwise(searchorg, searchdest, region.point) > 0.0)
if (RobustPredicates.CounterClockwise(searchorg, searchdest, region.point) > 0.0)
{
// Find a triangle that contains the region point.
intersect = mesh.locator.Locate(region.point, ref searchtri);
@@ -202,14 +202,14 @@ namespace TriangleNet.Meshing
if ((end1 < 0) || (end1 >= mesh.invertices))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("Invalid first endpoint of segment.", "Mesh.FormSkeleton().1");
}
}
else if ((end2 < 0) || (end2 >= mesh.invertices))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("Invalid second endpoint of segment.", "Mesh.FormSkeleton().2");
}
@@ -224,7 +224,7 @@ namespace TriangleNet.Meshing
endpoint2 = mesh.vertices[end2];
if ((endpoint1.x == endpoint2.x) && (endpoint1.y == endpoint2.y))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("Endpoints of segment (IDs " + end1 + "/" + end2 + ") are coincident.",
"Mesh.FormSkeleton()");
@@ -544,10 +544,10 @@ namespace TriangleNet.Meshing
rightvertex = searchtri.Dest();
leftvertex = searchtri.Apex();
// Is 'searchpoint' to the left?
leftccw = Primitives.CounterClockwise(searchpoint, startvertex, leftvertex);
leftccw = RobustPredicates.CounterClockwise(searchpoint, startvertex, leftvertex);
leftflag = leftccw > 0.0;
// Is 'searchpoint' to the right?
rightccw = Primitives.CounterClockwise(startvertex, searchpoint, rightvertex);
rightccw = RobustPredicates.CounterClockwise(startvertex, searchpoint, rightvertex);
rightflag = rightccw > 0.0;
if (leftflag && rightflag)
{
@@ -574,7 +574,7 @@ namespace TriangleNet.Meshing
}
leftvertex = searchtri.Apex();
rightccw = leftccw;
leftccw = Primitives.CounterClockwise(searchpoint, startvertex, leftvertex);
leftccw = RobustPredicates.CounterClockwise(searchpoint, startvertex, leftvertex);
leftflag = leftccw > 0.0;
}
while (rightflag)
@@ -588,7 +588,7 @@ namespace TriangleNet.Meshing
}
rightvertex = searchtri.Dest();
leftccw = rightccw;
rightccw = Primitives.CounterClockwise(startvertex, searchpoint, rightvertex);
rightccw = RobustPredicates.CounterClockwise(startvertex, searchpoint, rightvertex);
rightflag = rightccw > 0.0;
}
if (leftccw == 0.0)
@@ -867,7 +867,7 @@ namespace TriangleNet.Meshing
// Check whether the previous polygon vertex is a reflex vertex.
if (leftside)
{
if (Primitives.CounterClockwise(nearvertex, leftvertex, farvertex) <= 0.0)
if (RobustPredicates.CounterClockwise(nearvertex, leftvertex, farvertex) <= 0.0)
{
// leftvertex is a reflex vertex too. Nothing can
// be done until a convex section is found.
@@ -876,20 +876,20 @@ namespace TriangleNet.Meshing
}
else
{
if (Primitives.CounterClockwise(farvertex, rightvertex, nearvertex) <= 0.0)
if (RobustPredicates.CounterClockwise(farvertex, rightvertex, nearvertex) <= 0.0)
{
// rightvertex is a reflex vertex too. Nothing can
// be done until a convex section is found.
return;
}
}
if (Primitives.CounterClockwise(rightvertex, leftvertex, farvertex) > 0.0)
if (RobustPredicates.CounterClockwise(rightvertex, leftvertex, farvertex) > 0.0)
{
// fartri is not an inverted triangle, and farvertex is not a reflex
// vertex. As there are no reflex vertices, fixuptri isn't an
// inverted triangle, either. Hence, test the edge between the
// triangles to ensure it is locally Delaunay.
if (Primitives.InCircle(leftvertex, farvertex, rightvertex, nearvertex) <= 0.0)
if (RobustPredicates.InCircle(leftvertex, farvertex, rightvertex, nearvertex) <= 0.0)
{
return;
}
@@ -991,7 +991,7 @@ namespace TriangleNet.Meshing
{
// Check whether farvertex is to the left or right of the segment being
// inserted, to decide which edge of fixuptri to dig through next.
area = Primitives.CounterClockwise(endpoint1, endpoint2, farvertex);
area = RobustPredicates.CounterClockwise(endpoint1, endpoint2, farvertex);
if (area == 0.0)
{
// We've collided with a vertex between endpoint1 and endpoint2.
@@ -26,6 +26,16 @@ namespace TriangleNet.Meshing
/// </summary>
public bool Convex { get; set; }
/// <summary>
/// Suppresses boundary segment splitting.
/// </summary>
/// <remarks>
/// 0 = split segments (default)
/// 1 = no new vertices on the boundary
/// 2 = prevent all segment splitting, including internal boundaries
/// </remarks>
public int SegmentSplitting { get; set; }
#endregion
}
}
+3 -3
View File
@@ -12,7 +12,7 @@ namespace TriangleNet.Meshing
using System.Linq;
using TriangleNet.Data;
using TriangleNet.Geometry;
using TriangleNet.Log;
using TriangleNet.Logging;
/// <summary>
/// The DataReader class provides methods for mesh reconstruction.
@@ -140,7 +140,7 @@ namespace TriangleNet.Meshing
{
if ((corner[j] < 0) || (corner[j] >= mesh.invertices))
{
SimpleLog.Instance.Error("Triangle has an invalid vertex index.", "MeshReader.Reconstruct()");
Log.Instance.Error("Triangle has an invalid vertex index.", "MeshReader.Reconstruct()");
throw new Exception("Triangle has an invalid vertex index.");
}
}
@@ -250,7 +250,7 @@ namespace TriangleNet.Meshing
{
if ((end[j] < 0) || (end[j] >= mesh.invertices))
{
SimpleLog.Instance.Error("Segment has an invalid vertex index.", "MeshReader.Reconstruct()");
Log.Instance.Error("Segment has an invalid vertex index.", "MeshReader.Reconstruct()");
throw new Exception("Segment has an invalid vertex index.");
}
}
@@ -6,16 +6,14 @@
namespace TriangleNet.Meshing
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Geometry;
/// <summary>
/// TODO: Update summary.
/// </summary>
public interface ITriangulator
{
int Triangulate(Mesh mesh);
Mesh Triangulate(ICollection<Vertex> points);
}
}
+20 -20
View File
@@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="Quality.cs">
// <copyright file="QualityMesher.cs">
// Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html
// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
// </copyright>
@@ -10,8 +10,8 @@ namespace TriangleNet.Meshing
using System;
using System.Collections.Generic;
using TriangleNet.Data;
using TriangleNet.Log;
using TriangleNet.Geometry;
using TriangleNet.Logging;
/// <summary>
/// Provides methods for mesh quality enforcement and testing.
@@ -25,11 +25,11 @@ namespace TriangleNet.Meshing
NewLocation newLocation;
ILog<SimpleLogItem> logger;
ILog<LogItem> logger;
public QualityMesher(Mesh mesh)
{
logger = SimpleLog.Instance;
logger = Log.Instance;
badsubsegs = new Queue<BadSubseg>();
queue = new BadTriQueue();
@@ -150,15 +150,15 @@ namespace TriangleNet.Meshing
encroachedseg = new BadSubseg();
if (encroached == 1)
{
encroachedseg.encsubseg = testsubseg;
encroachedseg.subsegorg = eorg;
encroachedseg.subsegdest = edest;
encroachedseg.subseg = testsubseg;
encroachedseg.org = eorg;
encroachedseg.dest = edest;
}
else
{
encroachedseg.encsubseg = testsym;
encroachedseg.subsegorg = edest;
encroachedseg.subsegdest = eorg;
encroachedseg.subseg = testsym;
encroachedseg.org = edest;
encroachedseg.dest = eorg;
}
badsubsegs.Enqueue(encroachedseg);
@@ -430,14 +430,14 @@ namespace TriangleNet.Meshing
seg = badsubsegs.Dequeue();
currentenc = seg.encsubseg;
currentenc = seg.subseg;
eorg = currentenc.Org();
edest = currentenc.Dest();
// Make sure that this segment is still the same segment it was
// when it was determined to be encroached. If the segment was
// enqueued multiple times (because several newly inserted
// vertices encroached it), it may have already been split.
if (!Osub.IsDead(currentenc.seg) && (eorg == seg.subsegorg) && (edest == seg.subsegdest))
if (!Osub.IsDead(currentenc.seg) && (eorg == seg.org) && (edest == seg.dest))
{
// To decide where to split a segment, we need to know if the
// segment shares an endpoint with an adjacent segment.
@@ -569,7 +569,7 @@ namespace TriangleNet.Meshing
// Roundoff in the above calculation may yield a 'newvertex'
// that is not precisely collinear with 'eorg' and 'edest'.
// Improve collinearity by one step of iterative refinement.
multiplier = Primitives.CounterClockwise(eorg, edest, newvertex);
multiplier = RobustPredicates.CounterClockwise(eorg, edest, newvertex);
divisor = ((eorg.x - edest.x) * (eorg.x - edest.x) +
(eorg.y - edest.y) * (eorg.y - edest.y));
if ((multiplier != 0.0) && (divisor != 0.0))
@@ -615,7 +615,7 @@ namespace TriangleNet.Meshing
// Set subsegment's origin to NULL. This makes it possible to detect dead
// badsubsegs when traversing the list of all badsubsegs.
seg.subsegorg = null;
seg.org = null;
}
}
@@ -658,8 +658,8 @@ namespace TriangleNet.Meshing
// Make sure that this triangle is still the same triangle it was
// when it was tested and determined to be of bad quality.
// Subsequent transformations may have made it a different triangle.
if (!Otri.IsDead(badotri.triangle) && (borg == badtri.triangorg) &&
(bdest == badtri.triangdest) && (bapex == badtri.triangapex))
if (!Otri.IsDead(badotri.triangle) && (borg == badtri.org) &&
(bdest == badtri.dest) && (bapex == badtri.apex))
{
errorflag = false;
// Create a new vertex at the triangle's circumcenter.
@@ -670,7 +670,7 @@ namespace TriangleNet.Meshing
// reset VertexType?
if (behavior.fixedArea || behavior.VarArea)
{
newloc = Primitives.FindCircumcenter(borg, bdest, bapex, ref xi, ref eta, behavior.offconstant);
newloc = RobustPredicates.FindCircumcenter(borg, bdest, bapex, ref xi, ref eta, behavior.offconstant);
}
else
{
@@ -682,7 +682,7 @@ namespace TriangleNet.Meshing
((newloc.x == bdest.x) && (newloc.y == bdest.y)) ||
((newloc.x == bapex.x) && (newloc.y == bapex.y)))
{
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("New vertex falls on existing vertex.", "Quality.SplitTriangle()");
errorflag = true;
@@ -746,7 +746,7 @@ namespace TriangleNet.Meshing
else
{ // success == DUPLICATEVERTEX
// Couldn't insert the new vertex because a vertex is already there.
if (Behavior.Verbose)
if (Log.Verbose)
{
logger.Warning("New vertex falls on existing vertex.", "Quality.SplitTriangle()");
errorflag = true;
@@ -811,7 +811,7 @@ namespace TriangleNet.Meshing
// and have no low-quality triangles.
// Might we have run out of Steiner points too soon?
if (Behavior.Verbose && behavior.ConformingDelaunay && (badsubsegs.Count > 0) && (mesh.steinerleft == 0))
if (Log.Verbose && behavior.ConformingDelaunay && (badsubsegs.Count > 0) && (mesh.steinerleft == 0))
{
logger.Warning("I ran out of Steiner points, but the mesh has encroached subsegments, "
+11 -11
View File
@@ -178,7 +178,7 @@ namespace TriangleNet
// Use the counterclockwise() routine to ensure a positive (and
// reasonably accurate) result, avoiding any possibility of
// division by zero.
denominator = 0.5 / Primitives.CounterClockwise(tdest, tapex, torg);
denominator = 0.5 / RobustPredicates.CounterClockwise(tdest, tapex, torg);
// Don't count the above as an orientation test.
Statistic.CounterClockwiseCount--;
}
@@ -473,7 +473,7 @@ namespace TriangleNet
neighborvertex_2 = neighborotri.Dest();
neighborvertex_3 = neighborotri.Apex();
// now calculate neighbor's circumcenter which is the voronoi site
neighborCircumcenter = Primitives.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
neighborCircumcenter = RobustPredicates.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
ref xi_tmp, ref eta_tmp);
/// compute petal and Voronoi edge intersection ///
@@ -604,7 +604,7 @@ namespace TriangleNet
neighborvertex_2 = neighborotri.Dest();
neighborvertex_3 = neighborotri.Apex();
// now calculate neighbor's circumcenter which is the voronoi site
neighborCircumcenter = Primitives.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
neighborCircumcenter = RobustPredicates.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
ref xi_tmp, ref eta_tmp);
/// compute petal and Voronoi edge intersection ///
@@ -891,7 +891,7 @@ namespace TriangleNet
// Use the counterclockwise() routine to ensure a positive (and
// reasonably accurate) result, avoiding any possibility of
// division by zero.
denominator = 0.5 / Primitives.CounterClockwise(tdest, tapex, torg);
denominator = 0.5 / RobustPredicates.CounterClockwise(tdest, tapex, torg);
// Don't count the above as an orientation test.
Statistic.CounterClockwiseCount--;
}
@@ -1234,7 +1234,7 @@ namespace TriangleNet
neighborvertex_2 = neighborotri.Dest();
neighborvertex_3 = neighborotri.Apex();
// now calculate neighbor's circumcenter which is the voronoi site
neighborCircumcenter = Primitives.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
neighborCircumcenter = RobustPredicates.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
ref xi_tmp, ref eta_tmp);
/// compute petal and Voronoi edge intersection ///
@@ -1516,7 +1516,7 @@ namespace TriangleNet
neighborvertex_2 = neighborotri.Dest();
neighborvertex_3 = neighborotri.Apex();
// now calculate neighbor's circumcenter which is the voronoi site
neighborCircumcenter = Primitives.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
neighborCircumcenter = RobustPredicates.FindCircumcenter(neighborvertex_1, neighborvertex_2, neighborvertex_3,
ref xi_tmp, ref eta_tmp);
/// compute petal and Voronoi edge intersection ///
@@ -2521,9 +2521,9 @@ namespace TriangleNet
petalr = new double[2 * numpoints];
wedges = new double[2 * numpoints * 16 + 36];
if (Behavior.Verbose)
if (Log.Verbose)
{
Log.SimpleLog.Instance.Info("NewLocation: resized work arrays (" + 2 * numpoints + ")");
Log.Instance.Info("NewLocation: resized work arrays (" + 2 * numpoints + ")");
}
}
@@ -2788,9 +2788,9 @@ namespace TriangleNet
petalr = new double[2 * numpoints];
wedges = new double[2 * numpoints * 20 + 40];
if (Behavior.Verbose)
if (Log.Verbose)
{
Log.SimpleLog.Instance.Info("NewLocation: resized work arrays (" + 2 * numpoints + ")");
Log.Instance.Info("NewLocation: resized work arrays (" + 2 * numpoints + ")");
}
}
@@ -4099,7 +4099,7 @@ namespace TriangleNet
else
{
// Orient 'searchtri' to fit the preconditions of calling preciselocate().
ahead = Primitives.CounterClockwise(torg, tdest, newvertex);
ahead = RobustPredicates.CounterClockwise(torg, tdest, newvertex);
if (ahead < 0.0)
{
// Turn around so that 'searchpoint' is to the left of the
@@ -23,7 +23,7 @@ namespace TriangleNet
/// command prompt with the command "CL /P /C EXACT.C", see
/// http://msdn.microsoft.com/en-us/library/8z9z0bx6.aspx
/// </remarks>
public static class Primitives
public static class RobustPredicates
{
private static double epsilon, splitter, resulterrbound;
private static double ccwerrboundA, ccwerrboundB, ccwerrboundC;
+1 -2
View File
@@ -9,7 +9,6 @@ namespace TriangleNet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// <summary>
/// Used for triangle sampling in the Mesh.Locate method.
@@ -93,7 +92,7 @@ namespace TriangleNet
// sure, use a range variable...
key = rand.Next(i * range, (i + 1) * range - 1);
if (!mesh.triangles.Keys.Contains(keys[key]))
if (!mesh.triangles.ContainsKey(keys[key]))
{
// Keys collection isn't up to date anymore!
this.Update(mesh, true);
@@ -128,7 +128,7 @@ namespace TriangleNet.Tools
{
tri.triangle = item;
pt = Primitives.FindCircumcenter(tri.Org(), tri.Dest(), tri.Apex(), ref xi, ref eta);
pt = RobustPredicates.FindCircumcenter(tri.Org(), tri.Dest(), tri.Apex(), ref xi, ref eta);
pt.id = item.id;
points[item.id] = pt;
+3 -3
View File
@@ -11,7 +11,7 @@ namespace TriangleNet.Tools
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TriangleNet.Log;
using TriangleNet.Logging;
/// <summary>
/// Applies the Cuthill and McKee renumbering algorithm to reduce the bandwidth of
@@ -51,9 +51,9 @@ namespace TriangleNet.Tools
bandwidth2 = PermBandwidth(perm, perm_inv);
if (Behavior.Verbose)
if (Log.Verbose)
{
SimpleLog.Instance.Info(String.Format("Reverse Cuthill-McKee (Bandwidth: {0} > {1})",
Log.Instance.Info(String.Format("Reverse Cuthill-McKee (Bandwidth: {0} > {1})",
bandwidth1, bandwidth2));
}
+1 -1
View File
@@ -114,7 +114,7 @@ namespace TriangleNet.Tools
{
tri.triangle = item;
pt = Primitives.FindCircumcenter(tri.Org(), tri.Dest(), tri.Apex(), ref xi, ref eta);
pt = RobustPredicates.FindCircumcenter(tri.Org(), tri.Dest(), tri.Apex(), ref xi, ref eta);
pt.id = item.id;
points[item.id] = pt;
+7 -7
View File
@@ -51,7 +51,7 @@
<Compile Include="Meshing\IConstraintMesher.cs" />
<Compile Include="Meshing\IQualityMesher.cs" />
<Compile Include="Meshing\ITriangulator.cs" />
<Compile Include="BadTriQueue.cs" />
<Compile Include="Data\BadTriQueue.cs" />
<Compile Include="Behavior.cs" />
<Compile Include="Meshing\ConstraintMesher.cs" />
<Compile Include="Data\BadSubseg.cs" />
@@ -60,7 +60,7 @@
<Compile Include="Data\Otri.cs" />
<Compile Include="Data\Segment.cs" />
<Compile Include="Data\Triangle.cs" />
<Compile Include="Data\Vertex.cs" />
<Compile Include="Geometry\Vertex.cs" />
<Compile Include="Meshing\Algorithm\Dwyer.cs" />
<Compile Include="Geometry\Rectangle.cs" />
<Compile Include="Geometry\Edge.cs" />
@@ -77,10 +77,10 @@
<Compile Include="IO\InputTriangle.cs" />
<Compile Include="IO\TriangleReader.cs" />
<Compile Include="IO\TriangleFormat.cs" />
<Compile Include="Log\ILog.cs" />
<Compile Include="Log\ILogItem.cs" />
<Compile Include="Log\SimpleLog.cs" />
<Compile Include="Log\SimpleLogItem.cs" />
<Compile Include="Logging\ILog.cs" />
<Compile Include="Logging\ILogItem.cs" />
<Compile Include="Log.cs" />
<Compile Include="Logging\LogItem.cs" />
<Compile Include="Meshing\QualityOptions.cs" />
<Compile Include="MeshValidator.cs" />
<Compile Include="NewLocation.cs" />
@@ -88,7 +88,7 @@
<Compile Include="Enums.cs" />
<Compile Include="Meshing\Algorithm\Incremental.cs" />
<Compile Include="Mesh.cs" />
<Compile Include="Primitives.cs" />
<Compile Include="RobustPredicates.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sampler.cs" />
<Compile Include="Smoothing\ISmoother.cs" />
+3 -3
View File
@@ -128,10 +128,10 @@ namespace TriangleNet
}
// Does the point lie on the other side of the line defined by the
// triangle edge opposite the triangle's destination?
destorient = Primitives.CounterClockwise(forg, fapex, searchpoint);
destorient = RobustPredicates.CounterClockwise(forg, fapex, searchpoint);
// Does the point lie on the other side of the line defined by the
// triangle edge opposite the triangle's origin?
orgorient = Primitives.CounterClockwise(fapex, fdest, searchpoint);
orgorient = RobustPredicates.CounterClockwise(fapex, fdest, searchpoint);
if (destorient > 0.0)
{
if (orgorient > 0.0)
@@ -317,7 +317,7 @@ namespace TriangleNet
return LocateResult.OnVertex;
}
// Orient 'searchtri' to fit the preconditions of calling preciselocate().
ahead = Primitives.CounterClockwise(torg, tdest, searchpoint);
ahead = RobustPredicates.CounterClockwise(torg, tdest, searchpoint);
if (ahead < 0.0)
{
// Turn around so that 'searchpoint' is to the left of the