// Copyright (C) Stichting Deltares 2024. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Linq; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using NUnit.Framework; namespace Deltares.DamEngine.Data.Tests.Geotechnics; [TestFixture] public class SurfaceLine2Tests { [Test] public void TestAddingCharacteristicPointsOnSameLocationDoesNotAddDoublePointsInGeometry() { SurfaceLine2 surfaceLine = FillSurfaceLine2(); Assert.AreEqual(10, surfaceLine.CharacteristicPoints.Count); ValidateSurfaceLine(surfaceLine); } [Test] public void TestDeepCloneWithoutGeometryMustContainPoint() { SurfaceLine2 surfaceLine = FillSurfaceLine2(); Assert.AreEqual(10, surfaceLine.CharacteristicPoints.Count); Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); // Note: resetting GeometryMustContainPoint to false after filling the surface line will erase all Characteristic Points. // So the actual code should NEVER reset the GeometryMustContainPoint for filled surface lines. surfaceLine.CharacteristicPoints.GeometryMustContainPoint = false; Assert.AreEqual(0, surfaceLine.CharacteristicPoints.Count); SurfaceLine2 newSurfaceLine = surfaceLine.FullDeepClone(); surfaceLine.CharacteristicPoints.Clear(); surfaceLine.Geometry.CalcPoints.Clear(); surfaceLine.Geometry.SyncPoints(); Assert.AreEqual(0, newSurfaceLine.CharacteristicPoints.Count); Assert.AreEqual(9, newSurfaceLine.Geometry.Points.Count); } [Test] public void TestDeepCloneWithGeometryMustContainPoint() { SurfaceLine2 surfaceLine = FillSurfaceLine2(); Assert.AreEqual(10, surfaceLine.CharacteristicPoints.Count); Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); // Note: resetting GeometryMustContainPoint to true after filling the surface line reset the Characteristic Points to be // equal to the amount of geometry points, keeping only one type, possibly making the surface line invalid. // So the actual code should NEVER reset the GeometryMustContainPoint for filled surface lines. surfaceLine.CharacteristicPoints.GeometryMustContainPoint = true; Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); Assert.AreEqual(9, surfaceLine.CharacteristicPoints.Count); SurfaceLine2 newSurfaceLine = surfaceLine.FullDeepClone(); surfaceLine.CharacteristicPoints.Clear(); surfaceLine.Geometry.CalcPoints.Clear(); surfaceLine.Geometry.SyncPoints(); Assert.AreEqual(9, newSurfaceLine.CharacteristicPoints.Count); Assert.AreEqual(9, newSurfaceLine.Geometry.Points.Count); } [Test] public void TestDeepCloneWithoutSettingGeometryMustContainPoint() { SurfaceLine2 surfaceLine = FillSurfaceLine2(); Assert.AreEqual(10, surfaceLine.CharacteristicPoints.Count); Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); SurfaceLine2 newSurfaceLine = surfaceLine.FullDeepClone(); surfaceLine.CharacteristicPoints.Clear(); surfaceLine.Geometry.CalcPoints.Clear(); surfaceLine.Geometry.SyncPoints(); Assert.AreEqual(10, newSurfaceLine.CharacteristicPoints.Count); Assert.AreEqual(9, newSurfaceLine.Geometry.Points.Count); var tolerance = 1e-8; surfaceLine = FillSurfaceLine2(); Assert.AreEqual(surfaceLine.CharacteristicPoints[0].X, newSurfaceLine.CharacteristicPoints[0].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[0].Z, newSurfaceLine.CharacteristicPoints[0].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[0].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[0].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[1].X, newSurfaceLine.CharacteristicPoints[1].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[1].Z, newSurfaceLine.CharacteristicPoints[1].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[1].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[1].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[2].X, newSurfaceLine.CharacteristicPoints[2].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[2].Z, newSurfaceLine.CharacteristicPoints[2].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[2].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[2].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[3].X, newSurfaceLine.CharacteristicPoints[3].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[3].Z, newSurfaceLine.CharacteristicPoints[3].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[3].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[3].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[4].X, newSurfaceLine.CharacteristicPoints[4].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[4].Z, newSurfaceLine.CharacteristicPoints[4].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[4].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[4].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[5].X, newSurfaceLine.CharacteristicPoints[5].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[5].Z, newSurfaceLine.CharacteristicPoints[5].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[5].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[5].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[6].X, newSurfaceLine.CharacteristicPoints[6].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[6].Z, newSurfaceLine.CharacteristicPoints[6].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[6].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[6].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[7].X, newSurfaceLine.CharacteristicPoints[7].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[7].Z, newSurfaceLine.CharacteristicPoints[7].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[7].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[7].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[8].X, newSurfaceLine.CharacteristicPoints[8].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[8].Z, newSurfaceLine.CharacteristicPoints[8].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[8].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[8].CharacteristicPointType); Assert.AreEqual(surfaceLine.CharacteristicPoints[9].X, newSurfaceLine.CharacteristicPoints[9].X, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[9].Z, newSurfaceLine.CharacteristicPoints[9].Z, tolerance); Assert.AreEqual(surfaceLine.CharacteristicPoints[9].CharacteristicPointType, newSurfaceLine.CharacteristicPoints[9].CharacteristicPointType); } private static void ValidateSurfaceLine(SurfaceLine2 surfaceLine) { var tolerance = 0.001; Assert.AreEqual(2, surfaceLine.CharacteristicPoints.Count(cp => Math.Abs(cp.X - 13.0) < tolerance && Math.Abs(cp.Z - 5.4) < tolerance)); // Because TrafficLoadOutside and DikeTopAtPolder are on the same location, 1 point less should be in the geometry Assert.AreEqual(9, surfaceLine.Geometry.Points.Count); Assert.AreEqual(1, surfaceLine.Geometry.Points.Count(cp => Math.Abs(cp.X - 13.0) < tolerance && Math.Abs(cp.Z - 5.4) < tolerance)); } private SurfaceLine2 FillSurfaceLine2() { var surfaceLine = new SurfaceLine2(); surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry; AddPointToSurfaceLine(surfaceLine, 0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); AddPointToSurfaceLine(surfaceLine, 2.0, 0.5, CharacteristicPointType.None); AddPointToSurfaceLine(surfaceLine, 4.0, 0.0, CharacteristicPointType.DikeToeAtRiver); AddPointToSurfaceLine(surfaceLine, 9.0, 5.0, CharacteristicPointType.DikeTopAtRiver); AddPointToSurfaceLine(surfaceLine, 10.0, 5.2, CharacteristicPointType.None); AddPointToSurfaceLine(surfaceLine, 13.0, 5.4, CharacteristicPointType.DikeTopAtPolder); AddPointToSurfaceLine(surfaceLine, 13.0, 5.4, CharacteristicPointType.TrafficLoadOutside); AddPointToSurfaceLine(surfaceLine, 14.0, 4.52, CharacteristicPointType.TrafficLoadInside); AddPointToSurfaceLine(surfaceLine, 18.0, 1.0, CharacteristicPointType.DikeToeAtPolder); AddPointToSurfaceLine(surfaceLine, 24.0, 1.0, CharacteristicPointType.SurfaceLevelInside); surfaceLine.Geometry.SyncCalcPoints(); return surfaceLine; } private void AddPointToSurfaceLine(SurfaceLine2 surfaceLine, double xCoordinate, double zCoordinate, CharacteristicPointType characteristicPointType) { var geometryPoint = new GeometryPoint { X = xCoordinate, Y = 0.0, Z = zCoordinate }; surfaceLine.AddCharacteristicPoint(geometryPoint, characteristicPointType); } }