// 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)
{
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);
GeometrySurface surface = CreateSurfacesFromLayer(layer, soilProfile2D.Geometry.Surfaces);
foreach (PersistablePoint point in layer.Points)
{
if (!IsPointPresent(point, soilProfile2D.Geometry.Points))
{
soilProfile2D.Geometry.Points.Add(new GeometryPoint(point.X, 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);
}
SetLimits(soilProfile2D);
return soilProfile2D;
}
private static void SetLimits(SoilProfile2D soilProfile2D)
{
soilProfile2D.Geometry.Left = soilProfile2D.Geometry.MinGeometryPointsX;
soilProfile2D.Geometry.Right = soilProfile2D.Geometry.MaxGeometryPointsX;
soilProfile2D.Geometry.Bottom = soilProfile2D.Geometry.MinGeometryPointsZ;
}
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)
{
var surface = new GeometrySurface();
for (var i = 0; i < layer.Points.Count(); i++)
{
surface.OuterLoop.Points.Add(new GeometryPoint(layer.Points.ElementAt(i).X, 0, layer.Points.ElementAt(i).Z));
for (var j = 0; j < layer.Points.Count(); j++)
{
GeometryCurve curve = CreateCurveFromLayer(layer, j);
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)
{
for (var i = 0; i < layer.Points.Count(); i++)
{
GeometryCurve curve = CreateCurveFromLayer(layer, i);
if (!IsCurvePresent(curve, geometryCurves))
{
geometryCurves.Add(curve);
}
}
}
private GeometryCurve CreateCurveFromLayer(PersistableLayer layer, int index)
{
GeometryCurve curve;
if (index == layer.Points.Count() - 1)
{
curve = CreateCurve(layer.Points.ElementAt(index), layer.Points.ElementAt(0));
}
else
{
curve = CreateCurve(layer.Points.ElementAt(index), layer.Points.ElementAt(index + 1));
}
return curve;
}
private GeometryCurve CreateCurve(PersistablePoint firstPoint, PersistablePoint secondPoint)
{
return new GeometryCurve
{
HeadPoint = new GeometryPoint(firstPoint.X, 0, firstPoint.Z),
EndPoint = new GeometryPoint(secondPoint.X, 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)
{
return geometryPoints.Any(geometryPoint => ArePointsEqual(geometryPoint, point));
}
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)
{
const double pointTolerance = 1E-6;
return (Math.Abs(firstPoint.X - secondPoint.X) < pointTolerance) &&
(Math.Abs(firstPoint.Z - secondPoint.Z) < pointTolerance);
}
}