From da90ca5d0ef67c56cd38ee91dd6edd154dd56d30 Mon Sep 17 00:00:00 2001 From: "SND\\wo80_cp" Date: Wed, 26 Aug 2015 11:13:09 +0000 Subject: [PATCH] Make fixed vertex ids work (changed IPolygon interface) git-svn-id: https://triangle.svn.codeplex.com/svn@77167 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5 --- .../TestApp/Generators/RingPolygon.cs | 14 +- Triangle.NET/TestApp/Generators/StarInBox.cs | 28 +-- Triangle.NET/TestApp/IO/Formats/JsonFile.cs | 11 +- .../TestApp/IO/Formats/TriangleFile.cs | 4 +- .../Triangle.Rendering/ColorManager.cs | 6 +- .../Triangle.Rendering/GDI/MeshRenderer.cs | 7 +- .../Triangle.Rendering/RenderContext.cs | 8 + Triangle.NET/Triangle/Geometry/Contour.cs | 166 ++++++++++++++++ Triangle.NET/Triangle/Geometry/IEdge.cs | 7 +- Triangle.NET/Triangle/Geometry/IPolygon.cs | 13 +- Triangle.NET/Triangle/Geometry/ISegment.cs | 2 +- Triangle.NET/Triangle/Geometry/Polygon.cs | 177 ++---------------- Triangle.NET/Triangle/Geometry/Segment.cs | 93 +++++++++ Triangle.NET/Triangle/IO/IMeshFormat.cs | 4 +- Triangle.NET/Triangle/IO/IPolygonFormat.cs | 4 +- Triangle.NET/Triangle/IO/TriangleFormat.cs | 4 +- Triangle.NET/Triangle/IO/TriangleReader.cs | 47 +++-- Triangle.NET/Triangle/IO/TriangleWriter.cs | 9 +- Triangle.NET/Triangle/Mesh.cs | 20 +- .../Triangle/Meshing/ConstraintMesher.cs | 49 ++--- Triangle.NET/Triangle/Meshing/Converter.cs | 40 ++-- .../Triangle/Meshing/GenericMesher.cs | 38 +++- Triangle.NET/Triangle/Meshing/IMesh.cs | 2 +- .../Triangle/Tools/PolygonValidator.cs | 113 +++++++++-- Triangle.NET/Triangle/Topology/Osub.cs | 10 +- Triangle.NET/Triangle/Topology/Otri.cs | 2 +- .../Topology/{Segment.cs => SubSegment.cs} | 4 +- Triangle.NET/Triangle/Triangle.csproj | 107 +++++------ .../Voronoi/Legacy/BoundedVoronoiLegacy.cs | 4 +- 29 files changed, 618 insertions(+), 375 deletions(-) create mode 100644 Triangle.NET/Triangle/Geometry/Contour.cs create mode 100644 Triangle.NET/Triangle/Geometry/Segment.cs rename Triangle.NET/Triangle/Topology/{Segment.cs => SubSegment.cs} (93%) diff --git a/Triangle.NET/TestApp/Generators/RingPolygon.cs b/Triangle.NET/TestApp/Generators/RingPolygon.cs index 86386be..08ded0a 100644 --- a/Triangle.NET/TestApp/Generators/RingPolygon.cs +++ b/Triangle.NET/TestApp/Generators/RingPolygon.cs @@ -7,6 +7,7 @@ namespace MeshExplorer.Generators { using System; + using System.Collections.Generic; using TriangleNet.Geometry; /// @@ -54,15 +55,19 @@ namespace MeshExplorer.Generators double ro, r = 10; double step = 2 * Math.PI / m; + var inner = new List(m); + // Inner ring for (int i = 0; i < m; i++) { - input.Add(new Vertex(r * Math.Cos(i * step), r * Math.Sin(i * step))); - input.Add(new Edge(i, (i + 1) % m, 1)); + inner.Add(new Vertex(r * Math.Cos(i * step), r * Math.Sin(i * step))); } + input.AddContour(inner, 1); + r = 1.5 * r; + var outer = new List(n); step = 2 * Math.PI / n; double offset = step / 2; @@ -77,10 +82,11 @@ namespace MeshExplorer.Generators ro = r + r * Util.Random.NextDouble() * (param1 / 100); } - input.Add(new Vertex(ro * Math.Cos(i * step + offset), ro * Math.Sin(i * step + offset))); - input.Add(new Edge(m + i, m + ((i + 1) % n), 2)); + outer.Add(new Vertex(ro * Math.Cos(i * step + offset), ro * Math.Sin(i * step + offset))); } + input.AddContour(outer, 2); + input.Holes.Add(new Point(0, 0)); return input; diff --git a/Triangle.NET/TestApp/Generators/StarInBox.cs b/Triangle.NET/TestApp/Generators/StarInBox.cs index 9bd2e4a..b35c68b 100644 --- a/Triangle.NET/TestApp/Generators/StarInBox.cs +++ b/Triangle.NET/TestApp/Generators/StarInBox.cs @@ -29,9 +29,9 @@ namespace MeshExplorer.Generators { int numRays = GetParamValueInt(0, param0); - var input = new Polygon(numRays + 4); + var g = new Polygon(numRays + 4); - input.Add(new Vertex(0, 0)); // Center + g.Add(new Vertex(0, 0)); // Center double x, y, r, e, step = 2 * Math.PI / numRays; @@ -42,22 +42,22 @@ namespace MeshExplorer.Generators x = r * Math.Cos(i * step + e); y = r * Math.Sin(i * step + e); - input.Add(new Vertex(x, y, 2)); - input.Add(new Edge(0, i + 1, 2)); + g.Add(new Vertex(x, y, 2)); + g.Add(new Segment(g.Points[0], g.Points[i + 1], 2)); } - input.Add(new Vertex(-1, -1, 1)); // Box - input.Add(new Vertex(1, -1, 1)); - input.Add(new Vertex(1, 1, 1)); - input.Add(new Vertex(-1, 1, 1)); + g.Add(new Vertex(-1, -1, 1)); // Box + g.Add(new Vertex(1, -1, 1)); + g.Add(new Vertex(1, 1, 1)); + g.Add(new Vertex(-1, 1, 1)); - numRays = input.Count; - input.Add(new Edge(numRays - 1, numRays - 2, 1)); - input.Add(new Edge(numRays - 2, numRays - 3, 1)); - input.Add(new Edge(numRays - 3, numRays - 4, 1)); - input.Add(new Edge(numRays - 4, numRays - 1, 1)); + numRays = g.Count; + g.Add(new Segment(g.Points[numRays - 1], g.Points[numRays - 2], 1)); + g.Add(new Segment(g.Points[numRays - 2], g.Points[numRays - 3], 1)); + g.Add(new Segment(g.Points[numRays - 3], g.Points[numRays - 4], 1)); + g.Add(new Segment(g.Points[numRays - 4], g.Points[numRays - 1], 1)); - return input; + return g; } } } diff --git a/Triangle.NET/TestApp/IO/Formats/JsonFile.cs b/Triangle.NET/TestApp/IO/Formats/JsonFile.cs index 3891e7e..1c11dfe 100644 --- a/Triangle.NET/TestApp/IO/Formats/JsonFile.cs +++ b/Triangle.NET/TestApp/IO/Formats/JsonFile.cs @@ -154,7 +154,7 @@ namespace MeshExplorer.IO.Formats } } - public void Write(IMesh mesh, StreamWriter stream) + public void Write(IMesh mesh, Stream stream) { throw new NotImplementedException(); } @@ -226,7 +226,7 @@ namespace MeshExplorer.IO.Formats throw new NotImplementedException(); } - public void Write(IPolygon polygon, StreamWriter stream) + public void Write(IPolygon polygon, Stream stream) { throw new NotImplementedException(); } @@ -315,6 +315,9 @@ namespace MeshExplorer.IO.Formats int p0, p1; + throw new NotImplementedException(); + // TODO: Fix JSON format + for (int i = 0; i < n; i += 2) { mark = 0; @@ -332,7 +335,7 @@ namespace MeshExplorer.IO.Formats throw new Exception("JSON format error (segment index)."); } - geometry.Add(new Edge(p0, p1, mark)); + //geometry.Add(new Edge(p0, p1, mark)); } } } @@ -497,7 +500,7 @@ namespace MeshExplorer.IO.Formats writer.Write("]"); } - private void WriteSegments(IEnumerable data, StreamWriter writer, int ns) + private void WriteSegments(IEnumerable data, StreamWriter writer, int ns) { int i = 0; diff --git a/Triangle.NET/TestApp/IO/Formats/TriangleFile.cs b/Triangle.NET/TestApp/IO/Formats/TriangleFile.cs index 5b3c622..ae60afa 100644 --- a/Triangle.NET/TestApp/IO/Formats/TriangleFile.cs +++ b/Triangle.NET/TestApp/IO/Formats/TriangleFile.cs @@ -57,7 +57,7 @@ namespace MeshExplorer.IO.Formats format.Write(polygon, filename); } - public void Write(IPolygon polygon, StreamWriter stream) + public void Write(IPolygon polygon, Stream stream) { format.Write(polygon, stream); } @@ -75,7 +75,7 @@ namespace MeshExplorer.IO.Formats } } - public void Write(IMesh mesh, StreamWriter stream) + public void Write(IMesh mesh, Stream stream) { format.Write(mesh, stream); } diff --git a/Triangle.NET/Triangle.Rendering/ColorManager.cs b/Triangle.NET/Triangle.Rendering/ColorManager.cs index ba37f33..713e9b9 100644 --- a/Triangle.NET/Triangle.Rendering/ColorManager.cs +++ b/Triangle.NET/Triangle.Rendering/ColorManager.cs @@ -145,7 +145,7 @@ namespace TriangleNet.Rendering } } - internal void Dispose(Dictionary brushes) + internal void Dispose(Dictionary brushes) { foreach (var brush in brushes.Values) { @@ -153,9 +153,9 @@ namespace TriangleNet.Rendering } } - internal Dictionary GetBrushDictionary() + internal Dictionary GetBrushDictionary() { - var brushes = new Dictionary(); + var brushes = new Dictionary(); foreach (var item in ColorDictionary) { diff --git a/Triangle.NET/Triangle.Rendering/GDI/MeshRenderer.cs b/Triangle.NET/Triangle.Rendering/GDI/MeshRenderer.cs index e8d4348..38c3614 100644 --- a/Triangle.NET/Triangle.Rendering/GDI/MeshRenderer.cs +++ b/Triangle.NET/Triangle.Rendering/GDI/MeshRenderer.cs @@ -115,7 +115,12 @@ namespace TriangleNet.Rendering.GDI if (filled) { - g.FillPolygon(brushes[partition[i]], tri); + var b = brushes[partition[i]]; + + if (b.Color.A > 0) + { + g.FillPolygon(b, tri); + } } else { diff --git a/Triangle.NET/Triangle.Rendering/RenderContext.cs b/Triangle.NET/Triangle.Rendering/RenderContext.cs index b16bea4..0daa90c 100644 --- a/Triangle.NET/Triangle.Rendering/RenderContext.cs +++ b/Triangle.NET/Triangle.Rendering/RenderContext.cs @@ -80,6 +80,14 @@ namespace TriangleNet.Rendering // Always clear voronoi layer. RenderLayers[4].Reset(true); + int i = 0; + + // Ensure linear numbering of polygon vertices. + foreach (var p in data.Points) + { + p.ID = i++; + } + this.bounds = RenderLayers[2].SetPoints(data); this.zoom.Initialize(bounds); diff --git a/Triangle.NET/Triangle/Geometry/Contour.cs b/Triangle.NET/Triangle/Geometry/Contour.cs new file mode 100644 index 0000000..7ddb23d --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/Contour.cs @@ -0,0 +1,166 @@ +// ----------------------------------------------------------------------- +// +// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + using System.Collections.Generic; + + public class Contour + { + int marker; + + public List Points { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public Contour(IEnumerable points, int marker) + { + this.Points = new List(points); + + int count = Points.Count; + + // Check if first vertex equals last vertex. + if (Points[0] == Points[count - 1]) + { + count--; + Points.RemoveAt(count); + } + + this.marker = marker; + } + + public Point FindInteriorPoint(bool convex) + { + if (convex) + { + int count = this.Points.Count; + + var centroid = new Point(0.0, 0.0); + + for (int i = 0; i < count; i++) + { + centroid.x += this.Points[i].x; + centroid.y += this.Points[i].y; + } + + // If the hole is convex, use its centroid. + centroid.x /= count; + centroid.y /= count; + + return centroid; + } + + return FindPointInPolygon(this.Points); + } + + public List GetSegments() + { + var segments = new List(); + + var p = this.Points; + + int count = p.Count - 1; + + for (int i = 0; i < count; i++) + { + // Add segments to polygon. + segments.Add(new Segment(p[i], p[i + 1], marker)); + } + + // Close the contour. + segments.Add(new Segment(p[count], p[0], marker)); + + return segments; + } + + private static Point FindPointInPolygon(List contour) + { + var bounds = new Rectangle(); + bounds.Expand(contour); + + int length = contour.Count; + int limit = 8; + + var test = new Point(); + + Point a, b; // Current edge. + double cx, cy; // Center of current edge. + double dx, dy; // Direction perpendicular to edge. + + for (int i = 0; i < length; i++) + { + a = contour[i]; + b = contour[(i + 1) % length]; + + cx = (a.x + b.x) / 2; + cy = (a.y + b.y) / 2; + + dx = (b.y - a.y) / 1.374; + dy = (a.x - b.x) / 1.374; + + for (int j = 1; j <= limit; j++) + { + // Search to the right of the segment. + test.x = cx + dx / j; + test.y = cy + dy / j; + + if (bounds.Contains(test) && IsPointInPolygon(test, contour)) + { + return test; + } + + // Search on the other side of the segment. + test.x = cx - dx / j; + test.y = cy - dy / j; + + if (bounds.Contains(test) && IsPointInPolygon(test, contour)) + { + return test; + } + } + } + + throw new Exception(); + } + + /// + /// Return true if the given point is inside the polygon, or false if it is not. + /// + /// The point to check. + /// The polygon (list of contour points). + /// + /// + /// WARNING: If the point is exactly on the edge of the polygon, then the function + /// may return true or false. + /// + /// See http://alienryderflex.com/polygon/ + /// + private static bool IsPointInPolygon(Point point, List poly) + { + bool inside = false; + + double x = point.x; + double y = point.y; + + int count = poly.Count; + + for (int i = 0, j = count - 1; i < count; i++) + { + if (((poly[i].y < y && poly[j].y >= y) || (poly[j].y < y && poly[i].y >= y)) + && (poly[i].x <= x || poly[j].x <= x)) + { + inside ^= (poly[i].x + (y - poly[i].y) / (poly[j].y - poly[i].y) * (poly[j].x - poly[i].x) < x); + } + + j = i; + } + + return inside; + } + } +} diff --git a/Triangle.NET/Triangle/Geometry/IEdge.cs b/Triangle.NET/Triangle/Geometry/IEdge.cs index ab34b9f..ff55d80 100644 --- a/Triangle.NET/Triangle/Geometry/IEdge.cs +++ b/Triangle.NET/Triangle/Geometry/IEdge.cs @@ -1,4 +1,9 @@ - +// ----------------------------------------------------------------------- +// +// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ +// +// ----------------------------------------------------------------------- + namespace TriangleNet.Geometry { public interface IEdge diff --git a/Triangle.NET/Triangle/Geometry/IPolygon.cs b/Triangle.NET/Triangle/Geometry/IPolygon.cs index a99672c..19475db 100644 --- a/Triangle.NET/Triangle/Geometry/IPolygon.cs +++ b/Triangle.NET/Triangle/Geometry/IPolygon.cs @@ -1,4 +1,9 @@ - +// ----------------------------------------------------------------------- +// +// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ +// +// ----------------------------------------------------------------------- + namespace TriangleNet.Geometry { using System.Collections.Generic; @@ -17,7 +22,7 @@ namespace TriangleNet.Geometry /// /// Gets the segments of the polygon. /// - List Segments { get; } + List Segments { get; } /// /// Gets a list of points defining the holes of the polygon. @@ -30,12 +35,12 @@ namespace TriangleNet.Geometry List Regions { get; } /// - /// Gets or sets value indicating wether the vertices have marks or not. + /// Gets or sets a value indicating whether the vertices have marks or not. /// bool HasPointMarkers { get; set; } /// - /// Gets or sets value indicating wether the segments have marks or not. + /// Gets or sets a value indicating whether the segments have marks or not. /// bool HasSegmentMarkers { get; set; } diff --git a/Triangle.NET/Triangle/Geometry/ISegment.cs b/Triangle.NET/Triangle/Geometry/ISegment.cs index 1af96be..86a7d48 100644 --- a/Triangle.NET/Triangle/Geometry/ISegment.cs +++ b/Triangle.NET/Triangle/Geometry/ISegment.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------- -// +// // Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ // // ----------------------------------------------------------------------- diff --git a/Triangle.NET/Triangle/Geometry/Polygon.cs b/Triangle.NET/Triangle/Geometry/Polygon.cs index 1b113e7..3c2f955 100644 --- a/Triangle.NET/Triangle/Geometry/Polygon.cs +++ b/Triangle.NET/Triangle/Geometry/Polygon.cs @@ -1,4 +1,9 @@ - +// ----------------------------------------------------------------------- +// +// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ +// +// ----------------------------------------------------------------------- + namespace TriangleNet.Geometry { using System; @@ -14,7 +19,7 @@ namespace TriangleNet.Geometry List holes; List regions; - List segments; + List segments; /// public List Points @@ -35,7 +40,7 @@ namespace TriangleNet.Geometry } /// - public List Segments + public List Segments { get { return segments; } } @@ -80,7 +85,7 @@ namespace TriangleNet.Geometry holes = new List(); regions = new List(); - segments = new List(); + segments = new List(); HasPointMarkers = markers; HasSegmentMarkers = markers; @@ -90,76 +95,27 @@ namespace TriangleNet.Geometry public void AddContour(IEnumerable points, int marker = 0, bool hole = false, bool convex = false) { - // Copy input to list. - var contour = new List(points); + var c = new Contour(points, marker); - int offset = this.points.Count; - int count = contour.Count; + this.points.AddRange(c.Points); - // Check if first vertex equals last vertex. - if (contour[0] == contour[count - 1]) - { - count--; - contour.RemoveAt(count); - } - - // Add points to polygon. - this.points.AddRange(contour); - - var centroid = new Point(0.0, 0.0); - - for (int i = 0; i < count; i++) - { - centroid.x += contour[i].x; - centroid.y += contour[i].y; - - // Add segments to polygon. - this.segments.Add(new Edge(offset + i, offset + ((i + 1) % count), marker)); - } + this.segments.AddRange(c.GetSegments()); if (hole) { - if (convex) - { - // If the hole is convex, use its centroid. - centroid.x /= count; - centroid.y /= count; - - this.holes.Add(centroid); - } - else - { - this.holes.Add(FindPointInPolygon(contour)); - } + this.holes.Add(c.FindInteriorPoint(convex)); } } /// public void AddContour(IEnumerable points, int marker, Point hole) { - // Copy input to list. - var contour = new List(points); + var c = new Contour(points, marker); - int offset = this.points.Count; - int count = contour.Count; + this.points.AddRange(c.Points); - // Check if first vertex equals last vertex. - if (contour[0] == contour[count - 1]) - { - count--; - contour.RemoveAt(count); - } + this.segments.AddRange(c.GetSegments()); - // Add points to polygon. - this.points.AddRange(contour); - - for (int i = 0; i < count; i++) - { - // Add segments to polygon. - this.segments.Add(new Edge(offset + i, offset + ((i + 1) % count), marker)); - } - - // TODO: check if hole is actually inside contour? this.holes.Add(hole); } @@ -180,109 +136,12 @@ namespace TriangleNet.Geometry this.points.Add(vertex); } - /// - /// Add a vertex to the polygon. - /// - public void Add(Vertex vertex, double[] attributes) - { - // TODO: check attibutes - - vertex.attributes = attributes; - - this.points.Add(vertex); - } - /// /// Add a segment to the polygon. /// - public void Add(Edge edge) + public void Add(ISegment segment) { - this.segments.Add(edge); - } - - private Point FindPointInPolygon(List contour) - { - var bounds = new Rectangle(); - bounds.Expand(contour); - - int length = contour.Count; - int limit = 8; - - var test = new Point(); - - Point a, b; // Current edge. - double cx, cy; // Center of current edge. - double dx, dy; // Direction perpendicular to edge. - - for (int i = 0; i < length; i++) - { - a = contour[i]; - b = contour[(i + 1) % length]; - - cx = (a.x + b.x) / 2; - cy = (a.y + b.y) / 2; - - dx = (b.y - a.y) / 1.374; - dy = (a.x - b.x) / 1.374; - - for (int j = 1; j <= limit; j++) - { - // Search to the right of the segment. - test.x = cx + dx / j; - test.y = cy + dy / j; - - if (bounds.Contains(test) && IsPointInPolygon(test, contour)) - { - return test; - } - - // Search on the other side of the segment. - test.x = cx - dx / j; - test.y = cy - dy / j; - - if (bounds.Contains(test) && IsPointInPolygon(test, contour)) - { - return test; - } - } - } - - throw new Exception(); - } - - /// - /// Return true if the given point is inside the polygon, or false if it is not. - /// - /// The point to check. - /// The polygon (list of contour points). - /// - /// - /// WARNING: If the point is exactly on the edge of the polygon, then the function - /// may return true or false. - /// - /// See http://alienryderflex.com/polygon/ - /// - private bool IsPointInPolygon(Point point, List poly) - { - bool inside = false; - - double x = point.x; - double y = point.y; - - int count = poly.Count; - - for (int i = 0, j = count - 1; i < count; i++) - { - if (((poly[i].y < y && poly[j].y >= y) || (poly[j].y < y && poly[i].y >= y)) - && (poly[i].x <= x || poly[j].x <= x)) - { - inside ^= (poly[i].x + (y - poly[i].y) / (poly[j].y - poly[i].y) * (poly[j].x - poly[i].x) < x); - } - - j = i; - } - - return inside; + this.segments.Add(segment); } } } diff --git a/Triangle.NET/Triangle/Geometry/Segment.cs b/Triangle.NET/Triangle/Geometry/Segment.cs new file mode 100644 index 0000000..0066b85 --- /dev/null +++ b/Triangle.NET/Triangle/Geometry/Segment.cs @@ -0,0 +1,93 @@ +// ----------------------------------------------------------------------- +// +// Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ +// +// ----------------------------------------------------------------------- + +namespace TriangleNet.Geometry +{ + using System; + + /// + /// Represents a straight line segment in 2D space. + /// + public class Segment : ISegment + { + Vertex v0; + Vertex v1; + + int boundary; + + /// + /// Initializes a new instance of the class. + /// + public Segment(Vertex v0, Vertex v1) + : this (v0, v1, 0) + { + } + + /// + /// Initializes a new instance of the class. + /// + public Segment(Vertex v0, Vertex v1, int boundary) + { + this.v0 = v0; + this.v1 = v1; + + this.boundary = boundary; + } + + /// + /// Gets the specified segment endpoint. + /// + /// The endpoint index (0 or 1). + /// + public Vertex GetVertex(int index) + { + if (index == 0) + { + return v0; + } + + if (index == 1) + { + return v1; + } + + throw new IndexOutOfRangeException(); + } + + /// + /// WARNING: not implemented. + /// + public ITriangle GetTriangle(int index) + { + throw new NotImplementedException(); + } + + /// + /// Gets the first endpoints index. + /// + public int P0 + { + get { return v0.id; } + } + + /// + /// Gets the second endpoints index. + /// + public int P1 + { + get { return v1.id; } + } + + /// + /// Gets or sets the segments boundary mark. + /// + public int Boundary + { + get { return boundary; } + set { boundary = value; } + } + } +} diff --git a/Triangle.NET/Triangle/IO/IMeshFormat.cs b/Triangle.NET/Triangle/IO/IMeshFormat.cs index ec91624..99a2a13 100644 --- a/Triangle.NET/Triangle/IO/IMeshFormat.cs +++ b/Triangle.NET/Triangle/IO/IMeshFormat.cs @@ -29,10 +29,10 @@ namespace TriangleNet.IO void Write(IMesh mesh, string filename); /// - /// Save a mesh to a . + /// Save a mesh to a . /// /// An instance of the interface. /// The stream to save to. - void Write(IMesh mesh, StreamWriter stream); + void Write(IMesh mesh, Stream stream); } } diff --git a/Triangle.NET/Triangle/IO/IPolygonFormat.cs b/Triangle.NET/Triangle/IO/IPolygonFormat.cs index 9889230..7394243 100644 --- a/Triangle.NET/Triangle/IO/IPolygonFormat.cs +++ b/Triangle.NET/Triangle/IO/IPolygonFormat.cs @@ -29,10 +29,10 @@ namespace TriangleNet.IO void Write(IPolygon polygon, string filename); /// - /// Save a polygon geometry to a . + /// Save a polygon geometry to a . /// /// An instance of the class. /// The stream to save to. - void Write(IPolygon polygon, StreamWriter stream); + void Write(IPolygon polygon, Stream stream); } } diff --git a/Triangle.NET/Triangle/IO/TriangleFormat.cs b/Triangle.NET/Triangle/IO/TriangleFormat.cs index b1bda4a..58f18d3 100644 --- a/Triangle.NET/Triangle/IO/TriangleFormat.cs +++ b/Triangle.NET/Triangle/IO/TriangleFormat.cs @@ -55,7 +55,7 @@ namespace TriangleNet.IO TriangleWriter.WriteElements((Mesh)mesh, Path.ChangeExtension(filename, ".ele")); } - public void Write(IMesh mesh, StreamWriter stream) + public void Write(IMesh mesh, Stream stream) { throw new NotImplementedException(); } @@ -83,7 +83,7 @@ namespace TriangleNet.IO TriangleWriter.WritePoly(polygon, filename); } - public void Write(IPolygon polygon, StreamWriter stream) + public void Write(IPolygon polygon, Stream stream) { throw new NotImplementedException(); } diff --git a/Triangle.NET/Triangle/IO/TriangleReader.cs b/Triangle.NET/Triangle/IO/TriangleReader.cs index bd10ba6..80ba993 100644 --- a/Triangle.NET/Triangle/IO/TriangleReader.cs +++ b/Triangle.NET/Triangle/IO/TriangleReader.cs @@ -59,29 +59,36 @@ namespace TriangleNet.IO /// The current line. /// Number of point attributes /// Number of point markers (0 or 1) - static void ReadVertex(Polygon data, int index, string[] line, int attributes, int marks) + static void ReadVertex(List data, int index, string[] line, int attributes, int marks) { double x = double.Parse(line[1], nfi); double y = double.Parse(line[2], nfi); - int mark = 0; - double[] attribs = attributes == 0 ? null : new double[attributes]; - // Read the vertex attributes. - for (int j = 0; j < attributes; j++) - { - if (line.Length > 3 + j) - { - attribs[j] = double.Parse(line[3 + j], nfi); - } - } + var v = new Vertex(x, y); // Read a vertex marker. if (marks > 0 && line.Length > 3 + attributes) { - mark = int.Parse(line[3 + attributes]); + v.Boundary = int.Parse(line[3 + attributes]); } - data.Add(new Vertex(x, y, mark), attribs); + if (attributes > 0) + { + var attribs = new double[attributes]; + + // Read the vertex attributes. + for (int j = 0; j < attributes; j++) + { + if (line.Length > 3 + j) + { + attribs[j] = double.Parse(line[3 + j], nfi); + } + } + + v.attributes = attribs; + } + + data.Add(v); } #endregion @@ -219,7 +226,7 @@ namespace TriangleNet.IO startIndex = int.Parse(line[0], nfi); } - ReadVertex(data, i, line, attributes, nodemarkers); + ReadVertex(data.Points, i, line, attributes, nodemarkers); } } } @@ -326,19 +333,21 @@ namespace TriangleNet.IO startIndex = int.Parse(line[0], nfi); } - ReadVertex(data, i, line, attributes, nodemarkers); + ReadVertex(data.Points, i, line, attributes, nodemarkers); } } else { // If the .poly file claims there are zero vertices, that means that // the vertices should be read from a separate .node file. - string nodefile = Path.ChangeExtension(polyfilename, ".node"); - data = ReadNodeFile(nodefile); + data = ReadNodeFile(Path.ChangeExtension(polyfilename, ".node")); + invertices = data.Points.Count; } - if (data.Points == null) + var points = data.Points; + + if (points.Count == 0) { throw new Exception("No nodes available."); } @@ -401,7 +410,7 @@ namespace TriangleNet.IO } else { - data.Add(new Edge(end1, end2, mark)); + data.Add(new Segment(points[end1], points[end2], mark)); } } diff --git a/Triangle.NET/Triangle/IO/TriangleWriter.cs b/Triangle.NET/Triangle/IO/TriangleWriter.cs index acdb2f2..19a95af 100644 --- a/Triangle.NET/Triangle/IO/TriangleWriter.cs +++ b/Triangle.NET/Triangle/IO/TriangleWriter.cs @@ -202,17 +202,22 @@ namespace TriangleNet.IO // Number of segments, number of boundary markers (zero or one). writer.WriteLine("{0} {1}", polygon.Segments.Count, hasMarkers ? "1" : "0"); + Vertex p, q; + int j = 0; foreach (var seg in polygon.Segments) { + p = seg.GetVertex(0); + q = seg.GetVertex(1); + // Segment number, indices of its two endpoints, and possibly a marker. if (hasMarkers) { - writer.WriteLine("{0} {1} {2} {3}", j, seg.P0, seg.P1, seg.Boundary); + writer.WriteLine("{0} {1} {2} {3}", j, p.ID, q.ID, seg.Boundary); } else { - writer.WriteLine("{0} {1} {2}", j, seg.P0, seg.P1); + writer.WriteLine("{0} {1} {2}", j, p.ID, q.ID); } j++; diff --git a/Triangle.NET/Triangle/Mesh.cs b/Triangle.NET/Triangle/Mesh.cs index 585f79c..a3028df 100644 --- a/Triangle.NET/Triangle/Mesh.cs +++ b/Triangle.NET/Triangle/Mesh.cs @@ -35,7 +35,7 @@ namespace TriangleNet // Using hashsets for memory management should quite fast. internal Dictionary triangles; - internal Dictionary subsegs; + internal Dictionary subsegs; internal Dictionary vertices; // Hash seeds (should belong to mesh instance) @@ -111,7 +111,7 @@ namespace TriangleNet /// /// Gets the mesh segments. /// - public ICollection Segments + public ICollection Segments { get { return this.subsegs.Values; } } @@ -183,11 +183,11 @@ namespace TriangleNet // triangle side or subsegment end that isn't attached to a real // subsegment. - internal Segment dummysub; + internal SubSegment dummysub; private void Initialize() { - dummysub = new Segment(); + dummysub = new SubSegment(); dummysub.hash = DUMMY; // Initialize the two adjoining subsegments to be the omnipresent @@ -231,7 +231,7 @@ namespace TriangleNet vertices = new Dictionary(); triangles = new Dictionary(); - subsegs = new Dictionary(); + subsegs = new Dictionary(); flipstack = new Stack(); @@ -287,13 +287,13 @@ namespace TriangleNet } else if (num == NodeNumbering.CuthillMcKee) { - CuthillMcKee rcm = new CuthillMcKee(); - int[] perm_inv = rcm.Renumber(this); + var rcm = new CuthillMcKee(); + var iperm = rcm.Renumber(this); // Permute the node indices. foreach (var node in this.vertices.Values) { - node.id = perm_inv[node.id]; + node.id = iperm[node.id]; } } @@ -689,7 +689,7 @@ namespace TriangleNet /// Reference to the new subseg. internal void MakeSegment(ref Osub newsubseg) { - Segment seg = new Segment(); + var seg = new SubSegment(); seg.hash = this.hash_seg++; @@ -1924,7 +1924,7 @@ namespace TriangleNet /// Deallocate space for a subsegment, marking it dead. /// /// - internal void SubsegDealloc(Segment dyingsubseg) + internal void SubsegDealloc(SubSegment dyingsubseg) { // Mark the subsegment as dead. This makes it possible to detect dead // subsegments when traversing the list of all subsegments. diff --git a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs index 49a54aa..7fd3756 100644 --- a/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs +++ b/Triangle.NET/Triangle/Meshing/ConstraintMesher.cs @@ -169,9 +169,10 @@ namespace TriangleNet.Meshing /// public void FormSkeleton(IPolygon input) { - Vertex endpoint1, endpoint2; - int end1, end2; - int boundmarker; + // The segment endpoints. + Vertex p, q; + + int label; mesh.insegments = 0; @@ -191,51 +192,31 @@ namespace TriangleNet.Meshing mesh.MakeVertexMap(); } - boundmarker = 0; + label = 0; // Read and insert the segments. foreach (var seg in input.Segments) { mesh.insegments++; - end1 = seg.P0; - end2 = seg.P1; - boundmarker = seg.Boundary; + label = seg.Boundary; - if ((end1 < 0) || (end1 >= mesh.invertices)) + // TODO: wrap segment dictionary access in try / catch? + + p = seg.GetVertex(0); + q = seg.GetVertex(1); + + if ((p.x == q.x) && (p.y == q.y)) { if (Log.Verbose) { - logger.Warning("Invalid first endpoint of segment.", "Mesh.FormSkeleton().1"); - } - } - else if ((end2 < 0) || (end2 >= mesh.invertices)) - { - if (Log.Verbose) - { - logger.Warning("Invalid second endpoint of segment.", "Mesh.FormSkeleton().2"); + logger.Warning("Endpoints of segment (IDs " + p.id + "/" + q.id + ") are coincident.", + "Mesh.FormSkeleton()"); } } else { - // TODO: Is using the vertex ID reliable??? - // It should be. The ID gets appropriately set in TransferNodes(). - - // Find the vertices numbered 'end1' and 'end2'. - endpoint1 = mesh.vertices[end1]; - endpoint2 = mesh.vertices[end2]; - if ((endpoint1.x == endpoint2.x) && (endpoint1.y == endpoint2.y)) - { - if (Log.Verbose) - { - logger.Warning("Endpoints of segment (IDs " + end1 + "/" + end2 + ") are coincident.", - "Mesh.FormSkeleton()"); - } - } - else - { - InsertSegment(endpoint1, endpoint2, boundmarker); - } + InsertSegment(p, q, label); } } } diff --git a/Triangle.NET/Triangle/Meshing/Converter.cs b/Triangle.NET/Triangle/Meshing/Converter.cs index 34b9370..be6d9b9 100644 --- a/Triangle.NET/Triangle/Meshing/Converter.cs +++ b/Triangle.NET/Triangle/Meshing/Converter.cs @@ -213,10 +213,12 @@ namespace TriangleNet.Meshing Otri checkneighbor = default(Otri); Osub subseg = default(Osub); Otri prevlink; // Triangle - TVertex shorg; - TVertex segmentorg, segmentdest; - int[] end = new int[2]; + + TVertex tmp; + TVertex sorg, sdest; + bool notfound; + //bool segmentmarkers = false; int boundmarker; int aroundvertex; @@ -234,40 +236,38 @@ namespace TriangleNet.Meshing { subseg.seg = item; - end[0] = polygon.Segments[i].P0; - end[1] = polygon.Segments[i].P1; + sorg = polygon.Segments[i].GetVertex(0); + sdest = polygon.Segments[i].GetVertex(1); + boundmarker = polygon.Segments[i].Boundary; - for (int j = 0; j < 2; j++) + if ((sorg.id < 0 || sorg.id >= mesh.invertices) || (sdest.id < 0 || sdest.id >= mesh.invertices)) { - if ((end[j] < 0) || (end[j] >= mesh.invertices)) - { - Log.Instance.Error("Segment has an invalid vertex index.", "MeshReader.Reconstruct()"); - throw new Exception("Segment has an invalid vertex index."); - } + Log.Instance.Error("Segment has an invalid vertex index.", "MeshReader.Reconstruct()"); + throw new Exception("Segment has an invalid vertex index."); } // set the subsegment's vertices. subseg.orient = 0; - segmentorg = mesh.vertices[end[0]]; - segmentdest = mesh.vertices[end[1]]; - subseg.SetOrg(segmentorg); - subseg.SetDest(segmentdest); - subseg.SetSegOrg(segmentorg); - subseg.SetSegDest(segmentdest); + subseg.SetOrg(sorg); + subseg.SetDest(sdest); + subseg.SetSegOrg(sorg); + subseg.SetSegDest(sdest); subseg.seg.boundary = boundmarker; // Try linking the subsegment to triangles that share these vertices. for (subseg.orient = 0; subseg.orient < 2; subseg.orient++) { // Take the number for the destination of subsegloop. - aroundvertex = end[1 - subseg.orient]; + aroundvertex = subseg.orient == 1 ? sorg.id : sdest.id; + int index = vertexarray[aroundvertex].Count - 1; + // Look for triangles having this vertex. prevlink = vertexarray[aroundvertex][index]; nexttri = vertexarray[aroundvertex][index]; checktri = nexttri; - shorg = subseg.Org(); + tmp = subseg.Org(); notfound = true; // Look for triangles having this edge. Note that I'm only // comparing each triangle's destination with the subsegment; @@ -280,7 +280,7 @@ namespace TriangleNet.Meshing { checkdest = checktri.Dest(); - if (shorg == checkdest) + if (tmp == checkdest) { // We have a match. Remove this triangle from the list. //prevlink = vertexarray[aroundvertex][index]; diff --git a/Triangle.NET/Triangle/Meshing/GenericMesher.cs b/Triangle.NET/Triangle/Meshing/GenericMesher.cs index d0eca4d..4aeaf50 100644 --- a/Triangle.NET/Triangle/Meshing/GenericMesher.cs +++ b/Triangle.NET/Triangle/Meshing/GenericMesher.cs @@ -100,10 +100,10 @@ namespace TriangleNet.Meshing left = bounds.Left; bottom = bounds.Bottom; - int i, j, k, l, n; + int i, j, k, l, n = 0; // Add vertices. - var points = polygon.Points; + var points = new Vertex[(nx + 1) * (ny + 1)]; for (i = 0; i <= nx; i++) { @@ -113,10 +113,12 @@ namespace TriangleNet.Meshing { y = bottom + j * dy; - points.Add(new Vertex(x, y)); + points[n++] = new Vertex(x, y); } } + polygon.Points.AddRange(points); + n = 0; // Set vertex hash and id. @@ -130,22 +132,44 @@ namespace TriangleNet.Meshing segments.Capacity = 2 * (nx + ny); + Vertex a, b; + for (j = 0; j < ny; j++) { // Left - segments.Add(new Edge(j, j + 1)); + a = points[j]; + b = points[j + 1]; + + segments.Add(new Segment(a, b, 1)); + + a.Boundary = b.Boundary = 1; // Right - segments.Add(new Edge(nx * (ny + 1) + j, nx * (ny + 1) + (j + 1))); + a = points[nx * (ny + 1) + j]; + b = points[nx * (ny + 1) + (j + 1)]; + + segments.Add(new Segment(a, b, 1)); + + a.Boundary = b.Boundary = 1; } for (i = 0; i < nx; i++) { // Bottom - segments.Add(new Edge(i * (ny + 1), (i + 1) * (ny + 1))); + a = points[i * (ny + 1)]; + b = points[(i + 1) * (ny + 1)]; + + segments.Add(new Segment(a, b, 1)); + + a.Boundary = b.Boundary = 1; // Top - segments.Add(new Edge(i * (ny + 1) + nx, (i + 1) * (ny + 1) + nx)); + a = points[i * (ny + 1) + nx]; + b = points[(i + 1) * (ny + 1) + nx]; + + segments.Add(new Segment(a, b, 1)); + + a.Boundary = b.Boundary = 1; } // Add triangles. diff --git a/Triangle.NET/Triangle/Meshing/IMesh.cs b/Triangle.NET/Triangle/Meshing/IMesh.cs index 1e6a1be..7a769dd 100644 --- a/Triangle.NET/Triangle/Meshing/IMesh.cs +++ b/Triangle.NET/Triangle/Meshing/IMesh.cs @@ -23,7 +23,7 @@ namespace TriangleNet.Meshing /// /// Gets the segments (constraint edges) of the mesh. /// - ICollection Segments { get; } + ICollection Segments { get; } /// /// Gets the triangles of the mesh. diff --git a/Triangle.NET/Triangle/Tools/PolygonValidator.cs b/Triangle.NET/Triangle/Tools/PolygonValidator.cs index da1da08..7c99140 100644 --- a/Triangle.NET/Triangle/Tools/PolygonValidator.cs +++ b/Triangle.NET/Triangle/Tools/PolygonValidator.cs @@ -7,6 +7,7 @@ namespace TriangleNet.Tools { using System; + using System.Collections.Generic; using TriangleNet.Geometry; public static class PolygonValidator @@ -18,23 +19,37 @@ namespace TriangleNet.Tools { var logger = Log.Instance; + var points = poly.Points; + int horrors = 0; int i = 0; - int count = poly.Points.Count; + int count = points.Count; - foreach (var p in poly.Points) + if (count < 3) + { + logger.Warning("Polygon must have at least 3 vertices.", "PolygonValidator.IsConsistent()"); + return false; + } + + foreach (var p in points) { if (p == null) { horrors++; logger.Warning(String.Format("Point {0} is null.", i), "PolygonValidator.IsConsistent()"); } - else if (double.IsNaN(p.x + p.y) || double.IsInfinity(p.x + p.y)) + else if (double.IsNaN(p.x) || double.IsNaN(p.y)) { horrors++; logger.Warning(String.Format("Point {0} has invalid coordinates.", i), "PolygonValidator.IsConsistent()"); } + else if (double.IsInfinity(p.x) || double.IsInfinity(p.y)) + { + horrors++; + logger.Warning(String.Format("Point {0} has invalid coordinates.", i), "PolygonValidator.IsConsistent()"); + } + i++; } @@ -46,27 +61,33 @@ namespace TriangleNet.Tools { horrors++; logger.Warning(String.Format("Segment {0} is null.", i), "PolygonValidator.IsConsistent()"); - } - else - { - if (seg.P0 < 0 || seg.P0 >= count) - { - horrors++; - logger.Warning(String.Format("Segment {0} has invalid startpoint.", i), - "PolygonValidator.IsConsistent()"); - } - if (seg.P1 < 0 || seg.P1 >= count) - { - horrors++; - logger.Warning(String.Format("Segment {0} has invalid endpoint.", i), - "PolygonValidator.IsConsistent()"); - } + // Always abort if a NULL-segment is found. + return false; + } + + var p = seg.GetVertex(0); + var q = seg.GetVertex(1); + + if ((p.x == q.x) && (p.y == q.y)) + { + horrors++; + logger.Warning(String.Format("Endpoints of segment {0} are coincident (IDs {1} / {2}).", i, p.id, q.id), + "PolygonValidator.IsConsistent()"); } i++; } + if (points[0].ID == points[1].ID) + { + horrors += CheckVertexIDs(poly, count); + } + else + { + horrors += CheckDuplicateIDs(poly); + } + return horrors == 0; } @@ -116,8 +137,8 @@ namespace TriangleNet.Tools q0 = p0; q1 = p1; - p0 = (seg.P0 >= 0 && seg.P0 < count) ? poly.Points[seg.P0] : null; - p1 = (seg.P1 >= 0 && seg.P1 < count) ? poly.Points[seg.P1] : null; + p0 = seg.GetVertex(0); + p1 = seg.GetVertex(1); if (q0 != null && q1 != null) { @@ -160,5 +181,57 @@ namespace TriangleNet.Tools // Calculate the Z coordinate of the cross product. return (a.X - b.X) * (c.Y - b.Y) - (a.Y - b.Y) * (c.X - b.X); } + + private static int CheckVertexIDs(IPolygon poly, int count) + { + var logger = Log.Instance; + + int horrors = 0; + + int i = 0; + + Vertex p, q; + + foreach (var seg in poly.Segments) + { + p = seg.GetVertex(0); + q = seg.GetVertex(1); + + if (p.ID < 0 || p.ID >= count) + { + horrors++; + logger.Warning(String.Format("Segment {0} has invalid startpoint.", i), + "PolygonValidator.IsConsistent()"); + } + + if (q.ID < 0 || q.ID >= count) + { + horrors++; + logger.Warning(String.Format("Segment {0} has invalid endpoint.", i), + "PolygonValidator.IsConsistent()"); + } + + i++; + } + + return horrors; + } + + private static int CheckDuplicateIDs(IPolygon poly) + { + var ids = new HashSet(); + + // Check for duplicate ids. + foreach (var p in poly.Points) + { + if (!ids.Add(p.ID)) + { + Log.Instance.Warning("Found duplicate vertex ids.", "PolygonValidator.IsConsistent()"); + return 1; + } + } + + return 0; + } } } diff --git a/Triangle.NET/Triangle/Topology/Osub.cs b/Triangle.NET/Triangle/Topology/Osub.cs index 3a82522..f60281b 100644 --- a/Triangle.NET/Triangle/Topology/Osub.cs +++ b/Triangle.NET/Triangle/Topology/Osub.cs @@ -20,10 +20,10 @@ namespace TriangleNet.Topology /// public struct Osub { - internal Segment seg; + internal SubSegment seg; internal int orient; // Ranges from 0 to 1. - public Segment Segment + public SubSegment Segment { get { return seg; } } @@ -213,7 +213,7 @@ namespace TriangleNet.Topology /// /// Note that the other subsegment will still think it's /// connected to this subsegment. - internal void Dissolve(Segment dummy) + internal void Dissolve(SubSegment dummy) { seg.subsegs[orient].seg = dummy; } @@ -237,7 +237,7 @@ namespace TriangleNet.Topology /// /// Check a subsegment's deallocation. /// - internal static bool IsDead(Segment sub) + internal static bool IsDead(SubSegment sub) { return sub.subsegs[0].seg == null; } @@ -245,7 +245,7 @@ namespace TriangleNet.Topology /// /// Set a subsegment's deallocation. /// - internal static void Kill(Segment sub) + internal static void Kill(SubSegment sub) { sub.subsegs[0].seg = null; sub.subsegs[1].seg = null; diff --git a/Triangle.NET/Triangle/Topology/Otri.cs b/Triangle.NET/Triangle/Topology/Otri.cs index cc8da35..ba9efee 100644 --- a/Triangle.NET/Triangle/Topology/Otri.cs +++ b/Triangle.NET/Triangle/Topology/Otri.cs @@ -454,7 +454,7 @@ namespace TriangleNet.Topology /// /// Dissolve a bond (from the triangle side). /// - internal void SegDissolve(Segment dummy) + internal void SegDissolve(SubSegment dummy) { tri.subsegs[orient].seg = dummy; } diff --git a/Triangle.NET/Triangle/Topology/Segment.cs b/Triangle.NET/Triangle/Topology/SubSegment.cs similarity index 93% rename from Triangle.NET/Triangle/Topology/Segment.cs rename to Triangle.NET/Triangle/Topology/SubSegment.cs index 3cbb21b..dcbc78f 100644 --- a/Triangle.NET/Triangle/Topology/Segment.cs +++ b/Triangle.NET/Triangle/Topology/SubSegment.cs @@ -13,7 +13,7 @@ namespace TriangleNet.Topology /// /// The subsegment data structure. /// - public class Segment : ISegment + public class SubSegment : ISegment { // Hash for dictionary. Will be set by mesh instance. internal int hash; @@ -23,7 +23,7 @@ namespace TriangleNet.Topology internal Otri[] triangles; internal int boundary; - public Segment() + public SubSegment() { // Four NULL vertices. vertices = new Vertex[4]; diff --git a/Triangle.NET/Triangle/Triangle.csproj b/Triangle.NET/Triangle/Triangle.csproj index 7dd5d81..be22a09 100644 --- a/Triangle.NET/Triangle/Triangle.csproj +++ b/Triangle.NET/Triangle/Triangle.csproj @@ -38,15 +38,31 @@ - + + + - + + + + + + + + + + + + + + + @@ -54,69 +70,54 @@ - - - + + + + + + + + + + + - + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs b/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs index c9993a3..ace56aa 100644 --- a/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs +++ b/Triangle.NET/Triangle/Voronoi/Legacy/BoundedVoronoiLegacy.cs @@ -30,7 +30,7 @@ namespace TriangleNet.Voronoi.Legacy List segPoints; int segIndex; - Dictionary subsegMap; + Dictionary subsegMap; bool includeBoundary = true; @@ -151,7 +151,7 @@ namespace TriangleNet.Voronoi.Legacy int blinded = 0; Stack triangles; - subsegMap = new Dictionary(); + subsegMap = new Dictionary(); Otri f = default(Otri); Otri f0 = default(Otri);