// Copyright (C) Stichting Deltares 2024. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI is free software: you can redistribute it and/or modify // it under the terms of the GNU 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 General Public License for more details. // // You should have received a copy of the GNU 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.Collections.Generic; using System.Drawing; using System.Linq; using Components.Persistence.Stability.Version2.Data; using Deltares.Geometry; using Deltares.Geotechnics.Soils; namespace Deltares.Dam.StixFileReader; /// /// Creates a from a . /// public class SoilProfile2DDataModel { /// /// Converts a to a . /// /// /// /// public SoilProfile2D Create(PersistableDataModel dataModel, double offsetX) { string geometryId = dataModel.Scenarios.Last().Stages.Last().GeometryId; PersistableGeometry geometry = dataModel.Geometry.First(g => g.Id == geometryId); var soilProfile2D = new SoilProfile2D(); foreach (PersistableLayer layer in geometry.Layers) { CreateCurvesFromLayer(layer, soilProfile2D.Geometry.Curves, offsetX); GeometrySurface surface = CreateSurfacesFromLayer(layer, soilProfile2D.Geometry.Surfaces, offsetX); foreach (PersistablePoint point in layer.Points) { if (!IsPointPresent(point, soilProfile2D.Geometry.Points, offsetX)) { soilProfile2D.Geometry.Points.Add(new GeometryPoint(point.X + offsetX, 0, point.Z)); } } PersistableSoil persistableSoil = FetchSoilProperties(layer.Id, dataModel); var soil = new Soil(); if (persistableSoil != null) { soil.Name = persistableSoil.Name; soil.Color = FetchSoilColor(persistableSoil, dataModel); } var soilLayer2D = new SoilLayer2D { Soil = soil, GeometrySurface = surface }; soilProfile2D.Surfaces.Add(soilLayer2D); } soilProfile2D.Geometry.Rebox(); return soilProfile2D; } private Color FetchSoilColor(PersistableSoil persistableSoil, PersistableDataModel dataModel) { var color = new Color(); if (dataModel.SoilVisualizations == null) { return color; } foreach (PersistableSoilVisualization soilVisualization in dataModel.SoilVisualizations.SoilVisualizations) { if (soilVisualization.SoilId == persistableSoil.Id) { color = soilVisualization.Color; } } return color; } private PersistableSoil FetchSoilProperties(string layerId, PersistableDataModel dataModel) { var soilId = string.Empty; foreach (PersistableSoilLayerCollection soilLayer in dataModel.SoilLayers) { foreach (PersistableSoilLayer persistableSoilLayer in soilLayer.SoilLayers) { if (persistableSoilLayer.LayerId == layerId) { soilId = persistableSoilLayer.SoilId; } } } return soilId == string.Empty ? null : dataModel.Soils.Soils.FirstOrDefault(soil => soil.Id == soilId); } private GeometrySurface CreateSurfacesFromLayer(PersistableLayer layer, ICollection geometrySurface, double offsetX) { var surface = new GeometrySurface(); for (var i = 0; i < layer.Points.Count(); i++) { surface.OuterLoop.Points.Add(new GeometryPoint(layer.Points.ElementAt(i).X + offsetX, 0, layer.Points.ElementAt(i).Z)); for (var j = 0; j < layer.Points.Count(); j++) { GeometryCurve curve = CreateCurveFromLayer(layer, j, offsetX); if (!IsCurvePresent(curve, surface.OuterLoop.CurveList)) { surface.OuterLoop.CurveList.Add(curve); } } surface.Name = layer.Label; } // ToDo: Add inner loops geometrySurface.Add(surface); return surface; } private void CreateCurvesFromLayer(PersistableLayer layer, ICollection geometryCurves, double offsetX) { for (var i = 0; i < layer.Points.Count(); i++) { GeometryCurve curve = CreateCurveFromLayer(layer, i, offsetX); if (!IsCurvePresent(curve, geometryCurves)) { geometryCurves.Add(curve); } } //GeometryCurve curve = CreateCurveFromLayer(layer, i, offsetX); } private GeometryCurve CreateCurveFromLayer(PersistableLayer layer, int index, double offsetX) { GeometryCurve curve; if (index == layer.Points.Count() - 1) { curve = CreateCurve(layer.Points.ElementAt(index), layer.Points.ElementAt(0), offsetX); } else { curve = CreateCurve(layer.Points.ElementAt(index), layer.Points.ElementAt(index + 1), offsetX); } return curve; } private GeometryCurve CreateCurve(PersistablePoint firstPoint, PersistablePoint secondPoint, double offsetX) { return new GeometryCurve { HeadPoint = new GeometryPoint(firstPoint.X + offsetX, 0, firstPoint.Z), EndPoint = new GeometryPoint(secondPoint.X + offsetX, 0, secondPoint.Z) }; } private bool IsCurvePresent(GeometryCurve curve, IEnumerable geometryCurves) { return geometryCurves.Any(geometryCurve => (ArePointsEqual(geometryCurve.HeadPoint, curve.HeadPoint) && ArePointsEqual(geometryCurve.EndPoint, curve.EndPoint)) || (ArePointsEqual(geometryCurve.EndPoint, curve.HeadPoint) && ArePointsEqual(geometryCurve.HeadPoint, curve.EndPoint))); } private bool IsPointPresent(PersistablePoint point, IEnumerable geometryPoints, double offsetX) { return geometryPoints.Any(geometryPoint => ArePointsEqual(geometryPoint, point, offsetX)); } private bool ArePointsEqual(GeometryPoint firstPoint, GeometryPoint secondPoint) { const double pointTolerance = 1E-6; return (Math.Abs(firstPoint.X - secondPoint.X) < pointTolerance) && (Math.Abs(firstPoint.Z - secondPoint.Z) < pointTolerance); } private bool ArePointsEqual(GeometryPoint firstPoint, PersistablePoint secondPoint, double offsetX) { const double pointTolerance = 1E-6; return (Math.Abs(firstPoint.X - (secondPoint.X + offsetX)) < pointTolerance) && (Math.Abs(firstPoint.Z - secondPoint.Z) < pointTolerance); } }