// Copyright (C) Stichting Deltares 2024. All rights reserved. // // This file is part of the D-Soil Model application. // // The D-Soil Model application 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.Drawing; using System.Drawing.Drawing2D; using System.Linq; using Deltares.Geometry; using Deltares.Geometry.Forms; using Deltares.Geotechnics.IO; using Deltares.Mathematics; using Deltares.Standard.EventPublisher; using Deltares.Standard.Forms; using Deltares.Standard.Logging; namespace Deltares.DSoilModel.Forms { /// /// Drawing class for a new specific point for a mechanism (like Piping Location), which draws a simple square /// into a 2D Soil Profile. Simplicfication of DrawingCPT class. /// public class DrawingSpecificMechanismPointLocation : DrawingObject { private const double percentageForSpecificMechanismPointLocation = 0.01; private double bottom = -20; private object dataObj; private GeometryPoint insertionPoint = new GeometryPoint(0, 0, 0); private SpecificMechanismPointLocation specificMechanismPointLocation; private double top = 10; private double width = 1; /// /// Gets or sets a value indicating whether the axes will be shown. /// public bool ShowAxes { get; set; } /// /// Gets the x. /// public double X { get { return (specificMechanismPointLocation != null) ? specificMechanismPointLocation.XCoordinate : insertionPoint.X; } } /// /// Gets the left. /// public double Left { get { return X - width/2; } } /// /// Gets the right. /// public double Right { get { return X + width/2; } } /// /// Tops for drawing. /// public double TopForDrawing() { if (specificMechanismPointLocation.SoilProfile2D == null || specificMechanismPointLocation.SoilProfile2D.Geometry == null || specificMechanismPointLocation.SoilProfile2D.Geometry.Points.Count == 0) { return 10; } var diff = GetOffsetFromGeometryHeight(); return specificMechanismPointLocation.SoilProfile2D.Geometry.MaxGeometryPointsZ + 0.05*diff; } /// /// Bottoms for drawing. /// public double BottomForDrawing() { if (specificMechanismPointLocation.SoilProfile2D == null || specificMechanismPointLocation.SoilProfile2D.Geometry == null || specificMechanismPointLocation.SoilProfile2D.Geometry.Points.Count == 0) { if (specificMechanismPointLocation.SoilProfile2D != null && specificMechanismPointLocation.SoilProfile2D.Geometry != null) { return specificMechanismPointLocation.SoilProfile2D.Geometry.Bottom; } return 0; } var diff = GetOffsetFromGeometryHeight(); return specificMechanismPointLocation.SoilProfile2D.Geometry.MinGeometryPointsZ - 0.05*diff; } /// /// Width for drawing. /// public double WidthForDrawing() { if (specificMechanismPointLocation.SoilProfile2D == null || specificMechanismPointLocation.SoilProfile2D.Geometry == null || specificMechanismPointLocation.SoilProfile2D.Geometry.Points.Count == 0) { if (specificMechanismPointLocation.SoilProfile2D != null && specificMechanismPointLocation.SoilProfile2D.Geometry != null) { return Math.Max(1.0, specificMechanismPointLocation.SoilProfile2D.Geometry.Right - specificMechanismPointLocation.SoilProfile2D.Geometry.Left); } return 50.0; } return Math.Abs(specificMechanismPointLocation.SoilProfile2D.Geometry.MaxGeometryPointsX - specificMechanismPointLocation.SoilProfile2D.Geometry.MinGeometryPointsX); } /// /// Sets the data object (SpecificMechanismPointLocation). /// public override void SetDataObject(object dataObject) { dataObj = dataObject; specificMechanismPointLocation = null; var location = dataObject as SpecificMechanismPointLocation; if (location != null) { specificMechanismPointLocation = location; top = TopForDrawing(); bottom = BottomForDrawing(); width = WidthForDrawing()*percentageForSpecificMechanismPointLocation; insertionPoint = new GeometryPoint(specificMechanismPointLocation.XCoordinate, 0, bottom); ShowAxes = true; } } /// /// Gets the data object. /// public override object GetDataObject() { return dataObj; } /// /// Draws the Point Location. /// public override void Draw3D(GraphicsInfo info) { try { if (double.IsNaN(specificMechanismPointLocation.XCoordinate)) { return; } DrawingSupport.SetIEPDraw3D(info.Graphics); var topLeft = info.Projection.ConvertToScreen(new Point2D(Left, top)); var bottomRight = info.Projection.ConvertToScreen(new Point2D(Right, bottom)); var clipRect = new Rectangle(topLeft.X - 1, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); var isValid = RealTimeBackgroundValidator.ValidationResults.All(vr => vr.Subject != specificMechanismPointLocation); var rectangleColor = isValid ? Color.WhiteSmoke : Color.OrangeRed; var rectangleColor2 = isValid ? Color.LightGray : Color.LightCoral; var penColor = isValid ? Color.Black : Color.Red; if (info.Selected) { info.Graphics.FillRectangle(new HatchBrush(HatchStyle.LargeCheckerBoard, rectangleColor, rectangleColor2), clipRect); info.Graphics.DrawRectangle(new Pen(penColor, 2), clipRect); } else { info.Graphics.FillRectangle(new SolidBrush(rectangleColor), clipRect); info.Graphics.DrawRectangle(new Pen(penColor, 1), clipRect); } } catch (Exception ex) { LogManager.Add(new LogMessage(LogMessageType.Error, ex, ex.Message)); } } /// /// Draws the label. /// public override void DrawLabel(GraphicsInfo info) { var color = Color.LightGray; var text = specificMechanismPointLocation.ToString(); var textBrush = Brushes.Black; var backgroundBrush = new SolidBrush(DrawingSupport.GetLighterColor(color)); var borderBrush = new SolidBrush(DrawingSupport.GetDarkerColor(color)); var rectangle = GetExtents(info.Projection); if (rectangle != null) { var rect = (Rectangle) rectangle; var centerX = (rect.Left + rect.Right)/2; var centerY = (rect.Top + rect.Bottom)/2; DrawingSupport.DrawLabelAtPoint(info, new Point(centerX, centerY), text, textBrush, backgroundBrush, borderBrush); } } /// /// Called when [begin drag]. /// public override void OnBeginDrag(IProjection projection, Point3D aBeginDragDropPoint, bool isIndividualDrag) { if (specificMechanismPointLocation != null) { DataEventPublisher.BeforeChange(specificMechanismPointLocation, "xCoordinate"); DrawingPoint.BeginMovePoints(); } } /// /// Updates the data drag drop. /// public override void UpdateDataDragDrop(Point3D beginDragPoint, Vector3D vector) { if (specificMechanismPointLocation != null) { DrawingPoint.Move(insertionPoint, vector, beginDragPoint); specificMechanismPointLocation.XCoordinate = insertionPoint.X; insertionPoint.Z = bottom; } } /// /// Called when [end drag]. /// public override void OnEndDrag(IProjection projection, Point3D aCurrentDragPoint, Vector3D aVect3D) { if (specificMechanismPointLocation != null) { specificMechanismPointLocation.XCoordinate = insertionPoint.X; DataEventPublisher.AfterChange(specificMechanismPointLocation, "xCoordinate"); insertionPoint.Z = 0; } } /// /// Determines whether the specified projection contains the given point. /// public override bool ContainsPoint(IProjection projection, Point point) { var worldPoint = projection.ConvertToWorld(point); return (worldPoint.X >= Left) && (worldPoint.X <= Right) && (worldPoint.Y >= bottom) && (worldPoint.Y <= top); } /// /// Gets the extents. /// public override Rectangle? GetExtents(IProjection projection) { var topLeft = new Point2D(Left, top); var bottomRight = new Point2D(Right, bottom); var topLeftScreen = projection.ConvertToScreen(topLeft); var bottomRightScreen = projection.ConvertToScreen(bottomRight); return new Rectangle(topLeftScreen.X, topLeftScreen.Y, bottomRightScreen.X - topLeftScreen.X, bottomRightScreen.Y - topLeftScreen.Y); } private double GetOffsetFromGeometryHeight() { var diff = specificMechanismPointLocation.SoilProfile2D.Geometry.MaxGeometryPointsZ - specificMechanismPointLocation.SoilProfile2D.Geometry.MinGeometryPointsZ; return diff; } } }