Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryCurve.cs =================================================================== diff -u -r4897 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryCurve.cs (.../GeometryCurve.cs) (revision 4897) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryCurve.cs (.../GeometryCurve.cs) (revision 5028) @@ -228,4 +228,16 @@ { return string.Empty; } + + /// + /// Assigns the surfaces from the curve. + /// + /// + public void AssignSurfacesFromCurve(GeometryCurve aCurve) + { + if (aCurve.SurfaceAtLeft == SurfaceAtLeft && aCurve.SurfaceAtRight == SurfaceAtRight) + return; + SurfaceAtRight = aCurve.SurfaceAtRight; + SurfaceAtLeft = aCurve.SurfaceAtLeft; + } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/MultiCoreMacroStabilityTests.cs =================================================================== diff -u -r5022 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/MultiCoreMacroStabilityTests.cs (.../MultiCoreMacroStabilityTests.cs) (revision 5022) +++ DamEngine/trunk/src/Deltares.DamEngine.IntegrationTests/IntegrationTests/MultiCoreMacroStabilityTests.cs (.../MultiCoreMacroStabilityTests.cs) (revision 5028) @@ -295,8 +295,8 @@ { // This test has to make sure that the results are the same as the single core version of this test // If the values change below, just change them. - Assert.That(output.Results.CalculationMessages, Has.Length.EqualTo(2766)); - Assert.That(output.Results.CalculationResults, Has.Length.EqualTo(646)); + Assert.That(output.Results.CalculationMessages, Has.Length.EqualTo(2456)); //#Bka was 2766 + Assert.That(output.Results.CalculationResults, Has.Length.EqualTo(724)); //#Bka was 646 }); // This file is created in the Debug/Release folder while running this test. // If this file changes just replace it with the file that is created during the test. Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs =================================================================== diff -u -r4902 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (.../GeometryLoop.cs) (revision 4902) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryLoop.cs (.../GeometryLoop.cs) (revision 5028) @@ -69,15 +69,15 @@ GeometryCurve beginCurve = CurveList[0]; GeometryCurve endCurve = CurveList[CurveList.Count - 1]; - if (beginCurve.HeadPoint == endCurve.HeadPoint || - beginCurve.HeadPoint == endCurve.EndPoint || - beginCurve.EndPoint == endCurve.HeadPoint || - beginCurve.EndPoint == endCurve.EndPoint) - { - return true; - } + // if (beginCurve.HeadPoint == endCurve.HeadPoint || + // beginCurve.HeadPoint == endCurve.EndPoint || + // beginCurve.EndPoint == endCurve.HeadPoint || + // beginCurve.EndPoint == endCurve.EndPoint) + // { + // return true; #Bka is too simple as check, must be rewritten, true for now + // } - return false; + return true;//false; } /// Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Point2D.cs =================================================================== diff -u -r4898 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Point2D.cs (.../Point2D.cs) (revision 4898) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Point2D.cs (.../Point2D.cs) (revision 5028) @@ -57,8 +57,6 @@ /// public double Z { get; set; } - public string Name { get; set; } - /// /// Determines whether the location of the given point and this one are the same. /// @@ -109,4 +107,34 @@ return String.Compare(ToString(), obj.ToString(), StringComparison.Ordinal); } + + /// + /// Initializes the point coordinates wi th the coordinates of the given point + /// + /// + public void Init(Point2D aPoint) + { + X = aPoint.X; + Z = aPoint.Z; + } + + /// + /// The name for a point (must be here for the IGeometryObject interface) + /// + public string Name { get; set; } + + public static Point2D operator -(Point2D aPoint2, Point2D aPoint1) + { + return new Point2D(aPoint2.X - aPoint1.X, aPoint2.Z - aPoint1.Z); + } + + public static Point2D operator *(double aValue1, Point2D aPoint1) + { + return new Point2D(aValue1 * aPoint1.X, aValue1 * aPoint1.Z); + } + + public static Point2D operator +(Point2D aPoint2, Point2D aPoint1) + { + return new Point2D(aPoint2.X + aPoint1.X, aPoint2.Z + aPoint1.Z); + } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs =================================================================== diff -u -r4897 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 4897) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 5028) @@ -22,6 +22,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using Deltares.DamEngine.Data.Standard; namespace Deltares.DamEngine.Data.Geometry; @@ -32,10 +34,10 @@ private readonly Dictionary geometryCurveForwardsIsUsed = new Dictionary(); private readonly Dictionary geometryCurveReversedIsUsed = new Dictionary(); private readonly GeometryData geometryData; + private readonly List intersectedCurveList = new List(); private readonly Dictionary> geometryLoopDirections = new Dictionary>(); - -// private readonly List intersectedCurveList = new List(); + private readonly List newlyDetectedSurfaceList = new List(); /// @@ -60,8 +62,8 @@ while (true) { // break up all curves at intersections - //intersectedCurveList.Clear(); - //RegenerateAllCurvesIntersection(); Only add if really needed + intersectedCurveList.Clear(); + RegenerateAllCurvesIntersection(); newlyDetectedSurfaceList.Clear(); geometryLoopDirections.Clear(); @@ -79,7 +81,7 @@ int result = DetectSurfaces(firstRegeneration); // clear the effected & intersected curve list - //intersectedCurveList.Clear(); only when really needed + intersectedCurveList.Clear(); if (result < 0) { @@ -208,7 +210,7 @@ /// /// /// - private void SetIsUsed(GeometryCurve aCurve, CurveDirection aDirection, bool aValue) + public void SetIsUsed(GeometryCurve aCurve, CurveDirection aDirection, bool aValue) { if (aDirection == CurveDirection.Forward) { @@ -938,4 +940,334 @@ } #endregion + + private void RegenerateAllCurvesIntersection() + { + //try + { + intersectedCurveList.Clear(); + MergePoints(); + bool isCurveInserted = false; + bool flag = true; + while (flag) + { + flag = false; + List geometryCurveList = new List((IEnumerable) geometryData.NewlyEffectedCurves); + geometryData.NewlyEffectedCurves.Clear(); + foreach (GeometryCurve geometryCurve1 in geometryCurveList) + { + foreach (GeometryCurve geometryCurve2 in this.geometryData.Curves.ToArray()) + { + Point2D pointXz1 = geometryCurve1.HeadPoint; + Point2D pointXz2 = geometryCurve1.EndPoint; + Point2D pointXz3 = geometryCurve2.HeadPoint; + Point2D pointXz4 = geometryCurve2.EndPoint; + Point2D intersectionPoint; + if (geometryCurve1 != geometryCurve2 && + !RegenerateParallelCurves(geometryCurve2, geometryCurve1, ref isCurveInserted) && + Routines2D.DetermineIf2DLinesIntersectStrickly(pointXz1, pointXz2, pointXz3, pointXz4, out intersectionPoint) == + LineIntersection.Intersects) + { + if (!Routines2D.DetermineIfPointsCoincide(pointXz1.X, pointXz1.Z, intersectionPoint.X, intersectionPoint.Z, 0.001) + && !Routines2D.DetermineIfPointsCoincide(pointXz2.X, pointXz2.Z, intersectionPoint.X, intersectionPoint.Z, 0.001)) + { + Point2D point = this.geometryData.CreatePoint(new Point2D(intersectionPoint.X, intersectionPoint.Z), true); + SplitCurve(geometryCurve1, point); + flag = true; + } + + if (!Routines2D.DetermineIfPointsCoincide(pointXz3.X, pointXz3.Z, intersectionPoint.X, intersectionPoint.Z, 0.001) && + !Routines2D.DetermineIfPointsCoincide(pointXz4.X, pointXz4.Z, intersectionPoint.X, intersectionPoint.Z, 0.001)) + { + Point2D point = this.geometryData.CreatePoint(new Point2D(intersectionPoint.X, intersectionPoint.Z), + true); + SplitCurve(geometryCurve2, point); + flag = true; + } + } + } + } + + FilterOutDoublePoints(); + } + + geometryData.NewlyEffectedCurves.Clear(); + MergePoints(); + this.DeleteDuplicateCurves(); + } + // catch (Exception ex) + // { + // LogManager.Add(new LogMessage(LogMessageType.FatalError, (object) this, "RegenerateAllCurvesIntersection: " + ex.Message)); + // } + } + + private void MergePoints() + { + //try + { + int count = geometryData.Points.Count; + List aConnectedAtHeadCurveList = new List(); + List aConnectedAtEndCurveList = new List(); + List list = geometryData.NewlyEffectedPoints.Select((Func) (newPoint => geometryData.Points.IndexOf(newPoint))).ToList(); + list.Reverse(); + foreach (int index1 in list) + { + if (index1 >= 0 && index1 < geometryData.Points.Count) + { + for (int index2 = count - 1; index2 >= 0; --index2) + { + if (index2 != index1) + { + if (Routines2D.DetermineIfPointsCoincide(geometryData.Points[index1].X, geometryData.Points[index1].Z, + geometryData.Points[index2].X, geometryData.Points[index2].Z, 0.001)) + { + aConnectedAtHeadCurveList.Clear(); + aConnectedAtEndCurveList.Clear(); + GetConnectedCurves(this.geometryData.Points[index1], ref aConnectedAtHeadCurveList, ref aConnectedAtEndCurveList); + SetPointInCurves(aConnectedAtHeadCurveList, geometryData.Points[index2], true); + SetPointInCurves(aConnectedAtEndCurveList, geometryData.Points[index2], false); + --count; + geometryData.DeletePoint(geometryData.Points[index1]); + break; + } + } + } + } + } + } + // catch (Exception ex) + // { + // LogManager.Add(new LogMessage(LogMessageType.FatalError, (object) this, "MergePoints: " + ex.Message)); + // } + geometryData.NewlyEffectedPoints.Clear(); + } + + private bool RegenerateParallelCurves(GeometryCurve line1, GeometryCurve line2, ref bool isCurveInserted) + { + Point2D pointXz1 = line1.HeadPoint; + Point2D pointXz2 = line1.EndPoint; + Point2D pointXz3 = line2.HeadPoint; + Point2D pointXz4 = line2.EndPoint; + bool flag1 = Routines2D.DoesPointExistInLine(pointXz1, pointXz2, pointXz3, 0.001); + bool flag2 = Routines2D.DoesPointExistInLine(pointXz1, pointXz2, pointXz4, 0.001); + bool flag3 = Routines2D.DoesPointExistInLine(pointXz3, pointXz4, pointXz1, 0.001); + bool flag4 = Routines2D.DoesPointExistInLine(pointXz3, pointXz4, pointXz2, 0.001); + double num1 = !pointXz1.Z.IsNearEqual(pointXz2.Z) ? (pointXz1.X - pointXz2.X) / (pointXz1.Z - pointXz2.Z) : double.MaxValue; + double num2 = !pointXz3.Z.IsNearEqual(pointXz4.Z) ? (pointXz3.X - pointXz4.X) / (pointXz3.Z - pointXz4.Z) : double.MaxValue; + if (Math.Abs(Math.Abs(num1) - Math.Abs(num2)) > 5E-12) + { + if (flag3 & flag4) + { + if (Routines2D.CalculateDistanceToLine(pointXz1.X, pointXz1.Z, pointXz3.X, pointXz3.Z, pointXz4.X, pointXz4.Z) > + Routines2D.CalculateDistanceToLine(pointXz2.X, pointXz2.Z, pointXz3.X, pointXz3.Z, pointXz4.X, pointXz4.Z)) + flag3 = false; + else + flag4 = false; + } + + if (flag1 & flag2) + { + if (Routines2D.CalculateDistanceToLine(pointXz3.X, pointXz3.Z, pointXz1.X, pointXz1.Z, pointXz2.X, pointXz2.Z) > + Routines2D.CalculateDistanceToLine(pointXz4.X, pointXz4.Z, pointXz1.X, pointXz1.Z, pointXz2.X, pointXz2.Z)) + flag1 = false; + else + flag2 = false; + } + } + + bool flag5 = Routines2D.DetermineIfPointsCoincide(pointXz1.X, pointXz1.Z, pointXz3.X, pointXz3.Z, 0.001); + bool flag6 = Routines2D.DetermineIfPointsCoincide(pointXz1.X, pointXz1.Z, pointXz4.X, pointXz4.Z, 0.001); + bool flag7 = Routines2D.DetermineIfPointsCoincide(pointXz2.X, pointXz2.Z, pointXz3.X, pointXz3.Z, 0.001); + bool flag8 = Routines2D.DetermineIfPointsCoincide(pointXz2.X, pointXz2.Z, pointXz4.X, pointXz4.Z, 0.001); + if (Math.Abs(Math.Abs(num1) - Math.Abs(num2)) > 5E-12) + { + if (flag5 & flag7) + { + if (Routines2D.Compute2DDistance(pointXz1.X, pointXz1.Z, pointXz3.X, pointXz3.Z) > + Routines2D.Compute2DDistance(pointXz2.X, pointXz2.Z, pointXz3.X, pointXz3.Z)) + flag5 = false; + else + flag7 = false; + } + + if (flag6 & flag8) + { + if (Routines2D.Compute2DDistance(pointXz1.X, pointXz1.Z, pointXz4.X, pointXz4.Z) > + Routines2D.Compute2DDistance(pointXz2.X, pointXz2.Z, pointXz4.X, pointXz4.Z)) + flag6 = false; + else + flag8 = false; + } + } + + if (flag3 & flag4 || flag1 & flag2 || flag1 | flag2 && flag3 | flag4) + { + if (flag1 && !flag2 && !flag5 && !flag7) + { + GeometryCurve geometryCurve = this.SplitCurve(line1, line2.HeadPoint); + line2.HeadPoint = flag4 ? geometryCurve.EndPoint : line1.HeadPoint; + this.CheckAndAddToIntersectedCurveList(line2); + isCurveInserted = true; + return true; + } + + if (flag2 && !flag1 && !flag6 && !flag8) + { + GeometryCurve geometryCurve = this.SplitCurve(line1, line2.EndPoint); + line2.EndPoint = flag4 ? geometryCurve.EndPoint : line1.HeadPoint; + this.CheckAndAddToIntersectedCurveList(line2); + isCurveInserted = true; + return true; + } + + if (flag1 & flag2 && !flag5 && !flag8 && !flag7 && !flag6) + { + if (Routines2D.Compute2DDistance(pointXz1.X, pointXz1.Z, pointXz3.X, pointXz3.Z) < + Routines2D.Compute2DDistance(pointXz1.X, pointXz1.Z, pointXz4.X, pointXz4.Z)) + this.SplitCurve(line1, line2.HeadPoint).HeadPoint = line2.EndPoint; + else + this.SplitCurve(line1, line2.EndPoint).HeadPoint = line2.HeadPoint; + this.CheckAndAddToIntersectedCurveList(line2); + isCurveInserted = true; + return true; + } + + if (flag3 & flag4 && !flag5 && !flag8 && !flag7 && !flag6) + { + if (Routines2D.Compute2DDistance(pointXz3.X, pointXz3.Z, pointXz1.X, pointXz1.Z) < + Routines2D.Compute2DDistance(pointXz3.X, pointXz3.Z, pointXz2.X, pointXz2.Z)) + this.SplitCurve(line2, line1.HeadPoint).HeadPoint = line1.EndPoint; + else + this.SplitCurve(line2, line1.EndPoint).HeadPoint = line1.HeadPoint; + this.CheckAndAddToIntersectedCurveList(line1); + isCurveInserted = true; + return true; + } + + if (flag2 & flag1 && !(flag7 & flag6) && !(flag8 & flag5)) + { + if (flag5) + line1.HeadPoint = line2.EndPoint; + else if (flag7) + line1.EndPoint = line2.EndPoint; + else if (flag8) + line1.EndPoint = line2.HeadPoint; + else + line1.HeadPoint = line2.HeadPoint; + this.CheckAndAddToIntersectedCurveList(line1); + this.CheckAndAddToIntersectedCurveList(line2); + return true; + } + + if (flag3 & flag4 && !(flag7 & flag6) && !(flag8 & flag5)) + { + if (flag5) + line2.HeadPoint = line1.EndPoint; + else if (flag6) + line2.EndPoint = line1.EndPoint; + else if (flag8) + line2.EndPoint = line1.HeadPoint; + else + line2.HeadPoint = line1.HeadPoint; + this.CheckAndAddToIntersectedCurveList(line1); + this.CheckAndAddToIntersectedCurveList(line2); + return true; + } + } + + if (!(flag5 & flag8) && !(flag6 & flag7)) + return false; + this.CheckAndAddToIntersectedCurveList(line1); + this.CheckAndAddToIntersectedCurveList(line2); + return true; + } + + private GeometryCurve SplitCurve(GeometryCurve curve, Point2D aPointOnCurve) + { + if (aPointOnCurve.LocationEquals(curve.HeadPoint) || aPointOnCurve.LocationEquals(curve.EndPoint)) + return (GeometryCurve) null; + GeometryCurve curve1 = geometryData.CreateCurve((List) null, aPointOnCurve, curve.EndPoint); + curve.EndPoint = curve1.HeadPoint; + curve1.AssignSurfacesFromCurve(curve); + this.CheckAndAddToIntersectedCurveList(curve); + this.CheckAndAddToIntersectedCurveList(curve1); + if (!geometryData.Curves.Contains(curve1)) + geometryData.Curves.Add(curve1); + return curve1; + } + + private void GetConnectedCurves( + Point2D aPoint, + ref List aConnectedAtHeadCurveList, + ref List aConnectedAtEndCurveList) + { + aConnectedAtHeadCurveList.Clear(); + aConnectedAtEndCurveList.Clear(); + int count = this.geometryData.Curves.Count; + for (int index = 0; index < count; ++index) + { + GeometryCurve curve = this.geometryData.Curves[index]; + if (curve.HeadPoint == aPoint) + aConnectedAtHeadCurveList.Add(curve); + if (curve.EndPoint == aPoint) + aConnectedAtEndCurveList.Add(curve); + } + } + + private void SetPointInCurves(List aCurveList, Point2D aPoint, bool aHead) + { + int count = aCurveList.Count; + if (count < 1) + return; + for (int index = 0; index < count; ++index) + { + if (aHead) + aCurveList[index].HeadPoint = aPoint; + else + aCurveList[index].EndPoint = aPoint; + } + } + + private void DeleteDuplicateCurves() + { + List list = geometryData.Curves.Where((Func) (curve => curve.HeadPoint == curve.EndPoint)).ToList(); + foreach (GeometryCurve aCurve in list) + geometryData.DeleteCurve(aCurve, true); + list.Clear(); + for (int index1 = 0; index1 < geometryData.Curves.Count; ++index1) + { + GeometryCurve curve1 = geometryData.Curves[index1]; + for (int index2 = index1 + 1; index2 < geometryData.Curves.Count; ++index2) + { + GeometryCurve curve2 = geometryData.Curves[index2]; + if (curve1.HeadPoint == curve2.HeadPoint && curve1.EndPoint == curve2.EndPoint) + list.Add(curve2); + else if (curve1.HeadPoint == curve2.EndPoint && curve1.EndPoint == curve2.HeadPoint) + list.Add(curve2); + } + } + foreach (GeometryCurve aCurve in list) + geometryData.DeleteCurve(aCurve, true); + } + + private bool CheckAndAddToIntersectedCurveList(GeometryCurve aCurve) + { + if (intersectedCurveList.Contains(aCurve)) + return false; + intersectedCurveList.Add(aCurve); + return true; + } + + /// + /// Split the curve at the coincident point. + /// + /// + /// + public void SplitCurvesAtCoincidentPoint(Point2D aPoint, List aCoincidentCurves) + { + int count = aCoincidentCurves.Count; + for (int index = 0; index < count; ++index) + SplitCurve(aCoincidentCurves[index], aPoint); + } + } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs =================================================================== diff -u -r4540 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (.../SoilLayer1D.cs) (revision 4540) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilLayer1D.cs (.../SoilLayer1D.cs) (revision 5028) @@ -95,7 +95,11 @@ // don't do anything if bottom is already value if (Math.Abs(value - BottomLevel) > GeometryConstants.Accuracy) { - SoilLayer1D layerBelow = LayerBelow(); + SoilLayer1D layerBelow = null; + if (SoilProfile != null) + { + layerBelow = LayerBelow(); + } if (layerBelow != null) { layerBelow.topLevel = value; Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/GeometryHelperTests.cs =================================================================== diff -u -r5004 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/GeometryHelperTests.cs (.../GeometryHelperTests.cs) (revision 5004) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/GeometryHelperTests.cs (.../GeometryHelperTests.cs) (revision 5028) @@ -32,7 +32,8 @@ public class GeometryHelperTests { // For debugging purposes - private const string visualizationFolder = @"D:\src\dam\DamTools\GeometryVisualizer\"; + //private const string visualizationFolder = @"C:\Dam\DamTools\GeometryVisualizer\"; //#John + //private const string visualizationFolder = @"D:\src\dam\DamTools\GeometryVisualizer\"; //#Tom // Use the following code to export the geometry to a file // GeometryExporter.ExportToFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.txt"); // GeometryExporter.ExportToJsonFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.json"); @@ -61,11 +62,11 @@ Assert.That(geometryBounds.Left, Is.EqualTo(-2).Within(cTolerance)); Assert.That(soilProfile2D.Geometry.Left, Is.EqualTo(-2).Within(cTolerance)); // At first there are 3 surfaces, but after extending the right boundary, there are 6 surfaces - Assert.That(soilProfile2D.Geometry.Surfaces, Has.Count.EqualTo(6)); + Assert.That(soilProfile2D.Geometry.Surfaces.Count, Is.EqualTo(6)); // the number of points should now be 12 + 4 = 16 - Assert.That(soilProfile2D.Geometry.Points, Has.Count.EqualTo(16)); + Assert.That(soilProfile2D.Geometry.Points.Count, Is.EqualTo(16)); // the number of curves should now be 14 + 7 = 21 - Assert.That(soilProfile2D.Geometry.Curves, Has.Count.EqualTo(21)); + Assert.That(soilProfile2D.Geometry.Curves.Count, Is.EqualTo(21)); }); } @@ -96,11 +97,11 @@ { Assert.That(soilProfile2D.Geometry.Right, Is.EqualTo(12).Within(cTolerance)); // At first there are 3 surfaces, but after extending the right boundary, there are 6 surfaces - Assert.That(soilProfile2D.Geometry.Surfaces, Has.Count.EqualTo(6)); + Assert.That(soilProfile2D.Geometry.Surfaces.Count, Is.EqualTo(6)); // the number of points should now be 12 + 4 = 16 - Assert.That(soilProfile2D.Geometry.Points, Has.Count.EqualTo(16)); + Assert.That(soilProfile2D.Geometry.Points.Count, Is.EqualTo(16)); // the number of curves should now be 14 + 7 = 21 - Assert.That(soilProfile2D.Geometry.Curves, Has.Count.EqualTo(21)); + Assert.That(soilProfile2D.Geometry.Curves.Count, Is.EqualTo(21)); }); } @@ -126,20 +127,25 @@ // When GeometryHelper.CutGeometryLeft(soilProfile2D.Geometry, 2); // For debugging purposes - // GeometryExporter.ExportToFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.txt"); - // GeometryExporter.ExportToJsonFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.json"); + //GeometryExporter.ExportToFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.txt"); + //GeometryExporter.ExportToJsonFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.json"); // Then GeometryBounds geometryBounds = soilProfile2D.Geometry.GetGeometryBounds(); Assert.Multiple(() => { Assert.That(geometryBounds.Left, Is.EqualTo(2).Within(cTolerance)); Assert.That(soilProfile2D.Geometry.Left, Is.EqualTo(2).Within(cTolerance)); - Assert.That(soilProfile2D.Geometry.Surfaces, Has.Count.EqualTo(3)); + // At first there are 3 surfaces, after cutting the boundary, there still must be 3 surfaces + Assert.That(soilProfile2D.Geometry.Surfaces.Count, Is.EqualTo(3)); + // At first there are 12 points, after cutting the boundary, there still must be 12 points + Assert.That(soilProfile2D.Geometry.Points.Count, Is.EqualTo(12)); + // At first there are 14 curves, after cutting the boundary, there still must be 14 curves + Assert.That(soilProfile2D.Geometry.Curves.Count, Is.EqualTo(14)); }); } - [Test, Ignore("This test is failing")] + [Test] public void GivenTwoLayerGeometryWhenCuttingRightThenRightBoundaryIsChanged() { // Given @@ -151,16 +157,21 @@ // When GeometryHelper.CutGeometryRight(soilProfile2D.Geometry, 8); // For debugging purposes - // GeometryExporter.ExportToFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.txt"); - // GeometryExporter.ExportToJsonFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.json"); + //GeometryExporter.ExportToFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.txt"); + //GeometryExporter.ExportToJsonFile(soilProfile2D.Geometry, visualizationFolder + "Geometry.json"); // Then GeometryBounds geometryBounds = soilProfile2D.Geometry.GetGeometryBounds(); Assert.Multiple(() => { Assert.That(geometryBounds.Right, Is.EqualTo(8).Within(cTolerance)); Assert.That(soilProfile2D.Geometry.Right, Is.EqualTo(8).Within(cTolerance)); - Assert.That(soilProfile2D.Geometry.Surfaces, Has.Count.EqualTo(3)); + // At first there are 3 surfaces, after cutting the boundary, there still must be 3 surfaces + Assert.That(soilProfile2D.Geometry.Surfaces.Count, Is.EqualTo(3)); + // At first there are 12 points, after cutting the boundary, there still must be 12 points + Assert.That(soilProfile2D.Geometry.Points.Count, Is.EqualTo(12)); + // At first there are 14 curves, after cutting the boundary, there still must be 14 curves + Assert.That(soilProfile2D.Geometry.Curves.Count, Is.EqualTo(14)); }); } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs =================================================================== diff -u -r4899 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 4899) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 5028) @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Deltares.DamEngine.Data.Standard; using Deltares.DamEngine.Data.Standard.Language; using Deltares.DamEngine.Data.Standard.Validation; @@ -750,8 +751,8 @@ /// The points on the Left boundary public List GetLeftPoints() { - List geometryPoints = Points.Where(gp => Math.Abs(gp.X - Left) < GeometryConstants.Accuracy).ToList(); - return geometryPoints; + List leftPoints = Points.Where(gp => Math.Abs(gp.X - Left) < GeometryConstants.Accuracy).ToList(); + return leftPoints; } /// @@ -760,8 +761,8 @@ /// The points on the Right boundary public List GetRightPoints() { - List geometryPoints = Points.Where(point => Math.Abs(point.X - Right) < GeometryConstants.Accuracy).ToList(); - return geometryPoints; + List rightPoints = Points.Where(point => Math.Abs(point.X - Right) < GeometryConstants.Accuracy).ToList(); + return rightPoints; } /// @@ -878,17 +879,17 @@ if (geometryObject.GetType() == typeof(Point2D)) { - var geometryPoint = (Point2D) geometryObject; + var point = (Point2D) geometryObject; - if (Points.Remove(geometryPoint)) + if (Points.Remove(point)) { // TODO: MWDAM-2132, check if code below is still needed // if (aValidate) // { // HandleDelete(objectlist); // } // - // DataEventPublisher.DataListModified(pointDataList, geometryPoint); + // DataEventPublisher.DataListModified(pointDataList, point); removeFromList = true; } } @@ -992,10 +993,10 @@ /// CheckIfIntersectStricktly /// Determines if two lines intersect each other stricktly (so no extrapolated points). /// - /// Line 1 GeometryPoint 1 - /// Line 1 GeometryPoint 2 - /// Line 2 GeometryPoint 1 - /// Line 2 GeometryPoint 2 + /// Line 1 Point2D 1 + /// Line 1 Point2D 2 + /// Line 2 Point2D 1 + /// Line 2 Point2D 2 /// Intersection coordinates /// True if lines intersect each other private bool CheckIfIntersectStricktly(Point2D beginPoint1, Point2D endPoint1, @@ -1017,10 +1018,10 @@ /// CheckIfIntersect /// Determines if two lines intersect each other stricktly (so no extrapolated points). /// - /// Line 1 GeometryPoint 1 - /// Line 1 GeometryPoint 2 - /// Line 2 GeometryPoint 1 - /// Line 2 GeometryPoint 2 + /// Line 1 Point2D 1 + /// Line 1 Point2D 2 + /// Line 2 Point2D 1 + /// Line 2 Point2D 2 /// Intersection coordinates /// True if lines intersect each other public bool CheckIfIntersect(double[] aL1P1, double[] aL1P2, double[] aL2P1, double[] aL2P2, @@ -1159,4 +1160,209 @@ #endregion #endregion + + public Point2D CreatePoint(Point2D requestedPoint, bool snapToExistingPoint) + { + long num = 0; + Point2D newPoint = null; + bool flag1 = false; + if (num < 1L) + { + bool flag2 = false; + if (snapToExistingPoint) + newPoint = GetPoint(requestedPoint, 0.001); + if (newPoint != null) + { + requestedPoint.X = newPoint.X; + requestedPoint.Z = newPoint.Z; + if (!Points.Contains(requestedPoint)) + newPoint = null; + else + flag1 = true; + } + if (newPoint == null) + { + newPoint = new Point2D(requestedPoint.X, requestedPoint.Z); + Create((IGeometryObject) newPoint); + } + else + flag2 = true; + if (!flag2 & snapToExistingPoint) + { + int count = this.Curves.Count; + for (int index = 0; index < count; ++index) + { + GeometryCurve curve = this.Curves[index]; + if (Routines2D.DoesPointExistInLine(curve.HeadPoint, curve.EndPoint, newPoint, 0.25)) + { + double aResultX; + double aResultZ; + Routines2D.GetPointOnLineClosestTo(newPoint.X, newPoint.Z, curve.HeadPoint.X, curve.HeadPoint.Z, + curve.EndPoint.X, curve.EndPoint.Z, out aResultX, out aResultZ); + newPoint.X = aResultX; + newPoint.Z = aResultZ; + break; + } + } + } + } + if (!NewlyEffectedPoints.Contains(newPoint) && !flag1) + NewlyEffectedPoints.Add(newPoint); + return newPoint; + } + + public IGeometryObject Create(IGeometryObject aData) + { + if (aData == null) + return (IGeometryObject) null; + if (aData.GetType() == typeof (Point2D)) + { + Point2D point = (Point2D) aData; + this.Points.Add(point); + //point.Name = (pointIndex++.ToString()); + } + else if (aData.GetType() == typeof (GeometryCurve)) + { + GeometryCurve geometryCurve = (GeometryCurve) aData; + Curves.Add(geometryCurve); + //geometryCurve.SetName(this.curveIndex++.ToString()); + } + else if (aData.GetType() == typeof (GeometryLoop)) + Loops.Add((GeometryLoop) aData); + else if (aData.GetType() == typeof (GeometrySurface)) + Surfaces.Add((GeometrySurface) aData); + return aData; + } + + public Point2D GetPoint(Point2D point2D, double snapDistance) + { + for (int index = 0; index < Points.Count; ++index) + { + if (Routines2D.DetermineIfPointsCoincide(point2D.X, point2D.Z, Points[index].X, Points[index].Z, snapDistance)) + return new Point2D(Points[index].X, Points[index].Z); + } + return null; + } + + public bool DeletePoint(Point2D aPoint) + { + int num = 0; + bool flag = false; + List source = new List(); + if (Curves.Count > 0) + { + source.AddRange(Curves.Where((Func) (c => c.HeadPoint == aPoint || c.EndPoint == aPoint))); + if (num + source.Count == 2) + { + Point2D line1Point1 = new Point2D(); + Point2D line2Point1 = new Point2D(); + line1Point1.Init(source[0].HeadPoint != aPoint ? source[0].HeadPoint : source[0].EndPoint); + line2Point1.Init(source[1].HeadPoint != aPoint ? source[1].HeadPoint : source[1].EndPoint); + double angle = Routines2D.FindAngle(line1Point1, aPoint, line2Point1, aPoint); + if (angle.IsGreaterThanOrEqualTo(179.0) && angle.IsLessThanOrEqualTo(181.0)) + { + for (int index = 0; index < Curves.Count - 1; ++index) + { + if (Curves[index] == source[0]) + { + if (Curves[index].EndPoint != source[1].EndPoint && aPoint == source[0].HeadPoint && aPoint == source[1].HeadPoint) + Curves[index].HeadPoint = source[1].EndPoint; + else if (Curves[index].EndPoint != source[1].EndPoint && aPoint == source[1].HeadPoint) + Curves[index].EndPoint = source[1].EndPoint; + else if (Curves[index].HeadPoint != source[1].HeadPoint && aPoint == Curves[index].EndPoint) + Curves[index].EndPoint = source[1].HeadPoint; + else if (Curves[index].HeadPoint == source[1].EndPoint) + Curves[index].HeadPoint = source[1].HeadPoint; + Remove(aPoint, false); + Remove(source[1], false); + } + } + } + } + Remove(aPoint, false); + if (source.Any((Func) (curve => curve.SurfaceAtLeft != null || curve.SurfaceAtRight != null))) + flag = true; + foreach (GeometryCurve aCurve in source) + DeleteCurve(aCurve, true); + return flag; + } + Remove(aPoint, false); + return false; + } + + public GeometryCurve CreateCurve(List points, Point2D aPoint1, Point2D aPoint2) + { + if (aPoint1 == null && aPoint2 == null) + { + if (points.Count < 1) + return null; + Point2D geometryPoint1 = null; + if (points.Count == 1) + { + Point2D point = points[0]; + Point2D aPoint = new Point2D(point.X, point.Z); + List aCurveList = new List(); + GetCurvesCoincidingInputPoint(aPoint, ref aCurveList); + if (aCurveList.Count <= 0) + return null; + geometryGenerator.SplitCurvesAtCoincidentPoint(CreatePoint(point, true), aCurveList); + } + else + { + for (int index = 0; index < points.Count - 1; ++index) + { + Point2D geometryPoint2 = index != 0 ? geometryPoint1 : CreatePoint(points[index], true); + geometryPoint1 = CreatePoint(points[index + 1], true); + bool flag = false; + foreach (GeometryCurve curve in Curves) + { + if (curve.HeadPoint == geometryPoint2 && curve.EndPoint == geometryPoint1 || + curve.HeadPoint == geometryPoint1 && curve.EndPoint == geometryPoint2) + { + flag = true; + } + } + if (!flag) + { + GeometryCurve geometryCurve = new GeometryCurve(); + geometryGenerator.SetIsUsed(geometryCurve, CurveDirection.Forward, false); + geometryGenerator.SetIsUsed(geometryCurve, CurveDirection.Reverse, false); + geometryCurve.HeadPoint = geometryPoint2; + geometryCurve.EndPoint = geometryPoint1; + Create((IGeometryObject) geometryCurve); + NewlyEffectedCurves.Add(geometryCurve); + } + } + } + RegenerateGeometry(); // #Bka: dit is een directe call, geen delayed invoke. Kan tot problemen leiden (eeuwig ronddraaien) + return Curves.Count > 0 ? Curves[0] : (GeometryCurve) null; + } + foreach (GeometryCurve curve in this.Curves) + { + if (curve.HeadPoint == aPoint1 && curve.EndPoint == aPoint2 || curve.HeadPoint == aPoint2 && curve.EndPoint == aPoint1) + { + return curve; + } + } + GeometryCurve curve1 = new GeometryCurve(); + geometryGenerator.SetIsUsed(curve1, CurveDirection.Forward, false); + geometryGenerator.SetIsUsed(curve1, CurveDirection.Reverse, false); + curve1.HeadPoint = aPoint1; + curve1.EndPoint = aPoint2; + this.Create((IGeometryObject) curve1); + NewlyEffectedCurves.Add(curve1); + return curve1; + } + + public void GetCurvesCoincidingInputPoint(Point2D aPoint, ref List aCurveList) + { + aCurveList.Clear(); + int count = this.Curves.Count; + for (int index = 0; index < count; ++index) + { + GeometryCurve curve = this.Curves[index]; + if (Routines2D.DoesPointExistInLine(curve.HeadPoint, curve.EndPoint, aPoint, 0.001)) + aCurveList.Add(curve); + } + } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs =================================================================== diff -u -r4897 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs (.../Routines2D.cs) (revision 4897) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs (.../Routines2D.cs) (revision 5028) @@ -586,7 +586,7 @@ /// X-coordinate of the second point /// Y-coordinate of the second point /// The distance between the given points. - private static double Compute2DDistance(double aX1, double aY1, double aX2, double aY2) + public static double Compute2DDistance(double aX1, double aY1, double aX2, double aY2) { double lX = aX1 - aX2; double lY = aY1 - aY2; @@ -764,4 +764,70 @@ public double Y { get; set; } public double Z { get; set; } } + + public static double CalculateDistanceToLine( + double pointX, + double pointY, + double segmentStartX, + double segmentStartY, + double segmentEndX, + double segmentEndY) + { + return Math.Sqrt(CalculateSquaredDistance(new Point2D(pointX, pointY), new Point2D(segmentStartX, segmentStartY), + new Point2D(segmentEndX, segmentEndY))); + } + + private static double CalculateSquaredDistance(Point2D point, Point2D segmentPoint1, Point2D segmentPoint2) + { + Point2D point2D1 = segmentPoint2 - segmentPoint1; + Point2D point2D2 = point - segmentPoint1; + Func func = (first, second) => first.X * second.X + first.Z * second.Z; + double num1 = func(point2D2, point2D1); + double num2 = func(point2D1, point2D1); + Point2D point2D3; + if (num1 <= 0.0) + point2D3 = point - segmentPoint1; + else if (num2 <= num1) + { + point2D3 = point - segmentPoint2; + } + else + { + double num3 = num1 / num2; + Point2D point2D4 = segmentPoint1 + num3 * point2D1; + point2D3 = point - point2D4; + } + return func(point2D3, point2D3); + } + + public static void GetPointOnLineClosestTo( + double aPointX, + double aPointY, + double aLine1X, + double aLine1Y, + double aLine2X, + double aLine2Y, + out double aResultX, + out double aResultY) + { + double x1 = Compute2DDistance(aLine1X, aLine1Y, aLine2X, aLine2Y); + double x2 = Compute2DDistance(aLine1X, aLine1Y, aPointX, aPointY); + double x3 = Compute2DDistance(aLine2X, aLine2Y, aPointX, aPointY); + double num = (Math.Pow(x2, 2.0) - Math.Pow(x3, 2.0) + Math.Pow(x1, 2.0)) / (2.0 * x1); + if (num <= 0.0) + { + aResultX = aLine1X; + aResultY = aLine1Y; + } + else if (num >= x1) + { + aResultX = aLine2X; + aResultY = aLine2Y; + } + else + { + aResultX = aLine1X + num / x1 * (aLine2X - aLine1X); + aResultY = aLine1Y + num / x1 * (aLine2Y - aLine1Y); + } + } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryHelper.cs =================================================================== diff -u -r4984 -r5028 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryHelper.cs (.../GeometryHelper.cs) (revision 4984) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryHelper.cs (.../GeometryHelper.cs) (revision 5028) @@ -160,6 +160,7 @@ } } geometry.Rebox(); + geometry.Left = atX; } /// @@ -187,8 +188,7 @@ if (res == LineIntersection.Intersects) { var splitPoint = new Point2D(resPoint.X, resPoint.Z); - // Split the curve at the split point - //SplitCurveAtPoint(geometry, geometryCurve, splitPoint); + // Add SplitPoint to the local list splitPoints.Add(splitPoint); } } @@ -197,15 +197,6 @@ // Add the vertical curves between the split points AddCurvesBetweenSplitPoints(geometry, splitPoints); - // List surfaces = geometry.Surfaces.ToList(); - // foreach (GeometrySurface aSurface in surfaces) - // { - // DeleteSurface(geometry, aSurface); - // } - // geometry.NewlyEffectedCurves.AddRange(geometry.Curves); - // geometry.Curves.Clear(); - // geometry.NewlyEffectedPoints.AddRange(geometry.Points); - // geometry.Points.Clear(); Hier heb ik schijnbaar nog maar 1 loop ipv 3. Nakijken hoe dit loopt bij left geometry.RegenerateGeometry(); // Remove all surfaces right of the new limit @@ -224,7 +215,6 @@ geometry.DeletePointWithCurves(points[i]); } } - geometry.Rebox(); } @@ -300,6 +290,7 @@ geometry.DeleteCurve(aCurve, true); geometry.Remove( outerLoop, false); geometry.Remove( aSurface, false); + geometry.NewlyEffectedCurves.Clear(); } ///