Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 4052) @@ -23,906 +23,905 @@ using System.Collections.Generic; using System.Diagnostics; -namespace Deltares.DamEngine.Data.Geometry +namespace Deltares.DamEngine.Data.Geometry; + +// ---------------------------------------------------------- +// The main geometry regeneration manager +public class GeometryGenerator { - // ---------------------------------------------------------- - // The main geometry regeneration manager - public class GeometryGenerator - { - // aValue1 list that collects all surfaces that are at the right and left of effected curves (above) - // will be used to re-assign after regeneration + // aValue1 list that collects all surfaces that are at the right and left of effected curves (above) + // will be used to re-assign after regeneration - private readonly Dictionary geometryCurveForwardsIsUsed = new Dictionary(); - private readonly Dictionary geometryCurveReversedIsUsed = new Dictionary(); - private readonly GeometryData geometryData; + private readonly Dictionary geometryCurveForwardsIsUsed = new Dictionary(); + private readonly Dictionary geometryCurveReversedIsUsed = new Dictionary(); + private readonly GeometryData geometryData; - private readonly Dictionary> geometryLoopDirections = new Dictionary>(); + private readonly Dictionary> geometryLoopDirections = new Dictionary>(); // private readonly List intersectedCurveList = new List(); - private readonly List newlyDetectedSurfaceList = new List(); + private readonly List newlyDetectedSurfaceList = new List(); - /// - /// Regenerates the geometry. - /// - public GeometryGenerator(GeometryData aGeometryData) - { - geometryData = aGeometryData; - } + /// + /// Regenerates the geometry. + /// + public GeometryGenerator(GeometryData aGeometryData) + { + geometryData = aGeometryData; + } - /// - /// Regenerates the geometry. - /// - public void GenerateGeometry() + /// + /// Regenerates the geometry. + /// + public void GenerateGeometry() + { + FilterOutDoublePoints(); + + SetupCurveSurfaceAssociations(); + + var firstRegeneration = true; + + while (true) { - FilterOutDoublePoints(); + // break up all curves at intersections + //intersectedCurveList.Clear(); + //RegenerateAllCurvesIntersection(); Only add if really needed - SetupCurveSurfaceAssociations(); + newlyDetectedSurfaceList.Clear(); + geometryLoopDirections.Clear(); - var firstRegeneration = true; + int curvesCount = geometryData.Curves.Count; - while (true) + // initialise IsUsed of all curves to false + for (var index1 = 0; index1 < curvesCount; index1++) { - // break up all curves at intersections - //intersectedCurveList.Clear(); - //RegenerateAllCurvesIntersection(); Only add if really needed + SetIsUsed(geometryData.Curves[index1], CurveDirection.Forward, false); + SetIsUsed(geometryData.Curves[index1], CurveDirection.Reverse, false); + } - newlyDetectedSurfaceList.Clear(); - geometryLoopDirections.Clear(); + // detect surfaces... the plaxis algorithm + int result = DetectSurfaces(firstRegeneration); - int curvesCount = geometryData.Curves.Count; + // clear the effected & intersected curve list + //intersectedCurveList.Clear(); only when really needed - // initialise IsUsed of all curves to false - for (var index1 = 0; index1 < curvesCount; index1++) + if (result < 0) + { + if (!firstRegeneration) { - SetIsUsed(geometryData.Curves[index1], CurveDirection.Forward, false); - SetIsUsed(geometryData.Curves[index1], CurveDirection.Reverse, false); + break; } + } + else + { + break; + } - // detect surfaces... the plaxis algorithm - int result = DetectSurfaces(firstRegeneration); + firstRegeneration = false; + } + } - // clear the effected & intersected curve list - //intersectedCurveList.Clear(); only when really needed + /// + /// Adds the curve to the list in given direction. + /// + /// + /// + /// + /// + private bool AddCurve(GeometryCurve aCurve, CurveDirection aDirection, GeometryLoop aEditedLoop) + { + if (FindCurveIndex(aEditedLoop, aCurve, aDirection) > -1) + { + return false; + } - if (result < 0) - { - if (!firstRegeneration) - { - break; - } - } - else - { - break; - } + aEditedLoop.CurveList.Add(aCurve); + if (!geometryLoopDirections.ContainsKey(aEditedLoop)) + { + geometryLoopDirections.Add(aEditedLoop, new List()); + } - firstRegeneration = false; - } + geometryLoopDirections[aEditedLoop].Add(aDirection); + return true; + } + + // ------------------------------------------------------------------------------------- + // Loop Detection (Surface Creation) Algorithm from Plaxis + + /// + /// Creates the surface. + /// + /// a loop. + /// + private GeometrySurface CreateSurface(GeometryLoop aLoop) + { + if (aLoop.IsLoop() && aLoop.HasArea()) + { + var newSurface = new GeometrySurface(); + //newSurface.SetOuterLoop(aLoop); #Bka: replaced with + newSurface.OuterLoop = aLoop; + geometryData.Surfaces.Add(newSurface); + return newSurface; } - /// - /// Adds the curve to the list in given direction. - /// - /// - /// - /// - /// - private bool AddCurve(GeometryCurve aCurve, CurveDirection aDirection, GeometryLoop aEditedLoop) + return null; + } + + /// + /// Finds the index of the curve. + /// + /// a geometry loop. + /// a curve. + /// a direction. + /// + private int FindCurveIndex(GeometryLoop aGeometryLoop, GeometryCurve aCurve, CurveDirection aDirection) + { + if (!aGeometryLoop.CurveList.Contains(aCurve)) { - if (FindCurveIndex(aEditedLoop, aCurve, aDirection) > -1) - { - return false; - } + return -1; + } - aEditedLoop.CurveList.Add(aCurve); - if (!geometryLoopDirections.ContainsKey(aEditedLoop)) + int curvesCount = aGeometryLoop.CurveList.Count; + + for (var index = 0; index < curvesCount; index++) + { + // Note Bka: Checking the direction does allow one curve to be added to ONE loop twice! + // This produces some strange surfaces (see LoopDetectionCase5) but that seems to be required + if (aGeometryLoop.CurveList[index] == aCurve && geometryLoopDirections[aGeometryLoop][index] == aDirection) { - geometryLoopDirections.Add(aEditedLoop, new List()); + return index; } - - geometryLoopDirections[aEditedLoop].Add(aDirection); - return true; } - // ------------------------------------------------------------------------------------- - // Loop Detection (Surface Creation) Algorithm from Plaxis + return -1; + } - /// - /// Creates the surface. - /// - /// a loop. - /// - private GeometrySurface CreateSurface(GeometryLoop aLoop) + /// + /// + /// + /// + /// + /// + private void SetIsUsed(GeometryCurve aCurve, CurveDirection aDirection, bool aValue) + { + if (aDirection == CurveDirection.Forward) { - if (aLoop.IsLoop() && aLoop.HasArea()) + if (!(geometryCurveForwardsIsUsed.ContainsKey(aCurve))) { - var newSurface = new GeometrySurface(); - //newSurface.SetOuterLoop(aLoop); #Bka: replaced with - newSurface.OuterLoop = aLoop; - geometryData.Surfaces.Add(newSurface); - return newSurface; + geometryCurveForwardsIsUsed.Add(aCurve, aValue); } + else + { + geometryCurveForwardsIsUsed[aCurve] = aValue; + } + } + else + { + if (!(geometryCurveReversedIsUsed.ContainsKey(aCurve))) + { + geometryCurveReversedIsUsed.Add(aCurve, aValue); + } + else + { + geometryCurveReversedIsUsed[aCurve] = aValue; + } + } + } - return null; + /// + /// + /// + /// + /// + /// + private bool GetIsUsed(GeometryCurve aCurve, CurveDirection aDirection) + { + if (aDirection == CurveDirection.Forward) + { + return geometryCurveForwardsIsUsed[aCurve]; } - /// - /// Finds the index of the curve. - /// - /// a geometry loop. - /// a curve. - /// a direction. - /// - private int FindCurveIndex(GeometryLoop aGeometryLoop, GeometryCurve aCurve, CurveDirection aDirection) + return geometryCurveReversedIsUsed[aCurve]; + } + + /// + /// Removes all double points, replaces them in curves and newlyeffectedpoints. + /// Also deletes "zero" curves (beginpoint = endpoint) also from surface loops and newlyeffectedcurrves + /// + private void FilterOutDoublePoints() + { + var doublePoints = new Dictionary(); + + // Make sure all points (as pointers) in curves are in the point list + foreach (GeometryCurve curve in geometryData.Curves) { - if (!aGeometryLoop.CurveList.Contains(aCurve)) + if (!geometryData.Points.Contains(curve.HeadPoint)) { - return -1; + geometryData.Points.Add(curve.HeadPoint); } - int curvesCount = aGeometryLoop.CurveList.Count; + if (!geometryData.Points.Contains(curve.EndPoint)) + { + geometryData.Points.Add(curve.EndPoint); + } + } - for (var index = 0; index < curvesCount; index++) + // find double points (by location!) in point list and register them with original + for (var i = 0; i < geometryData.Points.Count; i++) + { + for (var j = 0; j < i; j++) { - // Note Bka: Checking the direction does allow one curve to be added to ONE loop twice! - // This produces some strange surfaces (see LoopDetectionCase5) but that seems to be required - if (aGeometryLoop.CurveList[index] == aCurve && geometryLoopDirections[aGeometryLoop][index] == aDirection) + if (i != j && geometryData.Points[i].LocationEquals(geometryData.Points[j])) { - return index; + // register the double point and the original point + doublePoints[geometryData.Points[i]] = geometryData.Points[j]; + break; } } - - return -1; } - /// - /// - /// - /// - /// - /// - private void SetIsUsed(GeometryCurve aCurve, CurveDirection aDirection, bool aValue) + // replace double points in curves with originals + foreach (Point2D doublePoint in doublePoints.Keys) { - if (aDirection == CurveDirection.Forward) + foreach (GeometryCurve curve in geometryData.Curves) { - if (!(geometryCurveForwardsIsUsed.ContainsKey(aCurve))) + if (curve.HeadPoint == doublePoint) { - geometryCurveForwardsIsUsed.Add(aCurve, aValue); + curve.HeadPoint = doublePoints[doublePoint]; } - else + + if (curve.EndPoint == doublePoint) { - geometryCurveForwardsIsUsed[aCurve] = aValue; + curve.EndPoint = doublePoints[doublePoint]; } } - else + } + + // remove curves which have the same head as end point + foreach (GeometryCurve curve in geometryData.Curves.ToArray()) + { + if (curve.HeadPoint == curve.EndPoint) { - if (!(geometryCurveReversedIsUsed.ContainsKey(aCurve))) + geometryData.Curves.Remove(curve); + if (geometryData.NewlyEffectedCurves.Contains(curve)) { - geometryCurveReversedIsUsed.Add(aCurve, aValue); + geometryData.NewlyEffectedCurves.Remove(curve); } - else + + foreach (GeometrySurface surface in geometryData.Surfaces) { - geometryCurveReversedIsUsed[aCurve] = aValue; + surface.OuterLoop.CurveList.Remove(curve); + foreach (GeometryLoop loop in surface.InnerLoops) + { + loop.CurveList.Remove(curve); + } } } } - /// - /// - /// - /// - /// - /// - private bool GetIsUsed(GeometryCurve aCurve, CurveDirection aDirection) + // removing curves from loops in surfaces may have created invalid surfaces, remove those here + foreach (GeometrySurface surface in geometryData.Surfaces.ToArray()) { - if (aDirection == CurveDirection.Forward) + if (!surface.OuterLoop.HasArea()) { - return geometryCurveForwardsIsUsed[aCurve]; + geometryData.Surfaces.Remove(surface); } - - return geometryCurveReversedIsUsed[aCurve]; } - /// - /// Removes all double points, replaces them in curves and newlyeffectedpoints. - /// Also deletes "zero" curves (beginpoint = endpoint) also from surface loops and newlyeffectedcurrves - /// - private void FilterOutDoublePoints() + // remove double points from point list + foreach (Point2D point in doublePoints.Keys) { - var doublePoints = new Dictionary(); + geometryData.Points.Remove(point); - // Make sure all points (as pointers) in curves are in the point list - foreach (GeometryCurve curve in geometryData.Curves) + if (geometryData.NewlyEffectedPoints.Contains(point)) { - if (!geometryData.Points.Contains(curve.HeadPoint)) + geometryData.NewlyEffectedPoints.Remove(point); + if (!geometryData.NewlyEffectedPoints.Contains(doublePoints[point])) { - geometryData.Points.Add(curve.HeadPoint); + geometryData.NewlyEffectedPoints.Add(doublePoints[point]); } - - if (!geometryData.Points.Contains(curve.EndPoint)) - { - geometryData.Points.Add(curve.EndPoint); - } } + } + } - // find double points (by location!) in point list and register them with original - for (var i = 0; i < geometryData.Points.Count; i++) + private int DetectSurfaces(bool aFirstRegeneration) + { + try + { + // declare some variables + int curvesCount = geometryData.Curves.Count; + + var newLoopList = new List(); + var attachedCurveList = new List(); + + // start the first iteration + for (var index = 0; index < curvesCount * 2; index++) { - for (var j = 0; j < i; j++) + int curveIndex = index / 2; + // look for current curve + GeometryCurve currentCurve = geometryData.Curves[curveIndex]; + + if (currentCurve == null) { - if (i != j && geometryData.Points[i].LocationEquals(geometryData.Points[j])) - { - // register the double point and the original point - doublePoints[geometryData.Points[i]] = geometryData.Points[j]; - break; - } + continue; } - } - // replace double points in curves with originals - foreach (Point2D doublePoint in doublePoints.Keys) - { - foreach (GeometryCurve curve in geometryData.Curves) + // check the direction + CurveDirection currentCurveDirection; + if (index % 2 == 0) { - if (curve.HeadPoint == doublePoint) + if (GetIsUsed(currentCurve, CurveDirection.Forward)) { - curve.HeadPoint = doublePoints[doublePoint]; + continue; } - if (curve.EndPoint == doublePoint) - { - curve.EndPoint = doublePoints[doublePoint]; - } + currentCurveDirection = CurveDirection.Forward; // get the direction of the current curve } - } - - // remove curves which have the same head as end point - foreach (GeometryCurve curve in geometryData.Curves.ToArray()) - { - if (curve.HeadPoint == curve.EndPoint) + else { - geometryData.Curves.Remove(curve); - if (geometryData.NewlyEffectedCurves.Contains(curve)) + if (GetIsUsed(currentCurve, CurveDirection.Reverse)) { - geometryData.NewlyEffectedCurves.Remove(curve); + continue; } - foreach (GeometrySurface surface in geometryData.Surfaces) - { - surface.OuterLoop.CurveList.Remove(curve); - foreach (GeometryLoop loop in surface.InnerLoops) - { - loop.CurveList.Remove(curve); - } - } + currentCurveDirection = CurveDirection.Reverse; // get the direction of the current curve } - } - // removing curves from loops in surfaces may have created invalid surfaces, remove those here - foreach (GeometrySurface surface in geometryData.Surfaces.ToArray()) - { - if (!surface.OuterLoop.HasArea()) - { - geometryData.Surfaces.Remove(surface); - } - } + // create aValue1 new loop + var newLoop = new GeometryLoop(); - // remove double points from point list - foreach (Point2D point in doublePoints.Keys) - { - geometryData.Points.Remove(point); + //this.geometryData.Loops.Add(newLoop); + newLoopList.Add(newLoop); - if (geometryData.NewlyEffectedPoints.Contains(point)) - { - geometryData.NewlyEffectedPoints.Remove(point); - if (!geometryData.NewlyEffectedPoints.Contains(doublePoints[point])) - { - geometryData.NewlyEffectedPoints.Add(doublePoints[point]); - } - } - } - } + // initialise LoopBeginCurve + GeometryCurve loopBeginCurve = geometryData.Curves[curveIndex]; + CurveDirection loopBeginDirection = currentCurveDirection; - private int DetectSurfaces(bool aFirstRegeneration) - { - try - { - // declare some variables - int curvesCount = geometryData.Curves.Count; - - var newLoopList = new List(); - var attachedCurveList = new List(); - - // start the first iteration - for (var index = 0; index < curvesCount * 2; index++) + while (true) { - int curveIndex = index / 2; - // look for current curve - GeometryCurve currentCurve = geometryData.Curves[curveIndex]; + // set the IsUsed status + SetIsUsed(currentCurve, currentCurveDirection, true); - if (currentCurve == null) + // add the current curve to new loop + if (!AddCurve(currentCurve, currentCurveDirection, newLoop)) { - continue; + // the curve wasn't added bcos the curve-direction pair was already present in loop. + // problem case - break here, else we'd get aValue1 hang! + // Todo: Solve this problem + if (!aFirstRegeneration) + { + //TODO:Show error message box + break; + } + + return -1; } - // check the direction - CurveDirection currentCurveDirection; - if (index % 2 == 0) + Point2D curveEndPoint = currentCurve.GetEndPoint(currentCurveDirection); + attachedCurveList.Clear(); + var minAngle = 365.0; + var minIndex = 0; + + // find all the curves that are connected to the Current Curve at curveEndPoint + for (var index2 = 0; index2 < curvesCount; index2++) { - if (GetIsUsed(currentCurve, CurveDirection.Forward)) + GeometryCurve curve = geometryData.Curves[index2]; + if (curve.LocationEquals(currentCurve)) // lets not get the reverse direction of the current curve here { continue; } - currentCurveDirection = CurveDirection.Forward; // get the direction of the current curve + if (curve.HeadPoint == curveEndPoint) + { + attachedCurveList.Add(new DirectionCurve(curve, CurveDirection.Forward)); + } + else if (curve.EndPoint == curveEndPoint) + { + attachedCurveList.Add(new DirectionCurve(curve, CurveDirection.Reverse)); + } } - else + + if (attachedCurveList.Count == 0) // no curves found { - if (GetIsUsed(currentCurve, CurveDirection.Reverse)) + CurveDirection oppCurrentDirection = currentCurveDirection == CurveDirection.Forward ? CurveDirection.Reverse : CurveDirection.Forward; + // if the current curve is not used in the opposite direction, it is considered in the opposite direction + if (!GetIsUsed(currentCurve, oppCurrentDirection)) { + currentCurveDirection = oppCurrentDirection; continue; } - currentCurveDirection = CurveDirection.Reverse; // get the direction of the current curve + break; } - // create aValue1 new loop - var newLoop = new GeometryLoop(); - - //this.geometryData.Loops.Add(newLoop); - newLoopList.Add(newLoop); - - // initialise LoopBeginCurve - GeometryCurve loopBeginCurve = geometryData.Curves[curveIndex]; - CurveDirection loopBeginDirection = currentCurveDirection; - - while (true) + // we have aValue1 set of curves, find the one that turns right the most + if (attachedCurveList.Count > 1) { - // set the IsUsed status - SetIsUsed(currentCurve, currentCurveDirection, true); + minIndex = -1; - // add the current curve to new loop - if (!AddCurve(currentCurve, currentCurveDirection, newLoop)) - { - // the curve wasn't added bcos the curve-direction pair was already present in loop. - // problem case - break here, else we'd get aValue1 hang! - // Todo: Solve this problem - if (!aFirstRegeneration) - { - //TODO:Show error message box - break; - } + Point2D point1 = currentCurve.GetEndPoint(currentCurveDirection); + Point2D point2 = currentCurve.GetHeadPoint(currentCurveDirection); - return -1; - } - - Point2D curveEndPoint = currentCurve.GetEndPoint(currentCurveDirection); - attachedCurveList.Clear(); - var minAngle = 365.0; - var minIndex = 0; - - // find all the curves that are connected to the Current Curve at curveEndPoint - for (var index2 = 0; index2 < curvesCount; index2++) + for (var index2 = 0; index2 < attachedCurveList.Count; index2++) { - GeometryCurve curve = geometryData.Curves[index2]; - if (curve.LocationEquals(currentCurve)) // lets not get the reverse direction of the current curve here - { - continue; - } + var point3 = new Point2D(); + var point4 = new Point2D(); - if (curve.HeadPoint == curveEndPoint) - { - attachedCurveList.Add(new DirectionCurve(curve, CurveDirection.Forward)); - } - else if (curve.EndPoint == curveEndPoint) - { - attachedCurveList.Add(new DirectionCurve(curve, CurveDirection.Reverse)); - } - } + point3.X = attachedCurveList[index2].GetHeadPoint().X; + point3.Z = attachedCurveList[index2].GetHeadPoint().Z; + point4.X = attachedCurveList[index2].GetEndPoint().X; + point4.Z = attachedCurveList[index2].GetEndPoint().Z; - if (attachedCurveList.Count == 0) // no curves found - { - CurveDirection oppCurrentDirection = currentCurveDirection == CurveDirection.Forward ? CurveDirection.Reverse : CurveDirection.Forward; - // if the current curve is not used in the opposite direction, it is considered in the opposite direction - if (!GetIsUsed(currentCurve, oppCurrentDirection)) - { - currentCurveDirection = oppCurrentDirection; - continue; - } + double angle = Routines2D.FindAngle(point1, point2, point3, point4); - break; - } - - // we have aValue1 set of curves, find the one that turns right the most - if (attachedCurveList.Count > 1) - { - minIndex = -1; - - Point2D point1 = currentCurve.GetEndPoint(currentCurveDirection); - Point2D point2 = currentCurve.GetHeadPoint(currentCurveDirection); - - for (var index2 = 0; index2 < attachedCurveList.Count; index2++) + if (angle < minAngle) { - var point3 = new Point2D(); - var point4 = new Point2D(); - - point3.X = attachedCurveList[index2].GetHeadPoint().X; - point3.Z = attachedCurveList[index2].GetHeadPoint().Z; - point4.X = attachedCurveList[index2].GetEndPoint().X; - point4.Z = attachedCurveList[index2].GetEndPoint().Z; - - double angle = Routines2D.FindAngle(point1, point2, point3, point4); - - if (angle < minAngle) - { - minAngle = angle; - minIndex = index2; - } + minAngle = angle; + minIndex = index2; } } + } - DirectionCurve pickedDirectionCurve = attachedCurveList[minIndex]; + DirectionCurve pickedDirectionCurve = attachedCurveList[minIndex]; - if (pickedDirectionCurve.Curve == loopBeginCurve && pickedDirectionCurve.Direction == loopBeginDirection) - { - break; - } - - // assign the CurrentCurve from the picked one - currentCurve = pickedDirectionCurve.Curve; - currentCurveDirection = pickedDirectionCurve.Direction; + if (pickedDirectionCurve.Curve == loopBeginCurve && pickedDirectionCurve.Direction == loopBeginDirection) + { + break; } - } - // create surfaces! - return CreateSurfaces(newLoopList); + // assign the CurrentCurve from the picked one + currentCurve = pickedDirectionCurve.Curve; + currentCurveDirection = pickedDirectionCurve.Direction; + } } + + // create surfaces! + return CreateSurfaces(newLoopList); + } #if DEBUG - catch //(Exception ex) - { - //Todo:Show error msg box - //var lm = new LogMessage(LogMessageType.FatalError, this, "DetectSurfaces:" + ex.Message); - //LogManager.Add(lm); - return 0; - } + catch //(Exception ex) + { + //Todo:Show error msg box + //var lm = new LogMessage(LogMessageType.FatalError, this, "DetectSurfaces:" + ex.Message); + //LogManager.Add(lm); + return 0; + } #else catch { return 0; } #endif - } + } - private int CreateSurfaces(List aNewLoopList) - { - var newSurfacesGeoDtaObjectList = new List(); + private int CreateSurfaces(List aNewLoopList) + { + var newSurfacesGeoDtaObjectList = new List(); - int loopsCount = aNewLoopList.Count; - int curvesCount; - GeometrySurface newSurface; - var newSurfaceList = new List(); + int loopsCount = aNewLoopList.Count; + int curvesCount; + GeometrySurface newSurface; + var newSurfaceList = new List(); - for (var index = 0; index < loopsCount; index++) + for (var index = 0; index < loopsCount; index++) + { + GeometryLoop loop = aNewLoopList[index]; + curvesCount = loop.CurveList.Count; + + if (curvesCount < 2) // dont create aValue1 surface for loops that have less than 2 curves { - GeometryLoop loop = aNewLoopList[index]; - curvesCount = loop.CurveList.Count; + continue; + } - if (curvesCount < 2) // dont create aValue1 surface for loops that have less than 2 curves + if (curvesCount == 2) // if only 2 curves in loop, make sure they are distinct (non-repeated) + { + if (loop.CurveList[0] == loop.CurveList[1]) { continue; } + } - if (curvesCount == 2) // if only 2 curves in loop, make sure they are distinct (non-repeated) + if (!loop.IsLoop()) + { + continue; + } + + // if the loop is clockwise, create aValue1 surface + if (loop.IsClockWise() && !CheckIfLoopEnclosesOpenPolyline(loop)) + { + // TEMP: aVector1 mechanism to remember surfaces after Geometry Regeneration + // find the surface that is most repeated in the loop's in curves + newSurface = GetReassignmentSurfaceFromCurves(loop); + + // an existing surface has been found + if (newSurface != null) { - if (loop.CurveList[0] == loop.CurveList[1]) - { - continue; - } + newSurface = CreateSurface(loop); } - - if (!loop.IsLoop()) + else // no existing surface found from its comprising curves... create aValue1 brand new surface! { - continue; + newSurface = CreateSurface(loop); + newlyDetectedSurfaceList.Add(newSurface); // populate the newly detected surface list + newSurfacesGeoDtaObjectList.Add(newSurface); } - // if the loop is clockwise, create aValue1 surface - if (loop.IsClockWise() && !CheckIfLoopEnclosesOpenPolyline(loop)) + if (newSurface != null) { - // TEMP: aVector1 mechanism to remember surfaces after Geometry Regeneration - // find the surface that is most repeated in the loop's in curves - newSurface = GetReassignmentSurfaceFromCurves(loop); - - // an existing surface has been found - if (newSurface != null) - { - newSurface = CreateSurface(loop); - } - else // no existing surface found from its comprising curves... create aValue1 brand new surface! - { - newSurface = CreateSurface(loop); - newlyDetectedSurfaceList.Add(newSurface); // populate the newly detected surface list - newSurfacesGeoDtaObjectList.Add(newSurface); - } - - if (newSurface != null) - { - newSurfaceList.Add(newSurface); - AssignSurfaceAtLeftOrRightToCurves(newSurface); - } + newSurfaceList.Add(newSurface); + AssignSurfaceAtLeftOrRightToCurves(newSurface); } } + } - // clear the left and right surfaces for all curves (some curves will have redundant data) - curvesCount = geometryData.Curves.Count; - for (var index = 0; index < curvesCount; index++) - { - geometryData.Curves[index].SurfaceAtRight = null; - geometryData.Curves[index].SurfaceAtLeft = null; - } + // clear the left and right surfaces for all curves (some curves will have redundant data) + curvesCount = geometryData.Curves.Count; + for (var index = 0; index < curvesCount; index++) + { + geometryData.Curves[index].SurfaceAtRight = null; + geometryData.Curves[index].SurfaceAtLeft = null; + } - // for the new surfaces -- assign the left/right surfaces for comprising curves, and find inner loops - int surfacesCount = newSurfaceList.Count; - for (var index = 0; index < surfacesCount; index++) - { - newSurface = newSurfaceList[index]; - AssignSurfaceAtLeftOrRightToCurves(newSurface); - object newSurfaceObject = newSurface /*new object()*/; - CheckAndAddInnerLoops(ref newSurfaceObject); - //newSurface = (GeometrySurface)newSurfaceObject; - } + // for the new surfaces -- assign the left/right surfaces for comprising curves, and find inner loops + int surfacesCount = newSurfaceList.Count; + for (var index = 0; index < surfacesCount; index++) + { + newSurface = newSurfaceList[index]; + AssignSurfaceAtLeftOrRightToCurves(newSurface); + object newSurfaceObject = newSurface /*new object()*/; + CheckAndAddInnerLoops(ref newSurfaceObject); + //newSurface = (GeometrySurface)newSurfaceObject; + } - if (newSurfacesGeoDtaObjectList.Count > 0) - { - var lNewSurfaces = new List(); - GetNewlyDetectedSurfaces(ref lNewSurfaces); - } + if (newSurfacesGeoDtaObjectList.Count > 0) + { + var lNewSurfaces = new List(); + GetNewlyDetectedSurfaces(ref lNewSurfaces); + } - return surfacesCount; + return surfacesCount; + } + + /// + /// Checks if loop encloses open polyline. + /// + /// a loop. + /// + private bool CheckIfLoopEnclosesOpenPolyline(GeometryLoop aLoop) + { + int curvesCount = aLoop.CurveList.Count; + if (curvesCount < 3) + { + return true; } - /// - /// Checks if loop encloses open polyline. - /// - /// a loop. - /// - private bool CheckIfLoopEnclosesOpenPolyline(GeometryLoop aLoop) + for (var index = 0; index < curvesCount; index++) { - int curvesCount = aLoop.CurveList.Count; - if (curvesCount < 3) - { - return true; - } + GeometryCurve curve = aLoop.CurveList[index]; + CurveDirection direction = geometryLoopDirections[aLoop][index]; + var foundOppDirection = false; - for (var index = 0; index < curvesCount; index++) + for (var index1 = 0; index1 < curvesCount; index1++) { - GeometryCurve curve = aLoop.CurveList[index]; - CurveDirection direction = geometryLoopDirections[aLoop][index]; - var foundOppDirection = false; - - for (var index1 = 0; index1 < curvesCount; index1++) + if (index == index1) { - if (index == index1) - { - continue; - } - - if (aLoop.CurveList[index1] == curve && geometryLoopDirections[aLoop][index] != direction) - { - foundOppDirection = true; - break; - } + continue; } - if (!foundOppDirection) + if (aLoop.CurveList[index1] == curve && geometryLoopDirections[aLoop][index] != direction) { - return false; + foundOppDirection = true; + break; } } - return true; + if (!foundOppDirection) + { + return false; + } } - private GeometrySurface GetReassignmentSurfaceFromCurves(GeometryLoop aLoop) + return true; + } + + private GeometrySurface GetReassignmentSurfaceFromCurves(GeometryLoop aLoop) + { + GeometrySurface surface = null; + GeometrySurface reassignmentSurface = null; + int curvesCount = aLoop.CurveList.Count; + + if (!geometryLoopDirections.ContainsKey(aLoop)) { - GeometrySurface surface = null; - GeometrySurface reassignmentSurface = null; - int curvesCount = aLoop.CurveList.Count; + return null; + } - if (!geometryLoopDirections.ContainsKey(aLoop)) + for (var index = 0; index < curvesCount; index++) + { + GeometryCurve curve = aLoop.CurveList[index]; + if (geometryLoopDirections[aLoop][index] == CurveDirection.Forward) { - return null; + if (curve.SurfaceAtRight != null) + { + surface = curve.SurfaceAtRight; + } } + else + { + if (curve.SurfaceAtLeft != null) + { + surface = curve.SurfaceAtLeft; + } + } - for (var index = 0; index < curvesCount; index++) + if (surface == null) { - GeometryCurve curve = aLoop.CurveList[index]; + continue; + } + + var maxTimesSurfacesFound = 0; + var noTimesSurfaceFound = 0; + for (var index1 = 0; index1 < curvesCount; index1++) + { if (geometryLoopDirections[aLoop][index] == CurveDirection.Forward) { - if (curve.SurfaceAtRight != null) + if (curve.SurfaceAtRight == surface) { - surface = curve.SurfaceAtRight; + noTimesSurfaceFound++; } } else { - if (curve.SurfaceAtLeft != null) + if (curve.SurfaceAtLeft == surface) { - surface = curve.SurfaceAtLeft; + noTimesSurfaceFound++; } } + } - if (surface == null) - { - continue; - } + if (noTimesSurfaceFound > maxTimesSurfacesFound) + { + maxTimesSurfacesFound = noTimesSurfaceFound; + reassignmentSurface = surface; + } + } - var maxTimesSurfacesFound = 0; - var noTimesSurfaceFound = 0; - for (var index1 = 0; index1 < curvesCount; index1++) - { - if (geometryLoopDirections[aLoop][index] == CurveDirection.Forward) - { - if (curve.SurfaceAtRight == surface) - { - noTimesSurfaceFound++; - } - } - else - { - if (curve.SurfaceAtLeft == surface) - { - noTimesSurfaceFound++; - } - } - } + return reassignmentSurface; + } - if (noTimesSurfaceFound > maxTimesSurfacesFound) - { - maxTimesSurfacesFound = noTimesSurfaceFound; - reassignmentSurface = surface; - } - } + /// + /// Assigns the surface at left or right to its curves on the outerloop. This tells at which side of the curve the surface is present. + /// So after this, for each curve in the outerloop of this surface, it is known at which side the surface is located. + /// + /// The surface. + private void AssignSurfaceAtLeftOrRightToCurves(GeometrySurface surface) + { + GeometryLoop loop = surface.OuterLoop; + int curvesCount = loop.CurveList.Count; + var isClockwise = true; - return reassignmentSurface; + try + { + isClockwise = loop.IsClockWise(); } - - /// - /// Assigns the surface at left or right to its curves on the outerloop. This tells at which side of the curve the surface is present. - /// So after this, for each curve in the outerloop of this surface, it is known at which side the surface is located. - /// - /// The surface. - private void AssignSurfaceAtLeftOrRightToCurves(GeometrySurface surface) + catch (GeometryLoop.NotEnoughUniquePointsException e) { - GeometryLoop loop = surface.OuterLoop; - int curvesCount = loop.CurveList.Count; - var isClockwise = true; + Debug.WriteLine(e.Message); + } + catch (InvalidOperationException e) + { + Debug.WriteLine(e.Message); + } - try + for (var index = 0; index < curvesCount; index++) + { + if (isClockwise) { - isClockwise = loop.IsClockWise(); + if (geometryLoopDirections[loop][index] == CurveDirection.Forward) + { + loop.CurveList[index].SurfaceAtRight = surface; + } + else + { + loop.CurveList[index].SurfaceAtLeft = surface; + } } - catch (GeometryLoop.NotEnoughUniquePointsException e) + else { - Debug.WriteLine(e.Message); - } - catch (InvalidOperationException e) - { - Debug.WriteLine(e.Message); - } - - for (var index = 0; index < curvesCount; index++) - { - if (isClockwise) + if (geometryLoopDirections[loop][index] == CurveDirection.Forward) { - if (geometryLoopDirections[loop][index] == CurveDirection.Forward) - { - loop.CurveList[index].SurfaceAtRight = surface; - } - else - { - loop.CurveList[index].SurfaceAtLeft = surface; - } + loop.CurveList[index].SurfaceAtLeft = surface; } else { - if (geometryLoopDirections[loop][index] == CurveDirection.Forward) - { - loop.CurveList[index].SurfaceAtLeft = surface; - } - else - { - loop.CurveList[index].SurfaceAtRight = surface; - } + loop.CurveList[index].SurfaceAtRight = surface; } } } + } - private void SetupCurveSurfaceAssociation() + private void SetupCurveSurfaceAssociation() + { + // clear the data + int count = geometryData.Curves.Count; + for (var i = 0; i < count; i++) { - // clear the data - int count = geometryData.Curves.Count; - for (var i = 0; i < count; i++) - { - geometryData.Curves[i].SurfaceAtLeft = null; - geometryData.Curves[i].SurfaceAtRight = null; - } + geometryData.Curves[i].SurfaceAtLeft = null; + geometryData.Curves[i].SurfaceAtRight = null; + } - // reset - count = geometryData.Surfaces.Count; - for (var i = 0; i < count; i++) - { - AssignSurfaceAtLeftOrRightToCurves(geometryData.Surfaces[i]); - } + // reset + count = geometryData.Surfaces.Count; + for (var i = 0; i < count; i++) + { + AssignSurfaceAtLeftOrRightToCurves(geometryData.Surfaces[i]); } + } - /// - /// Setups the curve surface associations. - /// - private void SetupCurveSurfaceAssociations() + /// + /// Setups the curve surface associations. + /// + private void SetupCurveSurfaceAssociations() + { + SetUpGeometryLoopDirections(); + // only try to connect curves to surfaces when there are loops (i.e. surfaces) + if (geometryLoopDirections.Count > 0) { - SetUpGeometryLoopDirections(); - // only try to connect curves to surfaces when there are loops (i.e. surfaces) - if (geometryLoopDirections.Count > 0) - { - SetupCurveSurfaceAssociation(); - } + SetupCurveSurfaceAssociation(); } + } - private void SetUpGeometryLoopDirections() + private void SetUpGeometryLoopDirections() + { + geometryLoopDirections.Clear(); + foreach (GeometryLoop loop in geometryData.Loops) { - geometryLoopDirections.Clear(); - foreach (GeometryLoop loop in geometryData.Loops) + if (!geometryLoopDirections.ContainsKey(loop)) { - if (!geometryLoopDirections.ContainsKey(loop)) - { - SetUpGeometryLoopDirections(loop); - } + SetUpGeometryLoopDirections(loop); } } + } - private void SetUpGeometryLoopDirections(GeometryLoop aLoop) + private void SetUpGeometryLoopDirections(GeometryLoop aLoop) + { + if (aLoop.CurveList.Count > 0) { - if (aLoop.CurveList.Count > 0) + Point2D loopPoint; + + geometryLoopDirections.Add(aLoop, new List()); + // get the first curve + if (aLoop.CurveList[0].EndPoint == aLoop.CurveList[1].HeadPoint || aLoop.CurveList[0].EndPoint == aLoop.CurveList[1].EndPoint) { - Point2D loopPoint; + geometryLoopDirections[aLoop].Add(CurveDirection.Forward); + loopPoint = aLoop.CurveList[0].EndPoint; + } + else + { + geometryLoopDirections[aLoop].Add(CurveDirection.Reverse); + loopPoint = aLoop.CurveList[0].HeadPoint; + } - geometryLoopDirections.Add(aLoop, new List()); - // get the first curve - if (aLoop.CurveList[0].EndPoint == aLoop.CurveList[1].HeadPoint || aLoop.CurveList[0].EndPoint == aLoop.CurveList[1].EndPoint) + // the rest of the curves + for (var index1 = 1; index1 < aLoop.CurveList.Count; index1++) + { + if (loopPoint == aLoop.CurveList[index1].HeadPoint) { geometryLoopDirections[aLoop].Add(CurveDirection.Forward); - loopPoint = aLoop.CurveList[0].EndPoint; + loopPoint = aLoop.CurveList[index1].EndPoint; } else { geometryLoopDirections[aLoop].Add(CurveDirection.Reverse); - loopPoint = aLoop.CurveList[0].HeadPoint; + loopPoint = aLoop.CurveList[index1].HeadPoint; } - - // the rest of the curves - for (var index1 = 1; index1 < aLoop.CurveList.Count; index1++) - { - if (loopPoint == aLoop.CurveList[index1].HeadPoint) - { - geometryLoopDirections[aLoop].Add(CurveDirection.Forward); - loopPoint = aLoop.CurveList[index1].EndPoint; - } - else - { - geometryLoopDirections[aLoop].Add(CurveDirection.Reverse); - loopPoint = aLoop.CurveList[index1].HeadPoint; - } - } } } + } - /// - /// Checks and adds inner loop to the new surface. - /// - /// - private void CheckAndAddInnerLoops(ref object aNewSurface) - { - var newSurface = (GeometrySurface) aNewSurface; - int surfaceCount = geometryData.Surfaces.Count; - GeometryLoop newLoop = newSurface.OuterLoop; - int newPointCount = newLoop.CurveList.Count; - List newPolygon = newLoop.CalcPoints; + /// + /// Checks and adds inner loop to the new surface. + /// + /// + private void CheckAndAddInnerLoops(ref object aNewSurface) + { + var newSurface = (GeometrySurface) aNewSurface; + int surfaceCount = geometryData.Surfaces.Count; + GeometryLoop newLoop = newSurface.OuterLoop; + int newPointCount = newLoop.CurveList.Count; + List newPolygon = newLoop.CalcPoints; - newSurface.InnerLoops.Clear(); + newSurface.InnerLoops.Clear(); - for (var index = 0; index < surfaceCount; index++) + for (var index = 0; index < surfaceCount; index++) + { + if (newSurface == geometryData.Surfaces[index]) { - if (newSurface == geometryData.Surfaces[index]) - { - continue; - } + continue; + } - var innerPointCount = 0; - var outerPointCount = 0; - var isOnPointCount = 0; - var hasOnPointCount = 0; - GeometryLoop loop = geometryData.Surfaces[index].OuterLoop; - List polygon = loop.CalcPoints; - int existingLoopPointCount = polygon.Count; + var innerPointCount = 0; + var outerPointCount = 0; + var isOnPointCount = 0; + var hasOnPointCount = 0; + GeometryLoop loop = geometryData.Surfaces[index].OuterLoop; + List polygon = loop.CalcPoints; + int existingLoopPointCount = polygon.Count; - // check if it is an inner loop - for (var innerIndex = 0; innerIndex < newPointCount; innerIndex++) - { - PointInPolygon location = Routines2D.CheckIfPointIsInPolygon(loop, newPolygon[innerIndex].X, newPolygon[innerIndex].Z); + // check if it is an inner loop + for (var innerIndex = 0; innerIndex < newPointCount; innerIndex++) + { + PointInPolygon location = Routines2D.CheckIfPointIsInPolygon(loop, newPolygon[innerIndex].X, newPolygon[innerIndex].Z); - if (location == PointInPolygon.InsidePolygon) - { - innerPointCount++; - } - else if (location == PointInPolygon.OnPolygonEdge) - { - isOnPointCount++; - } + if (location == PointInPolygon.InsidePolygon) + { + innerPointCount++; } - - // check if it has an inner loop - for (var innerIndex1 = 0; innerIndex1 < existingLoopPointCount; innerIndex1++) + else if (location == PointInPolygon.OnPolygonEdge) { - PointInPolygon location = Routines2D.CheckIfPointIsInPolygon(newLoop, polygon[innerIndex1].X, polygon[innerIndex1].Z); - - if (location == PointInPolygon.InsidePolygon) - { - outerPointCount++; - } - else if (location == PointInPolygon.OnPolygonEdge) - { - hasOnPointCount++; - } + isOnPointCount++; } + } - //Add New Loop as inner loop to the existing Surface - if ((innerPointCount == newPointCount) || ((innerPointCount > 0) && (newPointCount == (innerPointCount + isOnPointCount)))) + // check if it has an inner loop + for (var innerIndex1 = 0; innerIndex1 < existingLoopPointCount; innerIndex1++) + { + PointInPolygon location = Routines2D.CheckIfPointIsInPolygon(newLoop, polygon[innerIndex1].X, polygon[innerIndex1].Z); + + if (location == PointInPolygon.InsidePolygon) { - geometryData.Surfaces[index].AddInnerLoop(newLoop); + outerPointCount++; } - - //Add Inner Loop to the New Surface - if ((outerPointCount == existingLoopPointCount) || ((outerPointCount > 0) && (existingLoopPointCount == (outerPointCount + hasOnPointCount)))) + else if (location == PointInPolygon.OnPolygonEdge) { - newSurface.AddInnerLoop(loop); + hasOnPointCount++; } } - } - /// - /// Gets the newly detected surface from the list. - /// - /// - private void GetNewlyDetectedSurfaces(ref List aNewSurfaceList) - { - aNewSurfaceList.AddRange(newlyDetectedSurfaceList); - } + //Add New Loop as inner loop to the existing Surface + if ((innerPointCount == newPointCount) || ((innerPointCount > 0) && (newPointCount == (innerPointCount + isOnPointCount)))) + { + geometryData.Surfaces[index].AddInnerLoop(newLoop); + } - #region Nested type: DirectionCurve - - internal struct DirectionCurve - { - internal DirectionCurve(GeometryCurve aCurve, CurveDirection aDirection) + //Add Inner Loop to the New Surface + if ((outerPointCount == existingLoopPointCount) || ((outerPointCount > 0) && (existingLoopPointCount == (outerPointCount + hasOnPointCount)))) { - Curve = aCurve; - Direction = aDirection; + newSurface.AddInnerLoop(loop); } + } + } - internal GeometryCurve Curve { get; } + /// + /// Gets the newly detected surface from the list. + /// + /// + private void GetNewlyDetectedSurfaces(ref List aNewSurfaceList) + { + aNewSurfaceList.AddRange(newlyDetectedSurfaceList); + } - internal CurveDirection Direction { get; } + #region Nested type: DirectionCurve - internal Point2D GetHeadPoint() - { - return Curve.GetHeadPoint(Direction); - } + internal struct DirectionCurve + { + internal DirectionCurve(GeometryCurve aCurve, CurveDirection aDirection) + { + Curve = aCurve; + Direction = aDirection; + } - internal Point2D GetEndPoint() - { - return Curve.GetEndPoint(Direction); - } + internal GeometryCurve Curve { get; } + + internal CurveDirection Direction { get; } + + internal Point2D GetHeadPoint() + { + return Curve.GetHeadPoint(Direction); } - #endregion + internal Point2D GetEndPoint() + { + return Curve.GetEndPoint(Direction); + } } + + #endregion } \ No newline at end of file