Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs
===================================================================
diff -u -r3893 -r4000
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 3893)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryData.cs (.../GeometryData.cs) (revision 4000)
@@ -33,23 +33,10 @@
///
public class GeometryData : GeometryObject
{
+ private readonly GeometryPointString surfaceLine = new GeometryPointString();
private GeometryGenerator geometryGenerator;
- private readonly List newlyEffectedCurves = new List();
- private readonly List newlyEffectedPoints = new List();
private bool isRegeneratingGeometry;
- private readonly List curveDataList = new List();
-
- private readonly List loopDataList = new List();
- private readonly List pointDataList = new List();
- private readonly List surfaceDataList = new List();
- private readonly GeometryPointString surfaceLine = new GeometryPointString();
- private double bottom = GeometryConstants.DefaultBottomLimitGeometry;
-
- private double left = GeometryConstants.DefaultLeftLimitGeometry;
-
- private double right = GeometryConstants.DefaultRightLimitGeometry;
-
private bool updatingSurfaceLine;
///
@@ -60,90 +47,397 @@
geometryGenerator = null;
}
- #region properties
+ ///
+ /// Ordered list of all geometry points at the surface
+ ///
+ public virtual GeometryPointString SurfaceLine
+ {
+ get
+ {
+ if (surfaceLine.CalcPoints.Count == 0 && Points.Count > 0)
+ {
+ UpdateSurfaceLine();
+ }
+ return surfaceLine;
+ }
+ }
+
///
- /// Gets the points.
+ /// Checks geometry for loose curves and AutoRegeneration
///
- ///
- /// The points.
- ///
+ ///
[Validate]
- public List Points
+ public ValidationResult[] ValidateGeometry()
{
- get
+ var validationList = new List();
{
- return pointDataList;
+ foreach (Point2D point in Points)
+ {
+ foreach (Point2D point1 in Points)
+ {
+ if (point != point1)
+ {
+ var isValidated = false;
+ foreach (ValidationResult validatedItem in validationList)
+ {
+ if (validatedItem.Subject == point)
+ {
+ isValidated = true;
+ }
+ }
+
+ if (!isValidated)
+ {
+ if (Math.Abs(point.X - point1.X) < GeometryConstants.Accuracy &&
+ Math.Abs(point.Z - point1.Z) < GeometryConstants.Accuracy)
+ {
+ validationList.Add(new ValidationResult(ValidationResultType.Error,
+ point + " and " +
+ point1 + " values are same.",
+ point1));
+ }
+ }
+ }
+ }
+ }
}
+ if (Surfaces.Count < 1)
+ {
+ validationList.Add(new ValidationResult(ValidationResultType.Error, "No soil surface available.",
+ this));
+ }
+
+ return validationList.ToArray();
}
///
- /// Gets the newly effected points.
+ /// Deletes the point and the curves it belongs too.
///
- ///
- /// The newly effected points.
- ///
- public List NewlyEffectedPoints
+ /// The point.
+ public void DeletePointWithCurves(Point2D point)
{
- get
+ var curvesToDelete = new List();
+ foreach (GeometryCurve curve in Curves)
{
- return newlyEffectedPoints;
+ if (curve.ContainsPoint(point))
+ {
+ curvesToDelete.Add(curve);
+ }
}
+
+ foreach (GeometryCurve curveToDelete in curvesToDelete)
+ {
+ Curves.Remove(curveToDelete);
+ }
+
+ Points.Remove(point);
}
///
- /// gets the Curve data list.
+ /// Synchronizes the loops.
///
- ///
- /// The curves.
- ///
- public List Curves
+ public void SynchronizeLoops()
{
- get
+ DeleteAllLoops();
+ foreach (GeometrySurface surface in Surfaces)
{
- return curveDataList;
+ // #Bka: as real donuts (or holes in geom) are not allowed, there can be no innerloop that
+ // is NOT an outerloop for another surface. So no need to sync innerloops.
+ if (surface.OuterLoop != null && surface.OuterLoop.IsLoop())
+ {
+ Loops.Add(surface.OuterLoop);
+ }
}
}
///
- /// Gets the newly effected curves.
+ /// Returns a that represents this instance.
///
- ///
- /// The newly effected curves.
- ///
- public List NewlyEffectedCurves
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
{
- get
+ return LocalizationManager.GetTranslatedText(this, "GeometryData");
+ }
+
+ ///
+ /// Removes the boundary curves from the given list of curves.
+ /// The boundaries themselves are determined from the given geometry
+ ///
+ /// The curves.
+ /// The geometry (as string).
+ private static void RemoveBoundaryCurves(List curves, GeometryPointString geometry)
+ {
+ double minX = geometry.GetMinX();
+ double maxX = geometry.GetMaxX();
+ double minZ = geometry.GetMinZ();
+ foreach (GeometryCurve curve in curves.ToArray())
{
- return newlyEffectedCurves;
+ if (IsBoundaryCurve(curve, minX, maxX, minZ))
+ {
+ curves.Remove(curve);
+ }
}
}
///
- /// gets the Loop data list.
+ /// get all geometrypoints from all geometrycurves
///
- ///
- /// The loops.
- ///
- public List Loops
+ ///
+ ///
+ private static GeometryPointString GetAllPointsFromCurveList(List curveList)
{
- get
+ var result = new GeometryPointString();
+ foreach (GeometryCurve curve in curveList)
{
- return loopDataList;
+ result.CalcPoints.Add(curve.EndPoint);
+ result.CalcPoints.Add(curve.HeadPoint);
}
+
+ return result;
}
///
- /// gets the Surface data list.
+ /// Gets next connected top curve in list of curves
///
- public List Surfaces
+ ///
+ ///
+ ///
+ ///
+ private GeometryCurve GetNextTopCurve(GeometryCurve curve, List boundaryCurves,
+ List excludedCurves)
{
- get
+ // if current curve ends on right limit then that must have been the last one so stop the search
+ if (Math.Abs(curve.HeadPoint.X - Right) < GeometryConstants.Accuracy || Math.Abs(curve.EndPoint.X - Right) < GeometryConstants.Accuracy)
{
- return surfaceDataList;
+ return null;
}
+
+ foreach (GeometryCurve geometryCurve in boundaryCurves)
+ {
+ if (geometryCurve != curve && !excludedCurves.Contains(geometryCurve))
+ {
+ if (AreConnected(curve, geometryCurve))
+ {
+ return geometryCurve;
+ }
+ }
+ }
+
+ return null;
}
+ ///
+ /// create a copy of the curves
+ ///
+ ///
+ ///
+ private List GetCurvesCopy(List bCurves)
+ {
+ var outerloopCurvesCopy = new List(bCurves);
+ return outerloopCurvesCopy;
+ }
+
+ ///
+ /// Create a surface line from points in curves
+ /// Precondition is that the curves start at the left boundary and are connected left to right
+ /// (not neccesarily neat head-end)
+ ///
+ ///
+ ///
+ private void CreateSurfaceLinePointString(List curves)
+ {
+ surfaceLine.CalcPoints.Clear();
+
+ if (curves.Count == 0)
+ {
+ return;
+ }
+
+ var reversed = false;
+ // The headpoint of the first curve must be on the left boundary otherwise the
+ // surface line will be in the wrong order. So make sure.
+ if (!(Math.Abs(curves[0].HeadPoint.X - Left) < GeometryConstants.Accuracy))
+ {
+ curves[0].Reverse();
+ reversed = true;
+ }
+
+ foreach (GeometryCurve curve in curves)
+ {
+ if (!surfaceLine.CalcPoints.Contains(curve.HeadPoint))
+ {
+ surfaceLine.CalcPoints.Add(curve.HeadPoint);
+ }
+
+ if (!surfaceLine.CalcPoints.Contains(curve.EndPoint))
+ {
+ surfaceLine.CalcPoints.Add(curve.EndPoint);
+ }
+ }
+
+ if (reversed)
+ {
+ curves[0].Reverse();
+ }
+ }
+
+ ///
+ /// get curves of the top side of the outerloop, vertical curves are omitted
+ ///
+ ///
+ ///
+ private List GetTopCurves(List curves)
+ {
+ GeometryCurve topCurve;
+ // Remove all curves on the geometry boundary
+ if (GetLeftPoints().Count > 0 && GetRightPoints().Count > 0)
+ {
+ foreach (GeometryCurve curve in curves.ToArray())
+ {
+ if (IsBoundaryCurve(curve, Left, Right, Bottom))
+ {
+ curves.Remove(curve);
+ }
+ }
+
+ // Make sure you start with topcurve = curve at the left top position
+ topCurve = curves.Where(g => Math.Abs(g.HeadPoint.X - Left) < GeometryConstants.Accuracy ||
+ Math.Abs(g.EndPoint.X - Left) < GeometryConstants.Accuracy)
+ .OrderByDescending(c => c.HeadPoint.Z)
+ .FirstOrDefault();
+ }
+ else
+ {
+ GeometryPointString gString = GetAllPointsFromCurveList(curves);
+ RemoveBoundaryCurves(curves, gString);
+ double minX = gString.GetMinX();
+ // Make sure you start with topcurve = curve at the left top position
+ topCurve =
+ curves.Where(g => Math.Abs(g.HeadPoint.X - minX) < GeometryConstants.Accuracy ||
+ Math.Abs(g.EndPoint.X - minX) < GeometryConstants.Accuracy).OrderByDescending(c => c.HeadPoint.Z).FirstOrDefault();
+ }
+
+ var topCurvesLocal = new List();
+ while (topCurve != null)
+ {
+ topCurvesLocal.Add(topCurve);
+ topCurve = GetNextTopCurve(topCurve, curves, topCurvesLocal);
+ }
+
+ return topCurvesLocal;
+ }
+
+ ///
+ /// Indicates whether a curve is on the boundary of the geometry
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static bool IsBoundaryCurve(GeometryCurve curve, double minX, double maxX, double minZ)
+ {
+ if (Math.Abs(curve.HeadPoint.X - minX) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.X - minX) < GeometryConstants.Accuracy)
+ {
+ return true;
+ }
+
+ if (Math.Abs(curve.HeadPoint.X - maxX) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.X - maxX) < GeometryConstants.Accuracy)
+ {
+ return true;
+ }
+
+ if (Math.Abs(curve.HeadPoint.Z - minZ) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.Z - minZ) < GeometryConstants.Accuracy)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool AreConnected(GeometryCurve curve1, GeometryCurve curve2)
+ {
+ return (curve1.HeadPoint == curve2.HeadPoint || curve1.HeadPoint == curve2.EndPoint ||
+ curve1.EndPoint == curve2.HeadPoint || curve1.EndPoint == curve2.EndPoint);
+ }
+
+ ///
+ /// Updates the line at the top of the geometry
+ ///
+ private void UpdateSurfaceLine()
+ {
+ if (updatingSurfaceLine)
+ {
+ return;
+ }
+
+ updatingSurfaceLine = true;
+
+ List bCurves = GetBoundaryCurves();
+ if (bCurves.Count == 0)
+ {
+ surfaceLine.CalcPoints.Clear();
+ }
+
+ List curvesCopy = GetCurvesCopy(bCurves);
+ List curves = GetTopCurves(curvesCopy);
+ CreateSurfaceLinePointString(curves);
+
+ updatingSurfaceLine = false;
+ surfaceLine.SyncPoints();
+ }
+
+ #region properties
+
+ ///
+ /// Gets the points.
+ ///
+ ///
+ /// The points.
+ ///
+ [Validate]
+ public List Points { get; } = new List();
+
+ ///
+ /// Gets the newly effected points.
+ ///
+ ///
+ /// The newly effected points.
+ ///
+ public List NewlyEffectedPoints { get; } = new List();
+
+ ///
+ /// gets the Curve data list.
+ ///
+ ///
+ /// The curves.
+ ///
+ public List Curves { get; } = new List();
+
+ ///
+ /// Gets the newly effected curves.
+ ///
+ ///
+ /// The newly effected curves.
+ ///
+ public List NewlyEffectedCurves { get; } = new List();
+
+ ///
+ /// gets the Loop data list.
+ ///
+ ///
+ /// The loops.
+ ///
+ public List Loops { get; } = new List();
+
+ ///
+ /// gets the Surface data list.
+ ///
+ public List Surfaces { get; } = new List();
+
public void RegenerateGeometry()
{
if (isRegeneratingGeometry)
@@ -156,22 +450,24 @@
{
geometryGenerator = new GeometryGenerator(this);
}
+
lock (this)
{
SynchronizeLoops();
RemoveDoublesFromNewlyEffectedPointsAndCurves();
Curves.Clear();
Points.Clear();
- Points.AddRange(newlyEffectedPoints);
- Curves.AddRange(newlyEffectedCurves);
+ Points.AddRange(NewlyEffectedPoints);
+ Curves.AddRange(NewlyEffectedCurves);
geometryGenerator.GenerateGeometry();
- newlyEffectedPoints.Clear();
- newlyEffectedCurves.Clear();
+ NewlyEffectedPoints.Clear();
+ NewlyEffectedCurves.Clear();
UpdateSurfaceLine();
SynchronizeLoops();
}
+
isRegeneratingGeometry = false;
}
@@ -249,62 +545,32 @@
///
/// The left.
///
- public double Left
- {
- get
- {
- return left;
- }
- set
- {
- left = value;
- }
- }
+ public double Left { get; set; } = GeometryConstants.DefaultLeftLimitGeometry;
///
/// Gets or sets the right.
///
///
/// The right.
///
- public double Right
- {
- get
- {
- return right;
- }
- set
- {
- right = value;
- }
- }
+ public double Right { get; set; } = GeometryConstants.DefaultRightLimitGeometry;
///
/// Gets or sets the bottom.
///
///
/// The bottom.
///
- public double Bottom
- {
- get
- {
- return bottom;
- }
- set
- {
- bottom = value;
- }
- }
+ public double Bottom { get; set; } = GeometryConstants.DefaultBottomLimitGeometry;
///
/// Removes the doubles from newly effected points and curves.
///
public void RemoveDoublesFromNewlyEffectedPointsAndCurves()
{
var pdel = new List();
- var par = newlyEffectedPoints.ToArray();
- for (int i = 0; i < par.Length; i++)
+ Point2D[] par = NewlyEffectedPoints.ToArray();
+ for (var i = 0; i < par.Length; i++)
{
for (int j = i; j < par.Length; j++)
{
@@ -317,29 +583,32 @@
}
}
}
- foreach (var point in pdel)
+
+ foreach (Point2D point in pdel)
{
- newlyEffectedPoints.Remove(point);
+ NewlyEffectedPoints.Remove(point);
}
var cdel = new List();
- var car = newlyEffectedCurves.ToArray();
+ GeometryCurve[] car = NewlyEffectedCurves.ToArray();
// First remove all "illegal" newlyeffected curves
- for (int i = 0; i < car.Length; i++)
+ for (var i = 0; i < car.Length; i++)
{
if (car[i].HeadPoint == null || car[i].EndPoint == null || car[i].HeadPoint.LocationEquals(car[i].EndPoint))
{
cdel.Add(car[i]);
}
}
- foreach (var curve in cdel)
+
+ foreach (GeometryCurve curve in cdel)
{
- newlyEffectedCurves.Remove(curve);
+ NewlyEffectedCurves.Remove(curve);
}
+
// then remove all real doubles
- var car2 = newlyEffectedCurves.ToArray();
+ GeometryCurve[] car2 = NewlyEffectedCurves.ToArray();
cdel.Clear();
- for (int i = 0; i < car2.Length; i++)
+ for (var i = 0; i < car2.Length; i++)
{
for (int j = i; j < car2.Length; j++)
{
@@ -352,9 +621,10 @@
}
}
}
- foreach (var curve in cdel)
+
+ foreach (GeometryCurve curve in cdel)
{
- newlyEffectedCurves.Remove(curve);
+ NewlyEffectedCurves.Remove(curve);
}
}
@@ -364,7 +634,7 @@
///
private List GetLeftPoints()
{
- var geometryPoints = pointDataList.Where(gp => Math.Abs(gp.X - Left) < GeometryConstants.Accuracy).ToList();
+ List geometryPoints = Points.Where(gp => Math.Abs(gp.X - Left) < GeometryConstants.Accuracy).ToList();
return geometryPoints;
}
@@ -374,7 +644,7 @@
///
private List GetRightPoints()
{
- var geometryPoints = pointDataList.Where(point => Math.Abs(point.X - Right) < GeometryConstants.Accuracy).ToList();
+ List geometryPoints = Points.Where(point => Math.Abs(point.X - Right) < GeometryConstants.Accuracy).ToList();
return geometryPoints;
}
@@ -399,21 +669,22 @@
///
public void Rebox()
{
- double xMin = double.MaxValue;
- double xMax = double.MinValue;
- double zMin = double.MaxValue;
- double zMax = double.MinValue;
+ var xMin = double.MaxValue;
+ var xMax = double.MinValue;
+ var zMin = double.MaxValue;
+ var zMax = double.MinValue;
- foreach (var point in pointDataList)
+ foreach (Point2D point in Points)
{
xMin = Math.Min(point.X, xMin);
xMax = Math.Max(point.X, xMax);
zMin = Math.Min(point.Z, zMin);
zMax = Math.Max(point.Z, zMax);
}
- bottom = zMin;
- left = xMin;
- right = xMax;
+
+ Bottom = zMin;
+ Left = xMin;
+ Right = xMax;
}
#endregion
@@ -425,11 +696,11 @@
///
public void Clear()
{
- pointDataList.Clear();
- curveDataList.Clear();
- surfaceDataList.Clear();
- newlyEffectedPoints.Clear();
- newlyEffectedCurves.Clear();
+ Points.Clear();
+ Curves.Clear();
+ Surfaces.Clear();
+ NewlyEffectedPoints.Clear();
+ NewlyEffectedCurves.Clear();
}
///
@@ -443,7 +714,7 @@
#endregion
#region other functions
-
+
#region calculation function
///
@@ -457,16 +728,17 @@
/// Intersection coordinates
/// True if lines intersect each other
private static bool CheckIfIntersectStricktly(Point2D beginPoint1, Point2D endPoint1,
- Point2D beginPoint2, Point2D endPoint2,
- ref Point2D intersect)
+ Point2D beginPoint2, Point2D endPoint2,
+ ref Point2D intersect)
{
Point2D ip;
- var res = Routines2D.DetermineIf2DLinesIntersectStrickly(beginPoint1, endPoint1,
- beginPoint2, endPoint2, out ip);
+ LineIntersection res = Routines2D.DetermineIf2DLinesIntersectStrickly(beginPoint1, endPoint1,
+ beginPoint2, endPoint2, out ip);
if (ip != null)
{
intersect = ip;
}
+
return res == LineIntersection.Intersects;
}
@@ -488,12 +760,13 @@
var p3 = new Point2D(aL2P1[0], aL2P1[1]);
var p4 = new Point2D(aL2P2[0], aL2P2[1]);
var ip = new Point2D();
- var res = CheckIfIntersectStricktly(p1, p2, p3, p4, ref ip);
+ bool res = CheckIfIntersectStricktly(p1, p2, p3, p4, ref ip);
if (res)
{
aIntersect[0] = ip.X;
aIntersect[1] = ip.Z;
}
+
return res;
}
@@ -506,7 +779,7 @@
{
double surfaceHeight = -Double.MaxValue;
double[] intersectionPoints = IntersectLayers(x, -9999);
- for (int i = 0; i < intersectionPoints.Length; i++)
+ for (var i = 0; i < intersectionPoints.Length; i++)
{
if (intersectionPoints[i] > surfaceHeight)
{
@@ -530,24 +803,26 @@
throw new Exception("Empty Surfaces in IntersectLayers");
}
- var beginPoint2 = new Point2D()
+ var beginPoint2 = new Point2D
{
- X = aXCoord, Z = aZCoord
+ X = aXCoord,
+ Z = aZCoord
};
- var endPoint2 = new Point2D()
+ var endPoint2 = new Point2D
{
- X = aXCoord, Z = 99999
+ X = aXCoord,
+ Z = 99999
};
var referencePoint = new Point2D();
var intersections = new List();
- for (int surfaceIndexLocal = 0; surfaceIndexLocal < Surfaces.Count; surfaceIndexLocal++)
+ for (var surfaceIndexLocal = 0; surfaceIndexLocal < Surfaces.Count; surfaceIndexLocal++)
{
- var outerLoopCurveList = Surfaces[surfaceIndexLocal].OuterLoop.CurveList;
- for (int curveIndexLocal = 0; curveIndexLocal < outerLoopCurveList.Count; curveIndexLocal++)
+ List outerLoopCurveList = Surfaces[surfaceIndexLocal].OuterLoop.CurveList;
+ for (var curveIndexLocal = 0; curveIndexLocal < outerLoopCurveList.Count; curveIndexLocal++)
{
//Check for each curve if it intersects with x coordinate
Point2D beginPoint1 = outerLoopCurveList[curveIndexLocal].GetHeadPoint(CurveDirection.Forward);
@@ -570,7 +845,7 @@
return intersections.ToArray();
}
-
+
///
/// Returns a list of boundary curves. These are curves which are used in only one surface so they have to be on a boundary (inner or outer)
///
@@ -579,7 +854,7 @@
{
var curves = new List();
var loops = new List();
- foreach (var surface in Surfaces)
+ foreach (GeometrySurface surface in Surfaces)
{
loops.Add(surface.OuterLoop);
// Todo Ask Rob/Tom: when a real "doughnut" type surface (so hole in the center) is permitted, adding the innerloops here will
@@ -589,9 +864,9 @@
loops.AddRange(surface.InnerLoops);
}
- foreach (var loop in loops)
+ foreach (GeometryLoop loop in loops)
{
- foreach (var curve in loop.CurveList)
+ foreach (GeometryCurve curve in loop.CurveList)
{
if (curves.Contains(curve))
{
@@ -604,347 +879,14 @@
}
}
}
+
return curves;
}
#endregion
-
#endregion
#endregion
-
- ///
- /// Ordered list of all geometry points at the surface
- ///
- public virtual GeometryPointString SurfaceLine
- {
- get
- {
- if (surfaceLine.CalcPoints.Count == 0 && pointDataList.Count > 0)
- {
- UpdateSurfaceLine();
- }
- return surfaceLine;
- }
- }
-
- ///
- /// Checks geometry for loose curves and AutoRegeneration
- ///
- ///
- [Validate]
- public ValidationResult[] ValidateGeometry()
- {
- var validationList = new List();
- {
- foreach (var point in Points)
- {
- foreach (var point1 in Points)
- {
- if (point != point1)
- {
- bool isValidated = false;
- foreach (var validatedItem in validationList)
- {
- if (validatedItem.Subject == point)
- {
- isValidated = true;
- }
- }
- if (!isValidated)
- {
- if (Math.Abs(point.X - point1.X) < GeometryConstants.Accuracy &&
- Math.Abs(point.Z - point1.Z) < GeometryConstants.Accuracy)
- {
- validationList.Add(new ValidationResult(ValidationResultType.Error,
- point + " and " +
- point1 + " values are same.",
- point1));
- }
- }
- }
- }
- }
- }
- if (Surfaces.Count < 1)
- {
- validationList.Add(new ValidationResult(ValidationResultType.Error, "No soil surface available.",
- this));
- }
- return validationList.ToArray();
- }
-
- ///
- /// Deletes the point and the curves it belongs too.
- ///
- /// The point.
- public void DeletePointWithCurves(Point2D point)
- {
- var curvesToDelete = new List();
- foreach (var curve in Curves)
- {
- if (curve.ContainsPoint(point))
- {
- curvesToDelete.Add(curve);
- }
- }
-
- foreach (var curveToDelete in curvesToDelete)
- {
- Curves.Remove(curveToDelete);
- }
-
- Points.Remove(point);
- }
-
- ///
- /// Removes the boundary curves from the given list of curves.
- /// The boundaries themselves are determined from the given geometry
- ///
- /// The curves.
- /// The geometry (as string).
- private static void RemoveBoundaryCurves(List curves, GeometryPointString geometry)
- {
- var minX = geometry.GetMinX();
- var maxX = geometry.GetMaxX();
- var minZ = geometry.GetMinZ();
- foreach (var curve in curves.ToArray())
- {
- if (IsBoundaryCurve(curve, minX, maxX, minZ))
- {
- curves.Remove(curve);
- }
- }
- }
-
- ///
- /// get all geometrypoints from all geometrycurves
- ///
- ///
- ///
- private static GeometryPointString GetAllPointsFromCurveList(List curveList)
- {
- var result = new GeometryPointString();
- foreach (var curve in curveList)
- {
- result.CalcPoints.Add(curve.EndPoint);
- result.CalcPoints.Add(curve.HeadPoint);
- }
- return result;
- }
-
- ///
- /// Gets next connected top curve in list of curves
- ///
- ///
- ///
- ///
- ///
- private GeometryCurve GetNextTopCurve(GeometryCurve curve, List boundaryCurves,
- List excludedCurves)
- {
- // if current curve ends on right limit then that must have been the last one so stop the search
- if (Math.Abs(curve.HeadPoint.X - Right) < GeometryConstants.Accuracy || Math.Abs(curve.EndPoint.X - Right) < GeometryConstants.Accuracy)
- {
- return null;
- }
- foreach (var geometryCurve in boundaryCurves)
- {
- if (geometryCurve != curve && !excludedCurves.Contains(geometryCurve))
- {
- if (AreConnected(curve, geometryCurve))
- {
- return geometryCurve;
- }
- }
- }
- return null;
- }
-
- ///
- /// Returns a that represents this instance.
- ///
- ///
- /// A that represents this instance.
- ///
- public override string ToString()
- {
- return LocalizationManager.GetTranslatedText(this, "GeometryData");
- }
-
- ///
- /// Synchronizes the loops.
- ///
- public void SynchronizeLoops()
- {
- DeleteAllLoops();
- foreach (var surface in Surfaces)
- {
- // #Bka: as real donuts (or holes in geom) are not allowed, there can be no innerloop that
- // is NOT an outerloop for another surface. So no need to sync innerloops.
- if (surface.OuterLoop != null && surface.OuterLoop.IsLoop())
- {
- loopDataList.Add(surface.OuterLoop);
- }
- }
- }
-
- ///
- /// create a copy of the curves
- ///
- ///
- ///
- private List GetCurvesCopy(List bCurves)
- {
- var outerloopCurvesCopy = new List(bCurves);
- return outerloopCurvesCopy;
- }
-
- ///
- /// Create a surface line from points in curves
- /// Precondition is that the curves start at the left boundary and are connected left to right
- /// (not neccesarily neat head-end)
- ///
- ///
- ///
- private void CreateSurfaceLinePointString(List curves)
- {
- surfaceLine.CalcPoints.Clear();
-
- if (curves.Count == 0)
- {
- return;
- }
-
- var reversed = false;
- // The headpoint of the first curve must be on the left boundary otherwise the
- // surface line will be in the wrong order. So make sure.
- if (!(Math.Abs(curves[0].HeadPoint.X - Left) < GeometryConstants.Accuracy))
- {
- curves[0].Reverse();
- reversed = true;
- }
-
- foreach (var curve in curves)
- {
- if (!surfaceLine.CalcPoints.Contains(curve.HeadPoint))
- {
- surfaceLine.CalcPoints.Add(curve.HeadPoint);
- }
- if (!surfaceLine.CalcPoints.Contains(curve.EndPoint))
- {
- surfaceLine.CalcPoints.Add(curve.EndPoint);
- }
- }
-
- if (reversed)
- {
- curves[0].Reverse();
- }
- }
-
- ///
- /// get curves of the top side of the outerloop, vertical curves are omitted
- ///
- ///
- ///
- private List GetTopCurves(List curves)
- {
- GeometryCurve topCurve;
- // Remove all curves on the geometry boundary
- if (GetLeftPoints().Count > 0 && GetRightPoints().Count > 0)
- {
- foreach (var curve in curves.ToArray())
- {
- if (IsBoundaryCurve(curve, Left, Right, Bottom))
- {
- curves.Remove(curve);
- }
- }
- // Make sure you start with topcurve = curve at the left top position
- topCurve = curves.Where(g => Math.Abs(g.HeadPoint.X - Left) < GeometryConstants.Accuracy ||
- Math.Abs(g.EndPoint.X - Left) < GeometryConstants.Accuracy)
- .OrderByDescending(c => c.HeadPoint.Z)
- .FirstOrDefault();
- }
- else
- {
- GeometryPointString gString = GetAllPointsFromCurveList(curves);
- RemoveBoundaryCurves(curves, gString);
- var minX = gString.GetMinX();
- // Make sure you start with topcurve = curve at the left top position
- topCurve =
- curves.Where(g => Math.Abs(g.HeadPoint.X - minX) < GeometryConstants.Accuracy ||
- Math.Abs(g.EndPoint.X - minX) < GeometryConstants.Accuracy).OrderByDescending(c => c.HeadPoint.Z).FirstOrDefault();
- }
- var topCurvesLocal = new List();
- while (topCurve != null)
- {
- topCurvesLocal.Add(topCurve);
- topCurve = GetNextTopCurve(topCurve, curves, topCurvesLocal);
- }
-
- return topCurvesLocal;
- }
-
- ///
- /// Indicates whether a curve is on the boundary of the geometry
- ///
- ///
- ///
- ///
- ///
- ///
- private static bool IsBoundaryCurve(GeometryCurve curve, double minX, double maxX, double minZ)
- {
- if (Math.Abs(curve.HeadPoint.X - minX) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.X - minX) < GeometryConstants.Accuracy)
- {
- return true;
- }
-
- if (Math.Abs(curve.HeadPoint.X - maxX) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.X - maxX) < GeometryConstants.Accuracy)
- {
- return true;
- }
-
- if (Math.Abs(curve.HeadPoint.Z - minZ) < GeometryConstants.Accuracy && Math.Abs(curve.EndPoint.Z - minZ) < GeometryConstants.Accuracy)
- {
- return true;
- }
-
- return false;
- }
-
- private bool AreConnected(GeometryCurve curve1, GeometryCurve curve2)
- {
- return (curve1.HeadPoint == curve2.HeadPoint || curve1.HeadPoint == curve2.EndPoint ||
- curve1.EndPoint == curve2.HeadPoint || curve1.EndPoint == curve2.EndPoint);
- }
-
- ///
- /// Updates the line at the top of the geometry
- ///
- private void UpdateSurfaceLine()
- {
- if (updatingSurfaceLine)
- {
- return;
- }
-
- updatingSurfaceLine = true;
-
- var bCurves = GetBoundaryCurves();
- if (bCurves.Count == 0)
- {
- surfaceLine.CalcPoints.Clear();
- }
- var curvesCopy = GetCurvesCopy(bCurves);
- var curves = GetTopCurves(curvesCopy);
- CreateSurfaceLinePointString(curves);
-
- updatingSurfaceLine = false;
- surfaceLine.SyncPoints();
- }
}
}
\ No newline at end of file