From ebec7286266e098fd22f019a37db803bc738de25 Mon Sep 17 00:00:00 2001 From: "SND\\wo80_cp" Date: Sat, 12 May 2012 09:35:11 +0000 Subject: [PATCH] Fixed issue #9389 Workaround for issue #9390 git-svn-id: https://triangle.svn.codeplex.com/svn@67385 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5 --- Triangle.NET/TestApp/Form1.cs | 1 - Triangle.NET/Triangle/Carver.cs | 49 ++++++++++++++++++++++++++++++-- Triangle.NET/Triangle/Mesh.cs | 2 ++ Triangle.NET/Triangle/Sampler.cs | 9 ++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Triangle.NET/TestApp/Form1.cs b/Triangle.NET/TestApp/Form1.cs index 78cbdce..316febf 100644 --- a/Triangle.NET/TestApp/Form1.cs +++ b/Triangle.NET/TestApp/Form1.cs @@ -131,7 +131,6 @@ namespace TestApp { dlgDirectory = Path.GetFullPath(@"Data\"); } - } private void btnRandPts_Click(object sender, EventArgs e) diff --git a/Triangle.NET/Triangle/Carver.cs b/Triangle.NET/Triangle/Carver.cs index 47fc91f..3065333 100644 --- a/Triangle.NET/Triangle/Carver.cs +++ b/Triangle.NET/Triangle/Carver.cs @@ -9,6 +9,7 @@ namespace TriangleNet { using TriangleNet.Data; using System; + using System.Collections.Generic; /// /// Carves holes into the triangulation. @@ -27,7 +28,7 @@ namespace TriangleNet /// protected by subsegments. Where there are subsegments, set boundary /// markers as appropriate. /// - void InfectHull() + bool InfectHull() { Otri hulltri = default(Otri); Otri nexttri = default(Otri); @@ -35,6 +36,9 @@ namespace TriangleNet Osub hullsubseg = default(Osub); Vertex horg, hdest; + int workaround, ntri = mesh.triangles.Count; + Queue infectedTris = new Queue(); + // Find a triangle handle on the hull. hulltri.triangle = Mesh.dummytri; hulltri.orient = 0; @@ -44,6 +48,8 @@ namespace TriangleNet // Go once counterclockwise around the convex hull. do { + workaround = 0; + // Ignore triangles that are already infected. if (!hulltri.IsInfected()) { @@ -56,6 +62,8 @@ namespace TriangleNet { hulltri.Infect(); mesh.viri.Add(hulltri.triangle); + + infectedTris.Enqueue(hulltri.triangle); } } else @@ -84,8 +92,23 @@ namespace TriangleNet { nexttri.Copy(ref hulltri); hulltri.Oprev(ref nexttri); + + workaround++; + + if (workaround > ntri) + { + // Reverse infection + mesh.viri.Clear(); + while (infectedTris.Count > 0) + { + infectedTris.Dequeue().infected = false; + } + return false; + } } } while (!hulltri.Equal(starttri)); + + return true; } /// @@ -385,7 +408,29 @@ namespace TriangleNet { // Mark as infected any unprotected triangles on the boundary. // This is one way by which concavities are created. - InfectHull(); + if (!InfectHull()) + { + // THIS IS A WORKAROUND FOR + // http://triangle.codeplex.com/workitem/9390 + + // Problem seems to be Otri being a value type. Assigning and getting + // dummytri.neighbors[0] (the triangulation algorithms use this to + // store a pointer to a boundary triangle) always produces an otri copy, + // so changes made to the orientation aren't persisted. The problem occurs + // when InsertSegment -> ConstrainedEdge -> Flip is called and InsertSegment + // has Mesh.dummytri.neighbors[0] as searchtri1. + Mesh.dummytri.neighbors[0].LprevSelf(); + + if (!InfectHull()) + { + Mesh.dummytri.neighbors[0].LprevSelf(); + + if (!InfectHull()) + { + throw new Exception("Inconsistent topology."); + } + } + } } if (!Behavior.NoHoles) diff --git a/Triangle.NET/Triangle/Mesh.cs b/Triangle.NET/Triangle/Mesh.cs index ac5daee..8bdbf4c 100644 --- a/Triangle.NET/Triangle/Mesh.cs +++ b/Triangle.NET/Triangle/Mesh.cs @@ -651,6 +651,8 @@ namespace TriangleNet ymax = 0; edges = 0; + sampler.Reset(); + Reset(); } diff --git a/Triangle.NET/Triangle/Sampler.cs b/Triangle.NET/Triangle/Sampler.cs index 3176e01..26bc93c 100644 --- a/Triangle.NET/Triangle/Sampler.cs +++ b/Triangle.NET/Triangle/Sampler.cs @@ -30,6 +30,15 @@ namespace TriangleNet // Keys of the triangle dictionary. int[] keys; + /// + /// Reset the sampler. + /// + public void Reset() + { + this.samples = 1; + this.triangleCount = 0; + } + /// /// Update sampling parameters if mesh changed. ///