Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geometry/GeometryGeneratorTests.cs =================================================================== diff -u -r5687 -r5786 --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geometry/GeometryGeneratorTests.cs (.../GeometryGeneratorTests.cs) (revision 5687) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geometry/GeometryGeneratorTests.cs (.../GeometryGeneratorTests.cs) (revision 5786) @@ -19,6 +19,8 @@ // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. +using System.Collections.Generic; +using System.Linq; using System.Security.Cryptography.X509Certificates; using Deltares.DamEngine.Data.Geometry; using NUnit.Framework; @@ -71,4 +73,323 @@ Assert.That(isPoint2ClosestToPoint3, Is.EqualTo(isPoint2Closest)); }); } + + //[Test] + + + + // [TestCase(0.0, 0.0, 2.0, 2.0, 3.0, 3.0, 0.0, 0.0)] // p1/p4--p2--p3 keep c1, split c2 to c(p2--p3) + // [TestCase(0.0, 0.0, 2.0, 2.0, 3.0, 3.0, 0.0, 0.0)] // p1/p4--p2--p3 keep c1, split c2 to c(p2--p3) + [Test, TestCaseSource(nameof(CurvesToBeTestedForParallelCurves))] + public void TestRegenerateParallelCurves(TestCaseCurvesToBeTestedForParallelCurves testCase) + { + // Given + var geometryData = new GeometryData(); + geometryData.Points.Add(testCase.InputPoint1); + geometryData.Points.Add(testCase.InputPoint2); + geometryData.Points.Add(testCase.InputPoint3); + geometryData.Points.Add(testCase.InputPoint4); + var curve1 = new GeometryCurve(testCase.InputPoint1, testCase.InputPoint2); + var curve2 = new GeometryCurve(testCase.InputPoint3, testCase.InputPoint4); + geometryData.Curves.Add(curve1); + geometryData.Curves.Add(curve2); + var generator = new GeometryGenerator(geometryData); + + // When + bool isCurveInserted = false; + generator.RegenerateParallelCurves(curve1, curve2, ref isCurveInserted); + + // Then + Assert.Multiple(() => + { + Assert.That(curve1.HeadPoint, Is.EqualTo(testCase.ExpectedPoint1)); + Assert.That(curve1.EndPoint, Is.EqualTo(testCase.ExpectedPoint2)); + Assert.That(curve2.HeadPoint, Is.EqualTo(testCase.ExpectedPoint3)); + Assert.That(curve2.EndPoint, Is.EqualTo(testCase.ExpectedPoint4)); + Assert.That(isCurveInserted, Is.EqualTo(testCase.IsCurveInserted)); + if (testCase.ExpectedPoint5 != null) + { + Assert.That(geometryData.NewlyEffectedCurves[0].HeadPoint, Is.EqualTo(testCase.ExpectedPoint5)); + } + if (testCase.ExpectedPoint6 != null) + { + Assert.That(geometryData.NewlyEffectedCurves[0].EndPoint, Is.EqualTo(testCase.ExpectedPoint6)); + } + }); + } + + /// + /// Test case class for parallel curves + /// + public class TestCaseCurvesToBeTestedForParallelCurves + { + public Point2D InputPoint1 { get; init; } + public Point2D InputPoint2 { get; init; } + public Point2D InputPoint3 { get; init; } + public Point2D InputPoint4 { get; init; } + public Point2D ExpectedPoint1 { get; init; } + public Point2D ExpectedPoint2 { get; init; } + public Point2D ExpectedPoint3 { get; init; } + public Point2D ExpectedPoint4 { get; init; } + public Point2D ExpectedPoint5 { get; init; } + public Point2D ExpectedPoint6 { get; init; } + public bool IsCurveInserted { get; init; } + public int TestNumber { get; init; } + } + private static IEnumerable CurvesToBeTestedForParallelCurves + { + get + { + var point1 = new Point2D(0.0, 0.0); + var point2 = new Point2D(1.0, 1.0); + var point3 = new Point2D(2.0, 0.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point1, + InputPoint2 = point2, + InputPoint3 = point2, + InputPoint4 = point3, + IsCurveInserted = false, + ExpectedPoint1 = point1, + ExpectedPoint2 = point2, + ExpectedPoint3 = point2, + ExpectedPoint4 = point3, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 1: ordered, not parallel should do nothing"); + + var point2_1 = new Point2D(0.0, 0.0); + var point2_2 = new Point2D(4.0, 4.0); + var point2_3 = new Point2D(2.0, 2.0); + var point2_4 = new Point2D(3.0, 3.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point2_1, + InputPoint2 = point2_2, + InputPoint3 = point2_3, + InputPoint4 = point2_4, + IsCurveInserted = true, + ExpectedPoint1 = point2_1, + ExpectedPoint2 = point2_3, + ExpectedPoint3 = point2_3, + ExpectedPoint4 = point2_4, + ExpectedPoint5 = point2_4, + ExpectedPoint6 = point2_2 + }).SetName("Test 2: p1--p3--p4--p2 -> split c1 to c(p1--p3) keep c2, insert c(p4--p2)"); + + var point3_1 = new Point2D(0.0, 0.0); + var point3_2 = new Point2D(4.0, 4.0); + var point3_3 = new Point2D(3.0, 3.0); + var point3_4 = new Point2D(2.0, 2.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point3_1, + InputPoint2 = point3_2, + InputPoint3 = point3_3, + InputPoint4 = point3_4, + IsCurveInserted = true, + ExpectedPoint1 = point3_1, + ExpectedPoint2 = point3_4, + ExpectedPoint3 = point3_3, + ExpectedPoint4 = point3_4, + ExpectedPoint5 = point3_3, + ExpectedPoint6 = point3_2 + }).SetName("Test 3: p1--p4--p3--p2 split c1 to c(p1--p4) keep c2, insert c(p3--p2)"); + + var point4_1 = new Point2D(0.0, 0.0); + var point4_2 = new Point2D(3.0, 3.0); + var point4_3 = new Point2D(2.0, 2.0); + var point4_4 = new Point2D(4.0, 4.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point4_1, + InputPoint2 = point4_2, + InputPoint3 = point4_3, + InputPoint4 = point4_4, + IsCurveInserted = true, + ExpectedPoint1 = point4_1, + ExpectedPoint2 = point4_3, + ExpectedPoint3 = point4_2, + ExpectedPoint4 = point4_4, + ExpectedPoint5 = point4_3, + ExpectedPoint6 = point4_2 + }).SetName("Test 4: p1--p3--p2--p4 split c1 to c(p1--p3) split c2 to c(p2--p4), insert c(p3--p2)"); + + var point5_1 = new Point2D(0.0, 0.0); + var point5_2 = new Point2D(3.0, 3.0); + var point5_3 = new Point2D(4.0, 4.0); + var point5_4 = new Point2D(2.0, 2.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point5_1, + InputPoint2 = point5_2, + InputPoint3 = point5_3, + InputPoint4 = point5_4, + IsCurveInserted = true, + ExpectedPoint1 = point5_1, + ExpectedPoint2 = point5_4, + ExpectedPoint3 = point5_3, + ExpectedPoint4 = point5_2, + ExpectedPoint5 = point5_4, + ExpectedPoint6 = point5_2 + }).SetName("Test 5: p1--p4--p2--p3 split c1 to c(p1--p4) split c2 to c(p3--p2), insert c(p4--p2)"); + + var point6_1 = new Point2D(0.0, 0.0); + var point6_2 = new Point2D(2.0, 2.0); + var point6_3 = new Point2D(4.0, 4.0); + var point6_4 = new Point2D(3.0, 3.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point6_1, + InputPoint2 = point6_2, + InputPoint3 = point6_3, + InputPoint4 = point6_4, + IsCurveInserted = false, + ExpectedPoint1 = point6_1, + ExpectedPoint2 = point6_2, + ExpectedPoint3 = point6_3, + ExpectedPoint4 = point6_4, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 6: p1--p2 <--> p4--p3 in each other's extension, no overlap do nothing"); + + var point7_1 = new Point2D(0.0, 0.0); + var point7_2 = new Point2D(2.0, 2.0); + var point7_3 = new Point2D(3.0, 3.0); + var point7_4 = new Point2D(4.0, 4.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point7_1, + InputPoint2 = point7_2, + InputPoint3 = point7_3, + InputPoint4 = point7_4, + IsCurveInserted = false, + ExpectedPoint1 = point7_1, + ExpectedPoint2 = point7_2, + ExpectedPoint3 = point7_3, + ExpectedPoint4 = point7_4, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 7: p1--p2 <--> p3--p4 in each other's extension, no overlap do nothing"); + + var point8_1 = new Point2D(0.0, 0.0); + var point8_2 = new Point2D(2.0, 2.0); + var point8_3 = point8_1; + var point8_4 = new Point2D(4.0, 4.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point8_1, + InputPoint2 = point8_2, + InputPoint3 = point8_3, + InputPoint4 = point8_4, + IsCurveInserted = false, + ExpectedPoint1 = point8_1, + ExpectedPoint2 = point8_2, + ExpectedPoint3 = point8_2, + ExpectedPoint4 = point8_4, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 8: p1/p3--p2--p4 keep c1, split c2 to c(p2--p4)"); + + var point9_1 = new Point2D(0.0, 0.0); + var point9_2 = new Point2D(4.0, 4.0); + var point9_3 = point8_1; + var point9_4 = new Point2D(2.0, 2.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point9_1, + InputPoint2 = point9_2, + InputPoint3 = point9_3, + InputPoint4 = point9_4, + IsCurveInserted = false, + ExpectedPoint1 = point9_1, + ExpectedPoint2 = point9_4, + ExpectedPoint3 = point9_4, + ExpectedPoint4 = point9_2, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 9: p1/p3--p4--p2 split c1 to c(p1--p4), split c2 to c(p4--p2)"); + + var point10_1 = new Point2D(0.0, 0.0); + var point10_2 = new Point2D(2.0, 2.0); + var point10_3 = new Point2D(4.0, 4.0); + var point10_4 = point10_1; + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point10_1, + InputPoint2 = point10_2, + InputPoint3 = point10_3, + InputPoint4 = point10_4, + IsCurveInserted = false, + ExpectedPoint1 = point10_1, + ExpectedPoint2 = point10_2, + ExpectedPoint3 = point10_3, + ExpectedPoint4 = point10_2, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 10: p1/p4--p2--p3 keep c1(p1,p2) , split c2 to c(p3--p2)"); + + var point11_1 = new Point2D(0.0, 0.0); + var point11_2 = new Point2D(4.0, 4.0); + var point11_3 = new Point2D(2.0, 2.0); + var point11_4 = point10_1; + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point11_1, + InputPoint2 = point11_2, + InputPoint3 = point11_3, + InputPoint4 = point11_4, + IsCurveInserted = false, + ExpectedPoint1 = point11_3, + ExpectedPoint2 = point11_2, + ExpectedPoint3 = point11_3, + ExpectedPoint4 = point11_4, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 11: p1/p4--p3--p2 split c1 to c1(p3,p2), keep c2 (p3--p4)"); + + var point12_1 = new Point2D(0.0, 0.0); + var point12_2 = new Point2D(2.0, 2.0); + var point12_3 = point10_2; + var point12_4 = new Point2D(4.0, 4.0); + yield return new TestCaseData( + new TestCaseCurvesToBeTestedForParallelCurves + { + TestNumber = 1, + InputPoint1 = point12_1, + InputPoint2 = point12_2, + InputPoint3 = point12_3, + InputPoint4 = point12_4, + IsCurveInserted = false, + ExpectedPoint1 = point12_1, + ExpectedPoint2 = point12_2, + ExpectedPoint3 = point12_3, + ExpectedPoint4 = point12_4, + ExpectedPoint5 = null, + ExpectedPoint6 = null + }).SetName("Test 12: p1--p2/p3--p4 keep c1(p1,p2) , keep c2(p3--p4)"); + } + } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs =================================================================== diff -u -r5742 -r5786 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 5742) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 5786) @@ -31,14 +31,13 @@ // The main geometry regeneration manager public class GeometryGenerator { - private readonly Dictionary geometryCurveForwardsIsUsed = new Dictionary(); - private readonly Dictionary geometryCurveReversedIsUsed = new Dictionary(); + private readonly Dictionary geometryCurveForwardsIsUsed = new (); + private readonly Dictionary geometryCurveReversedIsUsed = new (); private readonly GeometryData geometryData; - private readonly List intersectedCurveList = new List(); - - private readonly Dictionary> geometryLoopDirections = new Dictionary>(); - private readonly List newlyDetectedSurfaceList = new List(); + private readonly Dictionary> geometryLoopDirections = new (); + + private readonly List newlyDetectedSurfaceList = new (); /// /// Regenerates the geometry. @@ -62,7 +61,6 @@ while (true) { // break up all curves at intersections - intersectedCurveList.Clear(); RegenerateAllCurvesIntersection(); newlyDetectedSurfaceList.Clear(); @@ -80,9 +78,6 @@ // detect surfaces... the plaxis algorithm int result = DetectSurfaces(firstRegeneration); - // clear the effected & intersected curve list - intersectedCurveList.Clear(); - if (result < 0) { if (!firstRegeneration) @@ -957,7 +952,6 @@ /// private void RegenerateAllCurvesIntersection() { - intersectedCurveList.Clear(); MergePoints(); bool isCurveInserted = false; bool hasCurveBeenSplit = true; @@ -1115,6 +1109,11 @@ bool isPoint2SameAsPoint3 = localPoint2.LocationEquals(localPoint3); bool isPoint2SameAsPoint4 = localPoint2.LocationEquals(localPoint4); + if ((isPoint2SameAsPoint3 && isPoint1SameAsPoint4) || (isPoint2SameAsPoint4 && isPoint1SameAsPoint3)) + { + return true; + } + double slope1 = DetermineSlope(line1); double slope2 = DetermineSlope(line2); @@ -1167,8 +1166,7 @@ newLine = SplitCurve(line1, line2.HeadPoint); line2.HeadPoint = isPoint2OnLine2 ? newLine.EndPoint : line1.HeadPoint; - AddToIntersectedCurveList(line2); - + isCurveInserted = true; return true; } @@ -1178,8 +1176,7 @@ { newLine = SplitCurve(line1, line2.EndPoint); line2.EndPoint = isPoint2OnLine2 ? newLine.EndPoint : line1.HeadPoint; - AddToIntersectedCurveList(line2); - + isCurveInserted = true; return true; } @@ -1201,8 +1198,7 @@ newLine = SplitCurve(line1, line2.EndPoint); newLine.HeadPoint = line2.HeadPoint; } - AddToIntersectedCurveList(line2); - + isCurveInserted = true; return true; } @@ -1224,23 +1220,26 @@ newLine = SplitCurve(line2, line1.EndPoint); newLine.HeadPoint = line1.HeadPoint; } - AddToIntersectedCurveList(line1); - + isCurveInserted = true; return true; } // vertices coincidence cases - Line2 on Line1 - if ((isPoint4OnLine1 && isPoint3OnLine1) && - (!((isPoint2SameAsPoint3 && isPoint1SameAsPoint4) || (isPoint2SameAsPoint4 && isPoint1SameAsPoint3)))) + if (isPoint4OnLine1 && isPoint3OnLine1) { if (isPoint1SameAsPoint3) { - line1.HeadPoint = line2.EndPoint; + // p1/p3----p4----p2 --> c1(p1, p4) & c(p4, p2) + var p2 = line1.EndPoint; + line1.EndPoint = line2.EndPoint; + line2.HeadPoint = line2.EndPoint; + line2.EndPoint = p2; } else if (isPoint2SameAsPoint3) { - line1.EndPoint = line2.EndPoint; + // p2/p3----p4----p1 + line2.EndPoint = line2.EndPoint; } else if (isPoint2SameAsPoint4) { @@ -1250,15 +1249,11 @@ { line1.HeadPoint = line2.HeadPoint; } - AddToIntersectedCurveList(line1); - AddToIntersectedCurveList(line2); - return true; } // Line1 on Line2 - if ((isPoint1OnLine2 && isPoint2OnLine2) && - (!((isPoint2SameAsPoint3 && isPoint1SameAsPoint4) || (isPoint2SameAsPoint4 && isPoint1SameAsPoint3)))) + if (isPoint1OnLine2 && isPoint2OnLine2) { if (isPoint1SameAsPoint3) { @@ -1276,19 +1271,10 @@ { line2.HeadPoint = line1.HeadPoint; } - AddToIntersectedCurveList(line1); - AddToIntersectedCurveList(line2); return true; } } - // Line1 and Line2 are same - if ((isPoint1SameAsPoint3 && isPoint2SameAsPoint4) || (isPoint1SameAsPoint4 && isPoint2SameAsPoint3)) - { - AddToIntersectedCurveList(line1); - AddToIntersectedCurveList(line2); - return true; - } return false; } @@ -1299,8 +1285,6 @@ GeometryCurve newCurve = geometryData.CreateCurve(pointOnCurve, srcCurve.EndPoint); srcCurve.EndPoint = newCurve.HeadPoint; newCurve.AssignSurfacesFromCurve(srcCurve); - AddToIntersectedCurveList(srcCurve); - AddToIntersectedCurveList(newCurve); if (!geometryData.DoesCurveExist(newCurve)) { geometryData.Curves.Add(newCurve); @@ -1363,10 +1347,4 @@ geometryData.DeleteCurve(aCurve, true); } - private void AddToIntersectedCurveList(GeometryCurve aCurve) - { - if (!intersectedCurveList.Contains(aCurve)) - intersectedCurveList.Add(aCurve); - } - } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs =================================================================== diff -u -r5702 -r5786 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 5702) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 5786) @@ -293,8 +293,11 @@ } var curve1 = new GeometryCurve(); - geometryGenerator.SetIsUsed(curve1, CurveDirection.Forward, false); - geometryGenerator.SetIsUsed(curve1, CurveDirection.Reverse, false); + if (geometryGenerator != null) + { + geometryGenerator.SetIsUsed(curve1, CurveDirection.Forward, false); + geometryGenerator.SetIsUsed(curve1, CurveDirection.Reverse, false); + } curve1.HeadPoint = point1; curve1.EndPoint = point2; AddDataItemToProperList(curve1);