diff --git a/Triangle.NET/Triangle/Geometry/RegionPointer.cs b/Triangle.NET/Triangle/Geometry/RegionPointer.cs index f44b872..2db73a3 100644 --- a/Triangle.NET/Triangle/Geometry/RegionPointer.cs +++ b/Triangle.NET/Triangle/Geometry/RegionPointer.cs @@ -17,6 +17,23 @@ namespace TriangleNet.Geometry { internal Point point; internal int id; + internal double area; + + /// + /// Gets or sets a region area constraint. + /// + public double Area + { + get { return area; } + set + { + if (value < 0.0) + { + throw new ArgumentException("Area constraints must not be negative."); + } + area = value; + } + } /// /// Initializes a new instance of the class. @@ -25,9 +42,22 @@ namespace TriangleNet.Geometry /// Y coordinate of the region. /// Region id. public RegionPointer(double x, double y, int id) + : this(x, y, id, 0.0) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// X coordinate of the region. + /// Y coordinate of the region. + /// Region id. + /// Area constraint. + public RegionPointer(double x, double y, int id, double area) { this.point = new Point(x, y); this.id = id; + this.area = area; } } } diff --git a/Triangle.NET/Triangle/IO/TriangleReader.cs b/Triangle.NET/Triangle/IO/TriangleReader.cs index fb3a90f..747a3bf 100644 --- a/Triangle.NET/Triangle/IO/TriangleReader.cs +++ b/Triangle.NET/Triangle/IO/TriangleReader.cs @@ -446,7 +446,7 @@ namespace TriangleNet.IO // Read area constraints (optional). if (TryReadLine(reader, out line)) { - int regions = int.Parse(line[0]); + int id, regions = int.Parse(line[0]); if (regions > 0) { @@ -462,10 +462,32 @@ namespace TriangleNet.IO throw new Exception("Invalid region attributes."); } + if (!int.TryParse(line[3], out id)) + { + id = i; + } + + double area = 0.0; + + if (line.Length > 4) + { + double.TryParse(line[4], NumberStyles.Number, nfi, out area); + } + + // Triangle's .poly file format allows region definitions with + // either 4 or 5 parameters, and different interpretations for + // them depending on the number of parameters. + // + // See http://www.cs.cmu.edu/~quake/triangle.poly.html + // + // The .NET version will interpret the fourth parameter always + // as an integer region id and the optional fifth parameter as + // an area constraint. + data.Regions.Add(new RegionPointer( double.Parse(line[1], nfi), // Region x double.Parse(line[2], nfi), // Region y - int.Parse(line[3]))); // Region id + id, area)); } } } diff --git a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs index 0bf5afe..69ccada 100644 --- a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs +++ b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs @@ -186,6 +186,7 @@ namespace TriangleNet.Meshing // holes have been carved. regionTris[i] = searchtri.tri; regionTris[i].label = region.id; + regionTris[i].area = region.area; } } } diff --git a/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs b/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs index 2a249a9..b0e97cd 100644 --- a/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs +++ b/Triangle.NET/Triangle/Meshing/Iterators/RegionIterator.cs @@ -92,7 +92,11 @@ namespace TriangleNet.Meshing.Iterators public void Process(Triangle triangle) { // Default action is to just set the region id for all trianlges. - this.Process(triangle, (tri) => { tri.label = triangle.label; }); + this.Process(triangle, (tri) => + { + tri.label = triangle.label; + tri.area = triangle.area; + }); } ///