diff --git a/src/Triangle.Examples/Examples/Example1.cs b/src/Triangle.Examples/Examples/Example1.cs new file mode 100644 index 0000000..2dbaa63 --- /dev/null +++ b/src/Triangle.Examples/Examples/Example1.cs @@ -0,0 +1,31 @@ + +namespace TriangleNet.Examples +{ + using TriangleNet.Geometry; + using TriangleNet.Meshing; + using TriangleNet.Meshing.Algorithm; + using TriangleNet.Rendering.Text; + + /// + /// Simple point set triangulation. + /// + public class Example1 + { + public static void Run(bool print = false) + { + // Generate points. + var points = Generate.RandomPoints(50, new Rectangle(0, 0, 100, 100)); + + // Choose triangulator: Incremental, SweepLine or Dwyer. + var triangulator = new Dwyer(); + + // Generate a default mesher. + var mesher = new GenericMesher(triangulator); + + // Generate mesh. + var mesh = mesher.Triangulate(points); + + if (print) SvgImage.Save(mesh, "example-1.png", 500); + } + } +} diff --git a/src/Triangle.Examples/Examples/Example2.cs b/src/Triangle.Examples/Examples/Example2.cs new file mode 100644 index 0000000..351d360 --- /dev/null +++ b/src/Triangle.Examples/Examples/Example2.cs @@ -0,0 +1,46 @@ +namespace TriangleNet.Examples +{ + using TriangleNet.Geometry; + using TriangleNet.Meshing; + using TriangleNet.Rendering.Text; + + /// + /// Triangulate a polygon with hole and set minimum angle constraint. + /// + public static class Example2 + { + public static void Run(bool print = false) + { + // Generate the input geometry. + var poly = CreatePolygon(); + + // Set minimum angle quality option. + var quality = new QualityOptions() { MinimumAngle = 30.0 }; + + // Generate mesh using the polygons Triangulate extension method. + var mesh = poly.Triangulate(quality); + + if (print) SvgImage.Save(mesh, "example-2.png", 500); + } + + public static IPolygon CreatePolygon(double h = 0.2) + { + // Generate the input geometry. + var poly = new Polygon(); + + // Center point. + var center = new Point(0, 0); + + // Inner contour (hole). + poly.Add(Generate.Circle(1.0, center, h, 1), center); + + // Internal contour. + poly.Add(Generate.Circle(2.0, center, h, 2)); + + // Outer contour. + poly.Add(Generate.Circle(3.0, center, h, 3)); + + return poly; + } + } +} \ No newline at end of file diff --git a/src/Triangle.Examples/Examples/Example3.cs b/src/Triangle.Examples/Examples/Example3.cs new file mode 100644 index 0000000..fbf3750 --- /dev/null +++ b/src/Triangle.Examples/Examples/Example3.cs @@ -0,0 +1,52 @@ + +namespace TriangleNet.Examples +{ + using System; + using TriangleNet.Geometry; + using TriangleNet.Meshing; + using TriangleNet.Rendering.Text; + using TriangleNet.Smoothing; + + /// + /// Triangulate a polygon with hole with maximum area constraint, followed by mesh smoothing. + /// + public class Example3 + { + public static void Run(bool print = false) + { + // Generate mesh. + var mesh = CreateMesh(); + + if (print) SvgImage.Save(mesh, "example-3.png", 500); + } + + public static IMesh CreateMesh() + { + // Generate the input geometry. + var poly = Example2.CreatePolygon(); + + // Since we want to do CVT smoothing, ensure that the mesh + // is conforming Delaunay. + var options = new ConstraintOptions() { ConformingDelaunay = true }; + + // Set maximum area quality option (we don't need to set a minimum + // angle, since smoothing will improve the triangle shapes). + var quality = new QualityOptions() + { + // The boundary segments have a length of 0.2, so we set a + // maximum area constraint assuming equilateral triangles. + MaximumArea = (Math.Sqrt(3) / 4 * 0.2 * 0.2) * 1.45 + }; + + // Generate mesh using the polygons Triangulate extension method. + var mesh = poly.Triangulate(options, quality); + + var smoother = new SimpleSmoother(); + + // Smooth mesh. + smoother.Smooth(mesh, 25); + + return mesh; + } + } +} diff --git a/src/Triangle.Examples/Examples/Example4.cs b/src/Triangle.Examples/Examples/Example4.cs new file mode 100644 index 0000000..c7ab07a --- /dev/null +++ b/src/Triangle.Examples/Examples/Example4.cs @@ -0,0 +1,69 @@ + +namespace TriangleNet.Examples +{ + using TriangleNet; + using TriangleNet.Geometry; + using TriangleNet.Meshing; + using TriangleNet.Rendering.Text; + using TriangleNet.Smoothing; + + /// + /// Refine only a part of a polygon mesh be using region pointers and an area constraint. + /// + public class Example4 + { + public static void Run(bool print = false) + { + // Generate the input geometry. + var poly = CreatePolygon(); + + // Define regions (first one defines the area constraint). + poly.Regions.Add(new RegionPointer(1.5, 0.0, 1, 0.01)); + poly.Regions.Add(new RegionPointer(2.5, 0.0, 2)); + + // Set quality and constraint options. + var options = new ConstraintOptions() + { + ConformingDelaunay = true + }; + + var quality = new QualityOptions() + { + MinimumAngle = 25.0, + VariableArea = true + }; + + //quality.UserTest = (t, area) => t.Label == 1 && area > 0.01; + + var mesh = poly.Triangulate(options, quality); + + var smoother = new SimpleSmoother(); + + smoother.Smooth(mesh, 5); + + if (print) SvgImage.Save(mesh, "example-4.png", 500); + } + + public static IPolygon CreatePolygon() + { + // Generate three concentric circles. + var poly = new Polygon(); + + // Center point. + var center = new Point(0, 0); + + // Inner contour (hole). + poly.Add(Generate.Circle(1.0, center, 0.1, 1), center); + + // Internal contour. + poly.Add(Generate.Circle(2.0, center, 0.1, 2)); + + // Outer contour. + poly.Add(Generate.Circle(3.0, center, 0.3, 3)); + + // Note that the outer contour has a larger segment size! + + return poly; + } + } +} diff --git a/src/Triangle.Examples/Examples/Example5.cs b/src/Triangle.Examples/Examples/Example5.cs new file mode 100644 index 0000000..a38529c --- /dev/null +++ b/src/Triangle.Examples/Examples/Example5.cs @@ -0,0 +1,96 @@ + +namespace TriangleNet.Examples +{ + using System.Collections.Generic; + using TriangleNet; + using TriangleNet.Geometry; + using TriangleNet.Meshing; + using TriangleNet.Meshing.Iterators; + using TriangleNet.Rendering.Text; + + /// + /// Two ways finding boundary triangles. + /// + public static class Example5 + { + public static void Run(bool print = false) + { + var mesh = Example3.CreateMesh(); + + FindBoundary1(mesh); + + if (print) SvgImage.Save(mesh, "example-5-1.png", 500, true, false); + + FindBoundary2(mesh); + + if (print) SvgImage.Save(mesh, "example-5-2.png", 500, true, false); + } + + /// + /// Find boundary triangles using segments. + /// + private static void FindBoundary1(IMesh mesh, bool neigbours = true) + { + mesh.Renumber(); + + var cache = new List(mesh.Segments.Count + 1); + + var circulator = new VertexCirculator((Mesh)mesh); + + foreach (var s in mesh.Segments) + { + int label = s.Label; + + for (int i = 0; i < 2; i++) + { + var vertex = s.GetVertex(i); + + // Check the vertex ID to see if it was processed already. + if (vertex.ID >= 0) + { + var star = circulator.EnumerateTriangles(vertex); + + foreach (var triangle in star) + { + triangle.Label = label; + } + + // Mark the vertex as "processed". + vertex.ID = -vertex.ID; + + cache.Add(vertex); + } + } + } + + // Undo the vertex ID changes. + foreach (var vertex in cache) + { + vertex.ID = -vertex.ID; + } + } + + /// + /// Find boundary triangles using vertices. + /// + private static void FindBoundary2(IMesh mesh) + { + var circulator = new VertexCirculator((Mesh)mesh); + + foreach (var vertex in mesh.Vertices) + { + int label = vertex.Label; + + if (label > 0) + { + var star = circulator.EnumerateTriangles(vertex); + + foreach (var triangle in star) + { + triangle.Label = label; + } + } + } + } + } +} diff --git a/src/Triangle.Examples/Examples/Example6.cs b/src/Triangle.Examples/Examples/Example6.cs new file mode 100644 index 0000000..d114eca --- /dev/null +++ b/src/Triangle.Examples/Examples/Example6.cs @@ -0,0 +1,51 @@ +namespace TriangleNet.Examples +{ + using System.Linq; + using TriangleNet; + using TriangleNet.Geometry; + using TriangleNet.Meshing.Iterators; + using TriangleNet.Tools; + using TriangleNet.Topology; + + /// + /// Boolean operation on mesh regions (intersection, difference, xor). + /// + public static class Example6 + { + public static void Run() //FindRegions() + { + // Generate the input geometry. + var polygon = new Polygon(8, true); + + // Two intersecting rectangles. + var A = Generate.Rectangle(0.0, 4.0, 4.0, 0.0, 1); + var B = Generate.Rectangle(1.0, 5.0, 3.0, 1.0, 2); + + polygon.Add(A); + polygon.Add(B); + + // Generate mesh. + var mesh = (Mesh)polygon.Triangulate(); + + // Find a seeding triangle (in this case, the point (2, 2) lies in + // both rectangles). + var seed = (new TriangleQuadTree(mesh)).Query(2.0, 2.0) as Triangle; + + var iterator = new RegionIterator(mesh); + + iterator.Process(seed, t => t.Label ^= 1, 1); + iterator.Process(seed, t => t.Label ^= 2, 2); + + // At this point, all triangles will have label 1, 2 or 3 (= 1 xor 2). + + // The intersection of A and B. + var intersection = mesh.Triangles.Where(t => t.Label == 3); + + // The difference A \ B. + var difference = mesh.Triangles.Where(t => t.Label == 1); + + // The xor of A and B. + var xor = mesh.Triangles.Where(t => t.Label == 1 || t.Label == 2); + } + } +} \ No newline at end of file diff --git a/src/Triangle.Examples/Examples/Example7.cs b/src/Triangle.Examples/Examples/Example7.cs new file mode 100644 index 0000000..f08de35 --- /dev/null +++ b/src/Triangle.Examples/Examples/Example7.cs @@ -0,0 +1,58 @@ + +namespace TriangleNet.Examples +{ + using TriangleNet.Geometry; + using TriangleNet.Meshing; + using TriangleNet.Rendering.Text; + + /// + /// Using a user test function to define a maximum edge length constraint. + /// + public static class Example7 + { + const double MAX_EDGE_LENGTH = 0.2; + + public static void Run(bool print = false) + { + var poly = new Polygon(); + + // Generate the input geometry. + poly.Add(Generate.Rectangle(0.0, 1.0, 1.0, 0.0)); + + // Set minimum angle quality option, ignoring holes. + var quality = new QualityOptions() + { + UserTest = MaxEdgeLength + }; + + // Generate mesh using the polygons Triangulate extension method. + var mesh = poly.Triangulate(quality); + + if (print) SvgImage.Save(mesh, "example-7.svg", 500); + } + + static bool MaxEdgeLength(ITriangle tri, double area) + { + var p0 = tri.GetVertex(0); + var p1 = tri.GetVertex(1); + var p2 = tri.GetVertex(2); + + var s1 = DistSqr(p0, p1); + var s2 = DistSqr(p1, p2); + var s3 = DistSqr(p2, p0); + + // Comparing against squared max leg length. + var maxlen = MAX_EDGE_LENGTH * MAX_EDGE_LENGTH; + + return s1 > maxlen || s2 > maxlen || s3 > maxlen; + } + + static double DistSqr(Vertex a, Vertex b) + { + var dx = a.X - b.X; + var dy = a.Y - b.Y; + + return dx * dx + dy * dy; + } + } +} diff --git a/src/Triangle.Examples/Examples/Example8.cs b/src/Triangle.Examples/Examples/Example8.cs new file mode 100644 index 0000000..02b6dcf --- /dev/null +++ b/src/Triangle.Examples/Examples/Example8.cs @@ -0,0 +1,82 @@ + +namespace TriangleNet.Examples +{ + using System; + using System.Collections.Generic; + using TriangleNet; + using TriangleNet.Meshing.Iterators; + using TriangleNet.Tools; + + /// + /// Compute the adjacency matrix of the mesh vertices. + /// + public class Example8 + { + public static void Run() + { + var mesh = (Mesh)Example3.CreateMesh(); + + FindAdjacencyMatrix(mesh); + } + + private static void FindAdjacencyMatrix(Mesh mesh) + { + mesh.Renumber(); + + var ap = new List(mesh.Vertices.Count); // Column pointers. + var ai = new List(4 * mesh.Vertices.Count); // Row indices. + + var circulator = new VertexCirculator(mesh); + + int k = 0; + + foreach (var vertex in mesh.Vertices) + { + var star = circulator.EnumerateVertices(vertex); + + ap.Add(k); + + // Each vertex is adjacent to itself. + ai.Add(vertex.ID); + k++; + + foreach (var item in star) + { + ai.Add(item.ID); + k++; + } + } + + ap.Add(k); + + var matrix1 = new AdjacencyMatrix(ap.ToArray(), ai.ToArray()); + var matrix2 = new AdjacencyMatrix(mesh); + + // Column pointers should be exactly the same. + if (!CompareArray(matrix1.ColumnPointers, matrix2.ColumnPointers)) + { + Console.WriteLine("Something's wrong in here ..."); + } + } + + private static bool CompareArray(int[] a, int[] b) + { + int length = a.Length; + + if (b.Length != length) + { + return false; + } + + for (int i = 0; i < length; i++) + { + if (a[i] != b[i]) + { + return false; + } + } + + return true; + } + } +} diff --git a/src/Triangle.Examples/Examples/Example9.cs b/src/Triangle.Examples/Examples/Example9.cs new file mode 100644 index 0000000..68d6157 --- /dev/null +++ b/src/Triangle.Examples/Examples/Example9.cs @@ -0,0 +1,84 @@ + +namespace TriangleNet.Examples +{ + using System; + using System.Collections.Generic; + using System.Linq; + using TriangleNet.Geometry; + + /// + /// Troubleshooting: finding degenerate boundary triangles. + /// + public class Example9 + { + public static void Run() + { + var pts = new List + { + // The 4 corners of the square. + new Vertex(1.5, 1.0), + new Vertex(1.5, -1.0), + new Vertex(-1.5, -1.0), + new Vertex(-1.5, 1.0), + + // The edge midpoints. + new Vertex(0.0, 1.0), + new Vertex(0.0, -1.0), + new Vertex(1.5, 0.0), + new Vertex(-1.5, 0.0) + }; + + var r = new Random(78403); + + // The original rectangle. + var poly = Rotate(pts, 0); + + for (int i = 0; i < 10; i++) + { + var mesh = poly.Triangulate(); + + var list = MeshValidator.GetDegenerateBoundaryTriangles(mesh); + + if (list.Any()) + { + Console.WriteLine("Iteration {0}: found {1} degenerate triangle(s) of {2}.", + i, list.Count(), mesh.Triangles.Count); + + foreach (var t in list) + { + Console.WriteLine(" [{0} {1} {2}]", + t.GetVertexID(0), + t.GetVertexID(1), + t.GetVertexID(2)); + } + } + + // Random rotation. + poly = Rotate(pts, Math.PI * r.NextDouble()); + } + } + + /// + /// Rotate given point set around the origin. + /// + private static IPolygon Rotate(List points, double radians) + { + var poly = new Polygon(points.Count); + + int id = 0; + + foreach (var p in points) + { + double x = p.X; + double y = p.Y; + + double xr = Math.Cos(radians) * x - Math.Sin(radians) * y; + double yr = Math.Sin(radians) * x + Math.Cos(radians) * y; + + poly.Points.Add(new Vertex(xr, yr) { ID = id++ }); + } + + return poly; + } + } +} diff --git a/src/Triangle.Examples/Generate.cs b/src/Triangle.Examples/Generate.cs new file mode 100644 index 0000000..ccf8c47 --- /dev/null +++ b/src/Triangle.Examples/Generate.cs @@ -0,0 +1,75 @@ + +namespace TriangleNet +{ + using System; + using System.Collections.Generic; + using TriangleNet.Geometry; + + static class Generate + { + private const int RANDOM_SEED = 63841; + + public static List RandomPoints(int n, Rectangle bounds, + int seed = RANDOM_SEED) + { + var points = new List(n); + + var xmin = bounds.Left; + var ymin = bounds.Bottom; + + var width = bounds.Width; + var height = bounds.Height; + + var random = new Random(seed); + + for (int i = 0; i < n; i++) + { + double x = random.NextDouble(); + double y = random.NextDouble(); + points.Add(new Vertex(xmin + x * width, ymin + y * height)); + } + + return points; + } + + public static Contour Rectangle(double left, double top, + double right, double bottom, int mark = 0) + { + var points = new List(4); + + points.Add(new Vertex(left, top, mark)); + points.Add(new Vertex(right, top, mark)); + points.Add(new Vertex(right, bottom, mark)); + points.Add(new Vertex(left, bottom, mark)); + + return new Contour(points, mark, true); + } + + /// + /// Create a circular contour. + /// + /// The radius. + /// The center point. + /// The desired segment length. + /// The boundary label. + /// A circular contour. + public static Contour Circle(double r, Point center, double h, int label = 0) + { + int n = (int)(2 * Math.PI * r / h); + + var points = new List(n); + + double x, y, dphi = 2 * Math.PI / n; + + for (int i = 0; i < n; i++) + { + x = center.X + r * Math.Cos(i * dphi); + y = center.Y + r * Math.Sin(i * dphi); + + points.Add(new Vertex(x, y, label)); + } + + return new Contour(points, label, true); + } + } +} diff --git a/src/Triangle.Examples/Program.cs b/src/Triangle.Examples/Program.cs new file mode 100644 index 0000000..4276026 --- /dev/null +++ b/src/Triangle.Examples/Program.cs @@ -0,0 +1,21 @@ + +namespace TriangleNet +{ + using TriangleNet.Examples; + + class Program + { + static void Main(string[] args) + { + Example1.Run(); + Example2.Run(); + Example3.Run(); + Example4.Run(); + Example5.Run(); + Example8.Run(); + Example6.Run(); + Example7.Run(); + Example9.Run(); + } + } +} \ No newline at end of file diff --git a/src/Triangle.Examples/Triangle.Examples.csproj b/src/Triangle.Examples/Triangle.Examples.csproj new file mode 100644 index 0000000..07f242f --- /dev/null +++ b/src/Triangle.Examples/Triangle.Examples.csproj @@ -0,0 +1,23 @@ + + + + Exe + net6.0 + TriangleNet + $(SolutionDir)bin\$(Configuration) + + + + + + + + + + + + + + + + diff --git a/src/Triangle.Rendering/Text/FormattingStreamWriter.cs b/src/Triangle.Rendering/Text/FormattingStreamWriter.cs index 72b5917..e134a7c 100644 --- a/src/Triangle.Rendering/Text/FormattingStreamWriter.cs +++ b/src/Triangle.Rendering/Text/FormattingStreamWriter.cs @@ -6,7 +6,7 @@ namespace TriangleNet.Rendering.Text using System.IO; /// - /// + /// A class allowing to specify the . /// /// /// From http://stackoverflow.com/questions/12011789/streamwriter-and-iformatprovider @@ -62,12 +62,6 @@ namespace TriangleNet.Rendering.Text /// /// Gets an object that controls formatting. /// - public override IFormatProvider FormatProvider - { - get - { - return this.formatProvider; - } - } + public override IFormatProvider FormatProvider => formatProvider; } } diff --git a/src/Triangle.Rendering/Text/SvgImage.cs b/src/Triangle.Rendering/Text/SvgImage.cs index da19b3f..5b63777 100644 --- a/src/Triangle.Rendering/Text/SvgImage.cs +++ b/src/Triangle.Rendering/Text/SvgImage.cs @@ -11,6 +11,7 @@ namespace TriangleNet.Rendering.Text using System.Text; using TriangleNet; using TriangleNet.Geometry; + using TriangleNet.Meshing; using TriangleNet.Meshing.Iterators; /// @@ -24,17 +25,31 @@ namespace TriangleNet.Rendering.Text float scale = 1f; /// - /// Export the mesh to SVG format. + /// Exports a mesh to SVG format. + /// + /// The mesh. + /// The SVG filename. + /// The desired width (pixel) of the image. + /// Enable rendering of regions. + /// Enable rendering of points. + public static void Save(IMesh mesh, string file = null, int width = 800, + bool regions = false, bool points = true) + { + new SvgImage().Export(mesh, file, width); + } + + /// + /// Export a mesh to SVG format. /// /// The current mesh. /// The SVG filename. /// The desired width of the image. - public void Export(Mesh mesh, string filename, int width) + public void Export(IMesh mesh, string filename, int width) { // Check file name - if (String.IsNullOrWhiteSpace(filename)) + if (string.IsNullOrWhiteSpace(filename)) { - filename = String.Format("mesh-{0}.svg", DateTime.Now.ToString("yyyy-M-d-hh-mm-ss")); + filename = string.Format("mesh-{0}.svg", DateTime.Now.ToString("yyyy-M-d-hh-mm-ss")); } if (!filename.EndsWith(".svg")) @@ -79,11 +94,11 @@ namespace TriangleNet.Rendering.Text } } - private void DrawTriangles(StreamWriter svg, Mesh mesh, bool label) + private void DrawTriangles(StreamWriter svg, IMesh mesh, bool label) { svg.Write("\t"); } - private void DrawSegments(StreamWriter svg, Mesh mesh) + private void DrawSegments(StreamWriter svg, IMesh mesh) { svg.Write("\t"); } - private void DrawPoints(StreamWriter svg, Mesh mesh, bool label) + private void DrawPoints(StreamWriter svg, IMesh mesh, bool label) { int n = mesh.Vertices.Count; @@ -223,7 +234,7 @@ namespace TriangleNet.Rendering.Text double x, y; - StringBuilder labels = new StringBuilder(); + var labels = new StringBuilder(); foreach (var node in mesh.Vertices) { diff --git a/src/Triangle.sln b/src/Triangle.sln index 99960ec..25ef40f 100644 --- a/src/Triangle.sln +++ b/src/Triangle.sln @@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Triangle.Rendering", "Trian EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Triangle.Tests", "Triangle.Tests\Triangle.Tests.csproj", "{67CCA496-DCD1-4D43-85D5-0A19A3948774}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle.Examples", "Triangle.Examples\Triangle.Examples.csproj", "{70EC2A88-E7CC-4678-9936-ED539969B003}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +53,14 @@ Global {67CCA496-DCD1-4D43-85D5-0A19A3948774}.Release|Any CPU.Build.0 = Release|Any CPU {67CCA496-DCD1-4D43-85D5-0A19A3948774}.Release|x64.ActiveCfg = Release|Any CPU {67CCA496-DCD1-4D43-85D5-0A19A3948774}.Release|x64.Build.0 = Release|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Debug|x64.ActiveCfg = Debug|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Debug|x64.Build.0 = Debug|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Release|Any CPU.Build.0 = Release|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Release|x64.ActiveCfg = Release|Any CPU + {70EC2A88-E7CC-4678-9936-ED539969B003}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Triangle/Meshing/Iterators/EdgeIterator.cs b/src/Triangle/Meshing/Iterators/EdgeIterator.cs index 056b925..773eebf 100644 --- a/src/Triangle/Meshing/Iterators/EdgeIterator.cs +++ b/src/Triangle/Meshing/Iterators/EdgeIterator.cs @@ -15,7 +15,7 @@ namespace TriangleNet.Meshing.Iterators /// public class EdgeIterator { - public IEnumerable EnumerateEdges(Mesh mesh) + public IEnumerable EnumerateEdges(IMesh mesh) { Otri tri = default; Otri neighbor = default; @@ -23,7 +23,7 @@ namespace TriangleNet.Meshing.Iterators Vertex p1, p2; - foreach (var t in mesh.triangles) + foreach (var t in mesh.Triangles) { tri.tri = t; tri.orient = 0; @@ -57,10 +57,10 @@ namespace TriangleNet.Meshing.Iterators /// /// /// - /// In contrast to the this method will return + /// In contrast to this method will return /// objects that include the vertex information (and not only the indices). /// - public static IEnumerable EnumerateEdges(Mesh mesh, bool skipSegments = true) + public static IEnumerable EnumerateEdges(IMesh mesh, bool skipSegments = true) { Otri tri = default; Otri neighbor = default; @@ -70,7 +70,7 @@ namespace TriangleNet.Meshing.Iterators bool segments = !skipSegments; - foreach (var t in mesh.triangles) + foreach (var t in mesh.Triangles) { tri.tri = t; tri.orient = 0;