// Copyright (C) Stichting Deltares 2016. 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.Drawing;
using System.Drawing.Drawing2D;
using Deltares.Geometry;
using Deltares.Geometry.Forms;
using Deltares.Geotechnics;
using Deltares.Mathematics;
using Deltares.Standard.EventPublisher;
using Deltares.Standard.Forms;
using Deltares.Standard.Logging;
namespace Deltares.DSoilModel.Forms
{
///
/// Drawing class for displaying a Boring in the DSL geometry editor
/// see http://www.geffiles.nl/cur/BORE_nl.html
///
public class DrawingBoring : DrawingObject
{
private Boring boring;
private BoringLookup1D boringLookup1D;
private BoringLookup2D boringLookup2D;
private object dataObj;
private GeometryPoint insertionPoint;
private double width = 10; // default display width
///
/// Gets the x of a 2D boring.
///
public double X
{
get
{
return (boringLookup2D != null) ? boringLookup2D.Xlocal : insertionPoint.X;
}
}
///
/// Gets the z of a 2D boring.
///
public double Z
{
get
{
return (boringLookup2D != null) ? boringLookup2D.Zlocal : 0;
}
}
///
/// Gets the top.
///
public double Top
{
get
{
return (boring != null) ? boring.Top + Z : 0;
}
}
///
/// Gets the bottom.
///
public double Bottom
{
get
{
return (boring != null) ? boring.Bottom + Z : 0;
}
}
///
/// Gets or sets the width.
///
public double Width
{
get
{
return width;
}
set
{
width = value;
}
}
///
/// Gets the left.
///
public double Left
{
get
{
return X - width/2;
}
}
///
/// Gets the right.
///
public double Right
{
get
{
return X + width/2;
}
}
///
/// Sets the data object (Boring, BoringLookup1D or BoringLookup2D).
///
/// The data object.
public override void SetDataObject(object dataObject)
{
dataObj = dataObject;
boringLookup1D = null;
boringLookup2D = null;
if (dataObject is Boring)
{
boring = (Boring) dataObject;
insertionPoint = new GeometryPoint(0, 0, 0);
width = 10;
}
else if (dataObject is BoringLookup1D)
{
boringLookup1D = (BoringLookup1D) dataObject;
boring = boringLookup1D.Boring;
insertionPoint = new GeometryPoint(-2.5, 0, 0);
width = 5;
}
else if (dataObject is BoringLookup2D)
{
boringLookup2D = (BoringLookup2D) dataObject;
boring = boringLookup2D.Boring;
insertionPoint = new GeometryPoint(boringLookup2D.Xlocal, 0, boringLookup2D.Zlocal);
width = 2.5;
if (boringLookup2D.SoilProfile2D != null)
{
var profile = boringLookup2D.SoilProfile2D;
var bounds = profile.Geometry.GetGeometryBounds();
width = (bounds.Right - bounds.Left)/40;
}
}
if (boring != null)
{
SynchronizeColors();
}
}
///
/// Returns the data object.
///
public override object GetDataObject()
{
return dataObj;
}
///
/// Draws the boring.
///
/// The information.
public override void Draw3D(GraphicsInfo info)
{
try
{
DrawingSupport.SetIEPDraw3D(info.Graphics);
var topLeft = GetScaledPoint(info.Projection, new Point3D(Left, 0d, Top));
var bottomRight = GetScaledPoint(info.Projection, new Point3D(Right, 0, Bottom));
var rectBoring = new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
if (info.Selected)
{
info.Graphics.FillRectangle(new HatchBrush(HatchStyle.LargeCheckerBoard, Color.WhiteSmoke, Color.LightGray), rectBoring);
info.Graphics.DrawRectangle(new Pen(Color.Black, 2), rectBoring);
}
else
{
info.Graphics.FillRectangle(new SolidBrush(Color.WhiteSmoke), rectBoring);
info.Graphics.DrawRectangle(new Pen(Color.Black), rectBoring);
}
Rectangle rect;
foreach (var row in boring.BoringDatarows)
{
topLeft = GetScaledPoint(info.Projection, new Point3D(Left, 0d, Z + row.TopLevel));
bottomRight = GetScaledPoint(info.Projection, new Point3D(Right, 0, Z + row.BottomLevel));
rect = new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
if (info.Selected)
{
info.Graphics.FillRectangle(new HatchBrush(HatchStyle.LargeCheckerBoard, row.SoilColor, DrawingSupport.GetLighterColor(row.SoilColor)), rect);
info.Graphics.DrawRectangle(new Pen(Color.DarkSlateGray), rect);
}
else
{
info.Graphics.FillRectangle(new SolidBrush(row.SoilColor), rect);
info.Graphics.DrawRectangle(new Pen(Color.DarkSlateGray), rect);
}
}
info.Graphics.DrawRectangle(new Pen(Color.Black), rectBoring);
}
catch (System.Exception ex)
{
LogManager.Add(new LogMessage(LogMessageType.Error, ex, ex.Message));
}
}
///
/// Called when dragging has begun
///
public override void OnBeginDrag(IProjection projection, Point3D aBeginDragDropPoint, bool isIndividualDrag)
{
if (boringLookup2D != null)
{
DataEventPublisher.BeforeChange(boringLookup2D, "Xlocal");
DrawingPoint.BeginMovePoints();
}
}
///
/// Updates the data drag drop.
///
public override void UpdateDataDragDrop(Point3D beginDragPoint, Vector3D vector)
{
if (boringLookup2D != null)
{
DrawingPoint.Move(insertionPoint, vector, beginDragPoint);
boringLookup2D.Xlocal = insertionPoint.X;
insertionPoint.Z = boringLookup2D.Zlocal;
}
}
///
/// Called when dragging has ended
///
public override void OnEndDrag(IProjection projection, Point3D aCurrentDragPoint, Vector3D aVect3D)
{
if (boringLookup2D != null)
{
// only XLocal can be set by dragging a Boring
boringLookup2D.Xlocal = insertionPoint.X;
DataEventPublisher.AfterChange(boringLookup2D, "Xlocal");
insertionPoint.Z = boringLookup2D.Zlocal;
}
}
///
/// Determines whether the specified projection contains 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 of the projection.
///
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);
}
///
/// Gets the scaled point.
///
private Point GetScaledPoint(IProjection projection, Point3D aOrginalPoint)
{
return projection.ConvertToScreen(aOrginalPoint.GetPointXZ());
}
///
/// Synchronizes the colors for the rows to the colors of the soil in the layers.
///
private void SynchronizeColors()
{
for (int i = 0; i < boring.BoringDatarows.Count; i++)
{
if (i < boring.BoringLayers.Count && boring.BoringLayers[i].Soil != null)
{
boring.BoringDatarows[i].SoilColor = boring.BoringLayers[i].Soil.Color;
}
}
}
}
}