From 6796de7c3cd2525228aae62437304946943d7ec8 Mon Sep 17 00:00:00 2001 From: Yasar YY Date: Mon, 6 Jan 2025 18:17:18 +0300 Subject: [PATCH 1/2] Cancellation option is added to Triangulate, Refine and Smooth methods. --- src/Triangle.sln | 20 ++++++++++++++++++++ src/Triangle/Geometry/ExtensionMethods.cs | 12 +++++++----- src/Triangle/Mesh.cs | 6 ++++-- src/Triangle/Meshing/GenericMesher.cs | 11 +++++++---- src/Triangle/Meshing/IMesh.cs | 8 ++++---- src/Triangle/Meshing/QualityMesher.cs | 11 ++++++++--- src/Triangle/Smoothing/SimpleSmoother.cs | 7 ++++++- 7 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/Triangle.sln b/src/Triangle.sln index e69823c..b9a8be8 100644 --- a/src/Triangle.sln +++ b/src/Triangle.sln @@ -11,6 +11,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Triangle.Examples", "Triang EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Triangle.Rendering", "Triangle.Rendering\Triangle.Rendering.csproj", "{20D64FA8-EC38-4507-9D99-96F855ED62C0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle.Viewer", "Triangle.Viewer\Triangle.Viewer.csproj", "{7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle.Rendering.GDI", "Triangle.Rendering.GDI\Triangle.Rendering.GDI.csproj", "{6FD3B121-D7C0-4708-9FF7-77DF820849AB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +55,22 @@ Global {20D64FA8-EC38-4507-9D99-96F855ED62C0}.Release|Any CPU.Build.0 = Release|Any CPU {20D64FA8-EC38-4507-9D99-96F855ED62C0}.Release|x64.ActiveCfg = Release|x64 {20D64FA8-EC38-4507-9D99-96F855ED62C0}.Release|x64.Build.0 = Release|x64 + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|x64.ActiveCfg = Debug|x64 + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|x64.Build.0 = Debug|x64 + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|Any CPU.Build.0 = Release|Any CPU + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|x64.ActiveCfg = Release|x64 + {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|x64.Build.0 = Release|x64 + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|x64.ActiveCfg = Debug|x64 + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|x64.Build.0 = Debug|x64 + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|Any CPU.Build.0 = Release|Any CPU + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|x64.ActiveCfg = Release|x64 + {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Triangle/Geometry/ExtensionMethods.cs b/src/Triangle/Geometry/ExtensionMethods.cs index fae7666..1874068 100644 --- a/src/Triangle/Geometry/ExtensionMethods.cs +++ b/src/Triangle/Geometry/ExtensionMethods.cs @@ -1,7 +1,7 @@  namespace TriangleNet.Geometry { - using System; + using System.Threading; using TriangleNet.Meshing; /// @@ -34,9 +34,10 @@ public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options /// /// Polygon instance. /// Quality options. - public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality) + /// A token that receives a cancellation notification when requested. + public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality, CancellationToken cancellationToken = default) { - return (new GenericMesher()).Triangulate(polygon, null, quality); + return (new GenericMesher()).Triangulate(polygon, null, quality, cancellationToken); } /// @@ -45,9 +46,10 @@ public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality) /// Polygon instance. /// Constraint options. /// Quality options. - public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality) + /// A token that receives a cancellation notification when requested. + public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality, CancellationToken cancellationToken = default) { - return (new GenericMesher()).Triangulate(polygon, options, quality); + return (new GenericMesher()).Triangulate(polygon, options, quality, cancellationToken); } /// diff --git a/src/Triangle/Mesh.cs b/src/Triangle/Mesh.cs index 0c0be46..eb012ea 100644 --- a/src/Triangle/Mesh.cs +++ b/src/Triangle/Mesh.cs @@ -9,6 +9,7 @@ namespace TriangleNet { using System; using System.Collections.Generic; + using System.Threading; using TriangleNet.Geometry; using TriangleNet.Meshing; using TriangleNet.Meshing.Data; @@ -224,7 +225,8 @@ public Mesh(Configuration config, IList points) /// /// The quality constraints. /// A value indicating, whether the refined mesh should be Conforming Delaunay. - public void Refine(QualityOptions quality, bool delaunay = false) + /// A token that receives a cancellation notification when requested. + public void Refine(QualityOptions quality, bool delaunay = false, CancellationToken cancellationToken = default) { invertices = vertices.Count; @@ -241,7 +243,7 @@ public void Refine(QualityOptions quality, bool delaunay = false) } // Enforce angle and area constraints. - qualityMesher.Apply(quality, delaunay); + qualityMesher.Apply(quality, delaunay, cancellationToken); } /// diff --git a/src/Triangle/Meshing/GenericMesher.cs b/src/Triangle/Meshing/GenericMesher.cs index d46080c..83cd60e 100644 --- a/src/Triangle/Meshing/GenericMesher.cs +++ b/src/Triangle/Meshing/GenericMesher.cs @@ -8,6 +8,7 @@ namespace TriangleNet.Meshing { using System; using System.Collections.Generic; + using System.Threading; using TriangleNet.Geometry; using TriangleNet.IO; using TriangleNet.Meshing.Algorithm; @@ -96,10 +97,11 @@ public IMesh Triangulate(IPolygon polygon, ConstraintOptions options) /// /// The input polygon. /// The . + /// A token that receives a cancellation notification when requested. /// The mesh. - public IMesh Triangulate(IPolygon polygon, QualityOptions quality) + public IMesh Triangulate(IPolygon polygon, QualityOptions quality, CancellationToken cancellationToken = default) { - return Triangulate(polygon, null, quality); + return Triangulate(polygon, null, quality, cancellationToken); } /// @@ -108,8 +110,9 @@ public IMesh Triangulate(IPolygon polygon, QualityOptions quality) /// The input polygon. /// The . /// The . + /// A token that receives a cancellation notification when requested. /// The mesh. - public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality) + public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality, CancellationToken cancellationToken = default) { var mesh = (Mesh)triangulator.Triangulate(polygon.Points, config); @@ -122,7 +125,7 @@ public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOpt cmesher.Apply(polygon, options); // Refine mesh. - qmesher.Apply(quality); + qmesher.Apply(quality, options?.ConformingDelaunay ?? false, cancellationToken); return mesh; } diff --git a/src/Triangle/Meshing/IMesh.cs b/src/Triangle/Meshing/IMesh.cs index b1be86b..20d579a 100644 --- a/src/Triangle/Meshing/IMesh.cs +++ b/src/Triangle/Meshing/IMesh.cs @@ -2,6 +2,7 @@ namespace TriangleNet.Meshing { using System.Collections.Generic; + using System.Threading; using TriangleNet.Topology; using TriangleNet.Geometry; @@ -49,9 +50,8 @@ public interface IMesh /// Refine the mesh. /// /// The quality constraints. - /// - /// A value indicating, whether the refined mesh should be Conforming Delaunay. - /// - void Refine(QualityOptions quality, bool delaunay); + /// A value indicating, whether the refined mesh should be Conforming Delaunay. + /// A token that receives a cancellation notification when requested. + void Refine(QualityOptions quality, bool delaunay, CancellationToken cancellationToken = default); } } diff --git a/src/Triangle/Meshing/QualityMesher.cs b/src/Triangle/Meshing/QualityMesher.cs index dfa19ec..7a97565 100644 --- a/src/Triangle/Meshing/QualityMesher.cs +++ b/src/Triangle/Meshing/QualityMesher.cs @@ -9,6 +9,7 @@ namespace TriangleNet.Meshing { using System; using System.Collections.Generic; + using System.Threading; using TriangleNet.Geometry; using TriangleNet.Meshing.Data; using TriangleNet.Topology; @@ -55,7 +56,8 @@ public QualityMesher(Mesh mesh, Configuration config) /// /// The quality constraints. /// A value indicating, whether the refined mesh should be Conforming Delaunay. - public void Apply(QualityOptions quality, bool delaunay = false) + /// A token that receives a cancellation notification when requested. + public void Apply(QualityOptions quality, bool delaunay = false, CancellationToken cancellationToken = default) { // Copy quality options if (quality != null) @@ -98,7 +100,7 @@ public void Apply(QualityOptions quality, bool delaunay = false) if (behavior.Quality && mesh.triangles.Count > 0) { // Enforce angle and area constraints. - EnforceQuality(); + EnforceQuality(cancellationToken); } } @@ -841,7 +843,7 @@ private void SplitTriangle(BadTriangle badtri) /// /// Remove all the encroached subsegments and bad triangles from the triangulation. /// - private void EnforceQuality() + private void EnforceQuality(CancellationToken cancellationToken) { BadTriangle badtri; @@ -864,6 +866,9 @@ private void EnforceQuality() mesh.checkquality = true; while ((queue.Count > 0) && (mesh.steinerleft != 0)) { + // throw an OperationCanceledException if cancellation is requested + cancellationToken.ThrowIfCancellationRequested(); + // Fix one bad triangle by inserting a vertex at its circumcenter. badtri = queue.Dequeue(); SplitTriangle(badtri); diff --git a/src/Triangle/Smoothing/SimpleSmoother.cs b/src/Triangle/Smoothing/SimpleSmoother.cs index a0f6fc2..30e4b05 100644 --- a/src/Triangle/Smoothing/SimpleSmoother.cs +++ b/src/Triangle/Smoothing/SimpleSmoother.cs @@ -5,6 +5,7 @@ // ----------------------------------------------------------------------- using System; +using System.Threading; namespace TriangleNet.Smoothing { @@ -77,11 +78,12 @@ public SimpleSmoother(IVoronoiFactory factory, Configuration config) /// the previous and the current solutions. If their relative difference /// is not greater than the tolerance, the current solution is /// considered good enough already. + /// A token that receives a cancellation notification when requested. /// The number of actual iterations performed. It is 0 if a /// non-positive limit is passed. Otherwise, it is always a value /// between 1 and the limit (inclusive). /// - public int Smooth(IMesh mesh, int limit = 10, double tol = .01) + public int Smooth(IMesh mesh, int limit = 10, double tol = .01, CancellationToken cancellationToken = default) { if (limit <= 0) return 0; @@ -106,6 +108,9 @@ public int Smooth(IMesh mesh, int limit = 10, double tol = .01) int i = 0; while (i < limit && Math.Abs(currMax - prevMax) > tol * currMax) { + // throw an OperationCanceledException if cancellation is requested + cancellationToken.ThrowIfCancellationRequested(); + prevMax = currMax; currMax = Step(smoothedMesh, factory, predicates); From 9de8c089eb7a69a36575ec8fd562268b0a1ec71a Mon Sep 17 00:00:00 2001 From: Yasar YY Date: Mon, 6 Jan 2025 19:38:12 +0300 Subject: [PATCH 2/2] Removed the Windows specific projects from the solution file. --- src/Triangle.sln | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/Triangle.sln b/src/Triangle.sln index b9a8be8..e69823c 100644 --- a/src/Triangle.sln +++ b/src/Triangle.sln @@ -11,10 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Triangle.Examples", "Triang EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Triangle.Rendering", "Triangle.Rendering\Triangle.Rendering.csproj", "{20D64FA8-EC38-4507-9D99-96F855ED62C0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle.Viewer", "Triangle.Viewer\Triangle.Viewer.csproj", "{7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Triangle.Rendering.GDI", "Triangle.Rendering.GDI\Triangle.Rendering.GDI.csproj", "{6FD3B121-D7C0-4708-9FF7-77DF820849AB}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -55,22 +51,6 @@ Global {20D64FA8-EC38-4507-9D99-96F855ED62C0}.Release|Any CPU.Build.0 = Release|Any CPU {20D64FA8-EC38-4507-9D99-96F855ED62C0}.Release|x64.ActiveCfg = Release|x64 {20D64FA8-EC38-4507-9D99-96F855ED62C0}.Release|x64.Build.0 = Release|x64 - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|x64.ActiveCfg = Debug|x64 - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Debug|x64.Build.0 = Debug|x64 - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|Any CPU.Build.0 = Release|Any CPU - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|x64.ActiveCfg = Release|x64 - {7DF0A588-6524-456E-9DEB-0A6E4C8BD66E}.Release|x64.Build.0 = Release|x64 - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|x64.ActiveCfg = Debug|x64 - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Debug|x64.Build.0 = Debug|x64 - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|Any CPU.Build.0 = Release|Any CPU - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|x64.ActiveCfg = Release|x64 - {6FD3B121-D7C0-4708-9FF7-77DF820849AB}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE