using System; using System.Collections.Generic; using System.Diagnostics; using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.Soils; using Deltares.Mathematics; using Deltares.Stability; using Deltares.Standard.Extensions; namespace Deltares.MStab.IO.Classic { internal class SurfaceTopAndBottom { public List GetTopOfLoop(GeometryLoop aLoop) { //each side (left right) var curvelist = new List(); curvelist.InsertRange(0, aLoop.CurveList); curvelist.Sort(delegate(GeometryCurve item1, GeometryCurve item2) { if ((item2.HeadPoint.X < item1.HeadPoint.X) || (item2.EndPoint.X < item1.EndPoint.X)) { return 1; } else if ((item2.HeadPoint.X == item1.HeadPoint.X) && (item2.EndPoint.X == item1.EndPoint.X)) { return 0; } else { return -1; } }); //seperate sides List leftCurveList = aLoop.CurveList.FindAll(x => ((x.EndPoint.X == curvelist[0].EndPoint.X) || (x.HeadPoint.X == curvelist[0].HeadPoint.X))); List rightCurveList = aLoop.CurveList.FindAll(x => ((x.EndPoint.X == curvelist[aLoop.CurveList.Count - 1].EndPoint.X) || (x.HeadPoint.X == curvelist[aLoop.CurveList.Count - 1].HeadPoint.X))); //Left top leftCurveList.Sort(delegate(GeometryCurve item1, GeometryCurve item2) { if ((item2.HeadPoint.Z > item1.HeadPoint.Z) || (item2.EndPoint.Z > item1.EndPoint.Z)) { return 1; } else if ((item2.HeadPoint.Z == item1.HeadPoint.Z) && (item2.EndPoint.Z == item1.EndPoint.Z)) { return 0; } else { return -1; } }); //Right top rightCurveList.Sort(delegate(GeometryCurve item1, GeometryCurve item2) { if ((item2.HeadPoint.Z > item1.HeadPoint.Z) || (item2.EndPoint.Z > item1.EndPoint.Z)) { return 1; } else if ((item2.HeadPoint.Z == item1.HeadPoint.Z) && (item2.EndPoint.Z == item1.EndPoint.Z)) { return 0; } else { return -1; } }); GeometryCurve lefttopcurve = leftCurveList[0]; GeometryCurve righttopcurve = rightCurveList[0]; //Warning direction differs from normal layers int stopIndex = aLoop.CurveList.FindIndex(x => x == lefttopcurve); int startIndex = aLoop.CurveList.FindIndex(x => x == righttopcurve); var topcurvelist = new List(); int index = startIndex; while (index != (stopIndex + 1)%aLoop.CurveList.Count) { topcurvelist.Add((GeometryCurve) aLoop.CurveList[index]); index = (index + 1)%aLoop.CurveList.Count; } return topcurvelist; } public List GetBottomOfLoop(GeometryLoop aLoop) { //each side (left right) var curvelist = new List(); curvelist.InsertRange(0, aLoop.CurveList); curvelist.Sort(delegate(GeometryCurve item1, GeometryCurve item2) { if ((item2.HeadPoint.X < item1.HeadPoint.X) || (item2.EndPoint.X < item1.EndPoint.X)) { return 1; } else if ((item2.HeadPoint.X == item1.HeadPoint.X) && (item2.EndPoint.X == item1.EndPoint.X)) { return 0; } else { return -1; } }); //seperate sides List leftCurveList = aLoop.CurveList.FindAll(x => ((x.EndPoint.X == curvelist[0].EndPoint.X) || (x.HeadPoint.X == curvelist[0].HeadPoint.X))); List rightCurveList = aLoop.CurveList.FindAll(x => ((x.EndPoint.X == curvelist[aLoop.CurveList.Count - 1].EndPoint.X) || (x.HeadPoint.X == curvelist[aLoop.CurveList.Count - 1].HeadPoint.X))); //Left top leftCurveList.Sort(delegate(GeometryCurve item1, GeometryCurve item2) { if ((item2.HeadPoint.Z < item1.HeadPoint.Z) || (item2.EndPoint.Z < item1.EndPoint.Z)) { return 1; } else if ((item2.HeadPoint.Z == item1.HeadPoint.Z) && (item2.EndPoint.Z == item1.EndPoint.Z)) { return 0; } else { return -1; } }); //Right top rightCurveList.Sort(delegate(GeometryCurve item1, GeometryCurve item2) { if ((item2.HeadPoint.Z > item1.HeadPoint.Z) || (item2.EndPoint.Z > item1.EndPoint.Z)) { return 1; } else if ((item2.HeadPoint.Z == item1.HeadPoint.Z) && (item2.EndPoint.Z == item1.EndPoint.Z)) { return 0; } else { return -1; } }); GeometryCurve leftBottomcurve = leftCurveList[0]; GeometryCurve rightBottomcurve = rightCurveList[0]; //Warning direction differs from normal layers int startIndex = aLoop.CurveList.FindIndex(x => x == leftBottomcurve); int stopIndex = aLoop.CurveList.FindIndex(x => x == rightBottomcurve); var bottomCurveList = new List(); int index = startIndex; while (index != (stopIndex + 1)%aLoop.CurveList.Count) { bottomCurveList.Add((GeometryCurve) aLoop.CurveList[index]); index = (index + 1)%aLoop.CurveList.Count; } return bottomCurveList; } } internal class Waternet { /// /// Manders Create new waternet /// public void GetWaterNet(int handle, StabilityModel stabilityModel, Dictionary aSurfaceDictionary, Dictionary> aBoundaryDictionary, List waternetGeometryPoints) { ClassicMStabFunctionDefinitions.MStabUnitWeightWater classicUnitWeightWater = null; ClassicMStabFunctionDefinitions.MStabMSeepNet classicMSeepNet = null; ClassicMStabFunctionDefinitions.MStabExternalWaterLevels externalWaterLevels = null; ClassicGeometryFunctionDefinitions.GeometryLayers classicGeometryLayers = null; try { GetClassicMStab.GetClassicUnitWeightWater(handle, ref classicUnitWeightWater); GetClassicMStab.GetClassicMSeepNet(handle, ref classicMSeepNet); GetClassicMStab.GetClassicExternalWaterLevels(handle, ref externalWaterLevels); GetClassicGeometry.GetClassicGeometryLayers(handle, ref classicGeometryLayers); } catch (Exception e) { Trace.WriteLine("Could not get classic waterobjects" + e.ToString()); } stabilityModel.GeotechnicsData.CurrentWaternet.UnitWeight = classicUnitWeightWater.gamWater; //mStabProject.Waternet.UseMSeepNetLocation = classicMSeepNet.useMSeepnet; stabilityModel.GeotechnicsData.UseMSeepNetLocation = classicMSeepNet.mSeepFileName; stabilityModel.GeotechnicsData.MakeNegativePressureZero = classicMSeepNet.netMakeZero; Geotechnics.Waternet waternet = stabilityModel.GeotechnicsData.CurrentWaternet; waternet.IsCurrentWaternet = true; stabilityModel.GeotechnicsData.CurrentWaternet = waternet; stabilityModel.GeotechnicsData.CurrentWaternet = waternet; var plAtBottom = new int[classicGeometryLayers.layers.Length]; var plAtTop = new int[classicGeometryLayers.layers.Length]; for (int i = 0; i < classicGeometryLayers.layers.Length; i++) { plAtBottom[i] = classicGeometryLayers.layers[i].p1AtBottom; plAtTop[i] = classicGeometryLayers.layers[i].p1AtTop; } int phreaticLineIndex = 1; // voorlopig, nog te lezen uit native dll var isBottomLine = new Dictionary(); AssignWaternetLines(handle, stabilityModel, aSurfaceDictionary, phreaticLineIndex, plAtBottom, plAtTop, isBottomLine, waternetGeometryPoints); CorrectWaternet(stabilityModel.GeotechnicsData.CurrentWaternet, isBottomLine); stabilityModel.GeotechnicsData.UseWaterData = externalWaterLevels.waterDataUsed; stabilityModel.GeotechnicsData.DecimateHeight = externalWaterLevels.decimate; stabilityModel.GeotechnicsData.DesignLevel = externalWaterLevels.mHW; stabilityModel.GeotechnicsData.ExceedingFrequency = (ExeedingFrequency) externalWaterLevels.exceeding; waternet.ExternalWaterLevel = externalWaterLevels.mHW; for (int i = 0; i < externalWaterLevels.numberOfItems; i++) { Geotechnics.Waternet newWaternet = null; newWaternet = stabilityModel.GeotechnicsData.Create(new Geotechnics.Waternet()) as Geotechnics.Waternet; //if (aMStabProject.GeotechnicsData.Waternets.Count > i) //{ // newWaternet = aMStabProject.GeotechnicsData.Waternets[i]; //} //else //{ // newWaternet = aMStabProject.GeotechnicsData.Create(new Geotechnics.Waternet()) as Deltares.Geotechnics.Waternet; //} stabilityModel.GeotechnicsData.CurrentWaternet = newWaternet; newWaternet.Name = externalWaterLevels.waterProperties[i].name; newWaternet.ExternalWaterLevel = externalWaterLevels.waterProperties[i].level; for (int j = 0; j < classicGeometryLayers.layers.Length; j++) { plAtBottom[j] = externalWaterLevels.waterProperties[i].pLs[j].pLBot; plAtTop[j] = externalWaterLevels.waterProperties[i].pLs[j].pLTop; } AssignWaternetLines(handle, stabilityModel, aSurfaceDictionary, externalWaterLevels.waterProperties[i].phreaLine, plAtBottom, plAtTop, isBottomLine, waternetGeometryPoints); CorrectWaternet(newWaternet, isBottomLine); } stabilityModel.GeotechnicsData.CurrentWaternet = waternet; } private void CorrectWaternet(Geotechnics.Waternet waternet, Dictionary isBottomLine) { var waternetLines = new List(); waternetLines.AddRange(waternet.WaternetLineList); var meanZ = new Dictionary(); foreach (var waternetLine in waternetLines) { if (isBottomLine[waternetLine]) { meanZ[waternetLine] = 100000 - waternetLine.GetMeanZ(); } else { meanZ[waternetLine] = waternetLine.GetMeanZ(); } } waternetLines.Sort(new MeanZComparer(meanZ)); for (int i = 0; i < waternetLines.Count; i++) { for (int j = i + 1; j < waternetLines.Count; j++) { List commonPart = waternetLines[j].GetCommonPart(waternetLines[i]); if (commonPart.Count > 1) { if (waternetLines[j].HeadLine == waternetLines[i].HeadLine) { List rangeBefore = waternetLines[j].GetRange(Double.NegativeInfinity, commonPart[0].X); List rangeAfter = waternetLines[j].GetRange(commonPart[commonPart.Count - 1].X, Double.PositiveInfinity); if (rangeBefore.Count > 1 && rangeAfter.Count > 1) { waternetLines[j].Points.Clear(); waternetLines[j].Points.AddRange(rangeBefore); var newWaternetLine = new WaternetLine(); newWaternetLine.Points.AddRange(rangeAfter); newWaternetLine.HeadLine = waternetLines[j].HeadLine; waternet.WaternetLineList.Add(newWaternetLine); } else if (rangeBefore.Count > 1) { waternetLines[j].Points.Clear(); waternetLines[j].Points.AddRange(rangeBefore); } else if (rangeAfter.Count > 1) { waternetLines[j].Points.Clear(); waternetLines[j].Points.AddRange(rangeAfter); } } else { // move up waternet line const double offset = 0.01; foreach (var point in waternetLines[j].Points) { point.Z += offset; } } } } } } private void AssignWaternetLines(int handle, StabilityModel aMStabProject, Dictionary aSurfaceDictionary, int phreaticLineIndex, int[] bottomIndex, int[] topIndex, Dictionary isBottomLine, List waternetGeometryPoints) { var phreaticLines = new Dictionary(); var headLines = new Dictionary(); var waternetLines = new Dictionary(); ClassicGeometryFunctionDefinitions.GeometryParam classicGeometryConstants = null; List classicGeometryCurves = null; List classicGeometryPoints = null; ClassicGeometryFunctionDefinitions.GeometryPiezoLines classicPiezoLines = null; ClassicGeometryFunctionDefinitions.GeometryLayers classicGeometryLayers = null; ClassicGeometryFunctionDefinitions.GeometryBoundaries classicGeometryBoundaries = null; try { GetClassicGeometry.GetClassicGeometryConstants(handle, ref classicGeometryConstants); GetClassicGeometry.GetClassicGeometryPiezoLines(handle, ref classicPiezoLines); GetClassicGeometry.GetClassicGeometryCurves(handle, ref classicGeometryCurves); GetClassicGeometry.GetClassicGeometryPoints(handle, ref classicGeometryPoints); GetClassicGeometry.GetClassicGeometryLayers(handle, ref classicGeometryLayers); GetClassicGeometry.GetClassicGeometryBoundaries(handle, ref classicGeometryBoundaries); } catch (Exception e) { Trace.WriteLine("Could not get classic waterobjects" + e.ToString()); } try { var bottomLines = new Dictionary(); var topLines = new Dictionary(); var lines = new Dictionary(); // Fill dictionaries with references to PL lines for (int i = 0; i < aMStabProject.Geometry.Surfaces.Count; i++) { GeometrySurface geometrySurface = aMStabProject.Geometry.Surfaces[i]; SoilLayer2D soilSurface = aMStabProject.SoilProfile.Surfaces.Find(aSoilSurface => aSoilSurface.GeometrySurface == geometrySurface); //Convert to old Geometry layer: int surfaceIndex; if (aSurfaceDictionary.TryGetValue(aMStabProject.Geometry.Surfaces[i], out surfaceIndex)) { int bottomLine = bottomIndex[surfaceIndex]; int topLine = topIndex[surfaceIndex]; bottomLines[soilSurface] = bottomIndex[surfaceIndex]; topLines[soilSurface] = topIndex[surfaceIndex]; } } // Fill list with lines for (int i = 1; i <= classicPiezoLines.numberOfLines; i++) { GeometryPointString line = null; if (i == phreaticLineIndex) { line = new PhreaticLine(); lines[i] = line; } else { line = new HeadLine(); lines[i] = line; } FillLineWithPoints(aMStabProject, line, classicPiezoLines.piezoLine[i - 1].curveIndices, classicGeometryPoints, classicGeometryCurves, waternetGeometryPoints, 0, true); aMStabProject.GeotechnicsData.Create(line); } // check whether they are all referring to the phreatic line, then no waternet lines are needed bool phreaticLineOnly = true; for (int i = 0; i < classicGeometryBoundaries.numberOfBoundaries; i++) { if ((bottomIndex[i] != 0 && bottomIndex[i] != 99 && bottomIndex[i] != phreaticLineIndex) || (topIndex[i] != 0 && topIndex[i] != 99 && topIndex[i] != phreaticLineIndex)) { phreaticLineOnly = false; break; } } if (!phreaticLineOnly) { int previousWaterline = -1; const double offset = 0.01; var hasOffset = new Dictionary(); for (int i = 0; i < classicGeometryBoundaries.numberOfBoundaries; i++) { int bottomLine = bottomIndex[i]; int topLine = topIndex[i]; bool bottomLineDefined = bottomLine != 0 && bottomLine != 99; bool topLineDefined = topLine != 0 && topLine != 99; if (bottomLineDefined) { int nextDefinedWaterline = NextDefinedWaterline(bottomIndex, topIndex, i, true); bool nextLineDifferent = nextDefinedWaterline != -1 && nextDefinedWaterline != bottomLine; bool previousLineDifferent = previousWaterline != -1 && previousWaterline != bottomLine; bool definedPartial = HasCurvesInCommonWithLowerBoundary(i, classicGeometryBoundaries, classicGeometryCurves); if (nextLineDifferent || previousLineDifferent || definedPartial) { WaternetLine newWaternetLine = CreateWaterline(aMStabProject, classicGeometryCurves, classicGeometryPoints, classicGeometryBoundaries, lines, i, bottomLine, offset, false); if (newWaternetLine != null) { isBottomLine[newWaternetLine] = true; hasOffset[newWaternetLine] = true; previousWaterline = bottomLine; } } } if (topLineDefined) { int nextDefinedWaterline = NextDefinedWaterline(bottomIndex, topIndex, i, false); bool nextLineDifferent = nextDefinedWaterline != -1 && nextDefinedWaterline != topLine; bool previousLineDifferent = previousWaterline != -1 && previousWaterline != topLine; bool definedPartial = HasCurvesInCommonWithLowerBoundary(i + 1, classicGeometryBoundaries, classicGeometryCurves); if (nextLineDifferent || previousLineDifferent || definedPartial) { WaternetLine newWaternetLine = CreateWaterline(aMStabProject, classicGeometryCurves, classicGeometryPoints, classicGeometryBoundaries, lines, i + 1, topLine, 0, true); if (newWaternetLine != null) { isBottomLine[newWaternetLine] = false; hasOffset[newWaternetLine] = false; previousWaterline = topLine; } } } // if there are no waternet lines added and there is a headline, generate an waternet line to the headline at the bottom of the geometry if (aMStabProject.GeotechnicsData.CurrentWaternet.WaternetLineList.Count == 0 && aMStabProject.GeotechnicsData.CurrentWaternet.HeadLineList.Count > 0) { WaternetLine bottomWaternetLine = CreateWaterline(aMStabProject, classicGeometryCurves, classicGeometryPoints, classicGeometryBoundaries, lines, 0, bottomLine, offset, false); if (bottomWaternetLine != null) { isBottomLine[bottomWaternetLine] = true; hasOffset[bottomWaternetLine] = true; } } } // add a line at the top of the geometry, if there was only one waternet line added if (aMStabProject.GeotechnicsData.CurrentWaternet.WaternetLineList.Count == 1 && aMStabProject.GeotechnicsData.CurrentWaternet.HeadLineList.Count > 0) { WaternetLine topWaternetLine = CreateWaterline(aMStabProject, classicGeometryCurves, classicGeometryPoints, classicGeometryBoundaries, lines, classicGeometryBoundaries.numberOfBoundaries - 1, bottomIndex[0], 0, true); if (topWaternetLine != null) { isBottomLine[topWaternetLine] = false; hasOffset[topWaternetLine] = false; } } CorrectWaternetLines(aMStabProject, hasOffset, offset); } } catch (Exception e) { Trace.WriteLine("Could not get headlines" + e.ToString()); } } /// /// Removes all duplicate or allmost duplicate waternet lines /// /// private void CorrectWaternetLines(StabilityModel project, Dictionary hasOffset, double offset) { var removeWaternetLines = new List(); // If there are two lines, which only differ in the offset and point to the same headline, remove on of them for (int i = 1; i < project.GeotechnicsData.CurrentWaternet.WaternetLineList.Count; i++) { WaternetLine line1 = project.GeotechnicsData.CurrentWaternet.WaternetLineList[i - 1]; WaternetLine line2 = project.GeotechnicsData.CurrentWaternet.WaternetLineList[i]; if (line1.HeadLine == line2.HeadLine) { if (AreAlmostEqual(line1, line2, offset)) { removeWaternetLines.Add(line2); } } } foreach (var waternetLine in removeWaternetLines) { project.GeotechnicsData.CurrentWaternet.WaternetLineList.Remove(waternetLine); } // Undo the offset if there is no lilne close to it for (int i = 1; i < project.GeotechnicsData.CurrentWaternet.WaternetLineList.Count; i++) { WaternetLine line1 = project.GeotechnicsData.CurrentWaternet.WaternetLineList[i - 1]; WaternetLine line2 = project.GeotechnicsData.CurrentWaternet.WaternetLineList[i]; if (hasOffset[line2] && !AreAlmostEqual(line1, line2, offset)) { foreach (var point in line2.Points) { point.Z -= offset; } } } // Renumber the waternet lines for (int i = 0; i < project.GeotechnicsData.CurrentWaternet.WaternetLineList.Count; i++) { project.GeotechnicsData.CurrentWaternet.WaternetLineList[i].Name = "Waternet line " + (i + 1).ToString(); } } private bool AreAlmostEqual(WaternetLine line1, WaternetLine line2, double offset) { const double delta = 0.0000001; if (line1.Points.Count == line2.Points.Count) { for (int j = 0; j < line1.Points.Count; j++) { if (!Routines2D.AreEqual(line1.Points[j].X, line2.Points[j].X, delta) || !Routines2D.AreEqual(line1.Points[j].Z, line2.Points[j].Z, offset + delta)) { return false; } } return true; } return false; } private WaternetLine CreateWaterline(StabilityModel aMStabProject, List classicGeometryCurves, List classicGeometryPoints, ClassicGeometryFunctionDefinitions.GeometryBoundaries classicGeometryBoundaries, Dictionary lines, int i, int bottomLine, double offset, bool isAtTopOfLayer) { var waternetLine = new WaternetLine(); if (lines.ContainsKey(bottomLine)) { waternetLine.HeadLine = lines[bottomLine]; } int[] boundaryCurves = null; if (isAtTopOfLayer) { boundaryCurves = GetBoundariesDifferentFromLowerBoundaries(i, classicGeometryBoundaries, classicGeometryCurves); } else { boundaryCurves = GetBoundariesDifferentFromUpperBoundaries(i, classicGeometryBoundaries, classicGeometryCurves); } FillLineWithPoints(aMStabProject, waternetLine, boundaryCurves, classicGeometryPoints, classicGeometryCurves, aMStabProject.Geometry.Points, offset, false); if (waternetLine.Points.Count > 1) { aMStabProject.GeotechnicsData.Create(waternetLine); return waternetLine; } else { return null; } } private bool HasCurvesInCommonWithLowerBoundary(int boundaryIndex, ClassicGeometryFunctionDefinitions.GeometryBoundaries boundaryCollection, List curves) { if (boundaryIndex == 0) { return false; } int[] boundaries = boundaryCollection.boundaries[boundaryIndex].curvesIndices; int[] lowerBoundaries = boundaryCollection.boundaries[boundaryIndex - 1].curvesIndices; for (int i = 0; i < boundaries.Length && boundaries[i] != 0; i++) { for (int j = 0; j < lowerBoundaries.Length && lowerBoundaries[j] != 0; j++) { if (curves.Count > boundaries[i] && curves.Count > lowerBoundaries[j] && AreCurvesEqual(curves[boundaries[i]], curves[lowerBoundaries[j]])) { return true; } } } return false; } private int[] GetBoundariesDifferentFromLowerBoundaries(int boundaryIndex, ClassicGeometryFunctionDefinitions.GeometryBoundaries boundaryCollection, List curves) { var differentBoundaries = new List(); int[] boundaries = boundaryCollection.boundaries[boundaryIndex].curvesIndices; for (int i = 0; i < boundaries.Length && boundaries[i] != 0; i++) { bool inLowerBoundary = false; for (int j = 0; j < boundaryIndex; j++) { int[] lowerBoundaries = boundaryCollection.boundaries[j].curvesIndices; for (int k = 0; k < lowerBoundaries.Length && lowerBoundaries[k] != 0; k++) { if (curves.Count > boundaries[i] && curves.Count > lowerBoundaries[k] && AreCurvesEqual(curves[boundaries[i]], curves[lowerBoundaries[k]])) { inLowerBoundary = true; break; } } if (inLowerBoundary) { break; } } if (!inLowerBoundary) { differentBoundaries.Add(boundaries[i]); } } return differentBoundaries.ToArray(); } private int[] GetBoundariesDifferentFromUpperBoundaries(int boundaryIndex, ClassicGeometryFunctionDefinitions.GeometryBoundaries boundaryCollection, List curves) { var differentBoundaries = new List(); int[] boundaries = boundaryCollection.boundaries[boundaryIndex].curvesIndices; for (int i = 0; i < boundaries.Length && boundaries[i] != 0; i++) { bool inUpperBoundary = false; for (int j = boundaryIndex + 1; j < boundaryCollection.boundaries.Length; j++) { int[] upperBoundaries = boundaryCollection.boundaries[j].curvesIndices; for (int k = 0; k < upperBoundaries.Length && upperBoundaries[k] != 0; k++) { if (curves.Count > boundaries[i] && curves.Count > upperBoundaries[k] && AreCurvesEqual(curves[boundaries[i]], curves[upperBoundaries[k]])) { inUpperBoundary = true; break; } } if (inUpperBoundary) { break; } } if (!inUpperBoundary) { differentBoundaries.Add(boundaries[i]); } } return differentBoundaries.ToArray(); } private bool AreCurvesEqual(ClassicGeometryFunctionDefinitions.GeometryCurve curve1, ClassicGeometryFunctionDefinitions.GeometryCurve curve2) { return ((curve1.pointIndices[0] == curve2.pointIndices[0] && curve1.pointIndices[1] == curve2.pointIndices[1]) || (curve1.pointIndices[0] == curve2.pointIndices[1] && curve1.pointIndices[1] == curve2.pointIndices[0])); } private int NextDefinedWaterline(int[] bottomIndex, int[] topIndex, int startIndex, bool isBottomIndex) { if (isBottomIndex) { for (int i = startIndex; i < bottomIndex.Length; i++) { if (i != startIndex && bottomIndex[i] != 0 && bottomIndex[i] != 99) { return bottomIndex[i]; } else if (topIndex[i] != 0 && topIndex[i] != 99) { return topIndex[i]; } } } else { for (int i = startIndex + 1; i < bottomIndex.Length; i++) { if (bottomIndex[i] != 0 && bottomIndex[i] != 99) { return bottomIndex[i]; } else if (topIndex[i] != 0 && topIndex[i] != 99) { return topIndex[i]; } } } return -1; } private void FillLineWithPoints(StabilityModel aMStabProject, GeometryPointString line, int[] curves, List classicGeometryPoints, List classicGeometryCurves, IList points, double offset, bool extendToGeometryBoundaries) { int count = 0; for (int i = 0; i < curves.Length; i++) { if (curves[i] > 0) { count++; } else { break; } } // fill lines with points for (int j = 0; j < count; j++) { int CurveIndex = curves[j]; //Convert curve to new curve model ClassicGeometryFunctionDefinitions.GeometryPoint classicBeginPoint = classicGeometryPoints[classicGeometryCurves[CurveIndex - 1].pointIndices[0] - 1]; ClassicGeometryFunctionDefinitions.GeometryPoint classicEndPoint = classicGeometryPoints[classicGeometryCurves[CurveIndex - 1].pointIndices[1] - 1]; // make a copy always line.Points.Add(new GeometryPoint(classicBeginPoint.x, classicBeginPoint.z, classicBeginPoint.y + offset)); if (j == count - 1) { line.Points.Add(new GeometryPoint(classicEndPoint.x, classicEndPoint.z, classicEndPoint.y + offset)); } } if (extendToGeometryBoundaries) { line.Points[0].X = aMStabProject.Geometry.Left; line.Points[line.Points.Count - 1].X = aMStabProject.Geometry.Right; } else { // Remove vertical parts at begin and end while (line.Points.Count >= 2 && line.Points[0].X == line.Points[1].X) { line.Points.RemoveAt(0); } while (line.Points.Count >= 2 && line.Points[line.Points.Count - 1].X == line.Points[line.Points.Count - 2].X) { line.Points.RemoveAt(line.Points.Count - 1); } } } } internal class MeanZComparer : IComparer { private Dictionary meanZ; public MeanZComparer(Dictionary meanZ) { this.meanZ = meanZ; } public int Compare(WaternetLine x, WaternetLine y) { return meanZ[x].CompareTo(meanZ[y]); } } }