diff --git a/Directory.Packages.props b/Directory.Packages.props index f53e6d4..5768b47 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,9 +2,9 @@ true - - - + + + diff --git a/src/MeshKernelNET/Api/IMeshKernelApi.cs b/src/MeshKernelNET/Api/IMeshKernelApi.cs index fbdc09a..edaaa25 100644 --- a/src/MeshKernelNET/Api/IMeshKernelApi.cs +++ b/src/MeshKernelNET/Api/IMeshKernelApi.cs @@ -238,13 +238,6 @@ int CurvilinearComputeTransfiniteFromTriangle(int meshKernelId, /// Error code int CurvilinearFinalizeLineShift(int meshKernelId); - /// - /// Finalizes curvilinear orthogonalize algorithm - /// - /// Id of the mesh state - /// Error code - int CurvilinearFinalizeOrthogonalize(int meshKernelId); - /// /// Gets the curvilinear data and returns a DisposableCurvilinearGrid /// @@ -334,14 +327,6 @@ int CurvilinearInitializeOrthogonalGridFromSplines(int meshKernelId, in CurvilinearParameters curvilinearParametersNative, in SplinesToCurvilinearParameters splinesToCurvilinearParameters); - /// - /// Initializes the orthogonal curvilinear algorithm - /// - /// The id of the mesh state - /// The orthogonalization parameters to use in the algorithm - /// Error code - int CurvilinearInitializeOrthogonalize(int meshKernelId, in OrthogonalizationParameters orthogonalizationParameters); - /// /// Inserts a new face on a curvilinear grid. The new face will be inserted on top of the closest edge by linear /// extrapolation. @@ -479,8 +464,18 @@ int CurvilinearMoveNodeLineShift(int meshKernelId, /// Orthogonalize a curvilinear grid /// /// The id of the mesh state + /// The orthogonalization parameters to use in the algorithm + /// The x coordinate of the lower left corner of the block to orthogonalize + /// The y coordinate of the lower left corner of the block to orthogonalize + /// The x coordinate of the upper right corner of the block to orthogonalize + /// The y coordinate of the upper right corner of the block to orthogonalize /// Error code - int CurvilinearOrthogonalize(int meshKernelId); + int CurvilinearOrthogonalize(int meshKernelId, + ref OrthogonalizationParameters orthogonalizationParameters, + double xLowerLeftCorner, + double yLowerLeftCorner, + double xUpperRightCorner, + double yUpperRightCorner); /// /// Directional curvilinear grid refinement. Additional gridlines are added perpendicularly to the segment defined by @@ -531,35 +526,74 @@ int CurvilinearSetBlockLineShift(int meshKernelId, double yUpperRightCorner); /// - /// efine a block on the curvilinear grid where to perform orthogonalization - /// - /// The meshKernelId of the block to orthogonalize - /// The xLowerLeftCorner of the block to orthogonalize - /// The yLowerLeftCorner of the block to orthogonalize - /// The xUpperRightCorner of the block to orthogonalize - /// The yUpperRightCorner of the block to orthogonalize - /// Error code - int CurvilinearSetBlockOrthogonalize(int meshKernelId, - double xLowerLeftCorner, - double yLowerLeftCorner, - double xUpperRightCorner, - double yUpperRightCorner); - - /// - /// Freezes a line in the curvilinear orthogonalization process + /// Adds a frozen in the meshkernel state. A frozen line is stored as a pair of coordinates. + /// The actual edges to freeze are computed during each algorithm execution, as they may change (for example, after a refinement operation). /// /// The id of the mesh state /// The x coordinate of the first point of the line to freeze /// The y coordinate of the first point of the line to freeze /// The x coordinate of the second point of the line to freeze /// The y coordinate of the second point of the line to freeze + /// The id of the frozen line, unique for each frozen line and meshkernel id. + /// It will not be re-issued again for another frozen line + /// Error code + int CurvilinearFrozenLineAdd(int meshKernelId, + double xFirstGridLineNode, + double yFirstGridLineNode, + double xSecondGridLineNode, + double ySecondGridLineNode, + ref int frozenLineId); + + /// + /// Deletes a frozen line in the meshkernel state + /// + /// The id of the mesh state + /// The id of the frozen line to delete /// Error code - int CurvilinearSetFrozenLinesOrthogonalize(int meshKernelId, - double xFirstGridLineNode, - double yFirstGridLineNode, - double xSecondGridLineNode, - double ySecondGridLineNode); + int CurvilinearFrozenLineDelete(int meshKernelId, int frozenLineId); + /// + /// Checks if a frozen line is valid + /// + /// The id of the mesh state + /// The id of the frozen line to check + /// True if the provided id is valid + /// Error code + int CurvilinearFrozenLineIsValid(int meshKernelId, int frozenLineId, ref bool isValid); + + /// + /// Gets the coordinates of the frozen line + /// + /// The id of the mesh state + /// The id of the frozen line to delete + /// The x coordinate of the first point of the frozen line + /// The y coordinate of the first point of the frozen line + /// The x coordinate of the second point of the frozen line + /// The x coordinate of the second point of the frozen line + /// Error code + int CurvilinearFrozenLineGet(int meshKernelId, + int frozenLineId, + ref double xFirstFrozenLineCoordinate, + ref double yFirstFrozenLineCoordinate, + ref double xSecondFrozenLineCoordinate, + ref double ySecondFrozenLineCoordinate); + + /// + /// Gets the number of stored frozen lines in the state + /// + /// The id of the mesh state + /// The number of stored frozen lines in the state + /// Error code + int CurvilinearFrozenLinesGetCount(int meshKernelId, ref int numFrozenLines); + + /// + /// Gets the ids of the frozen lines. + /// + /// The id of the mesh state + /// The frozen line ids + /// Error code + int CurvilinearFrozenLinesGetIds(int meshKernelId, out int[] frozenLinesIds); + /// /// Sets the start and end nodes of the line to shift /// @@ -576,13 +610,12 @@ int CurvilinearSetLineLineShift(int meshKernelId, double ySecondGridLineNode); /// - /// Smooths a curvilinear grid + /// Smooths the curvilinear grid inside a block /// - /// The meshKernelId of the block to orthogonalize - /// The number of smoothing iterations to perform + /// The meshKernelId /// The x coordinate of the lower left corner of the block to smooth /// The y coordinate of the lower left corner of the block to smooth - /// The x coordinate of the right corner of the block to smooth + /// The x coordinate of the lower corner of the block to smooth /// The y coordinate of the upper right corner of the block to smooth /// Error code int CurvilinearSmoothing(int meshKernelId, @@ -918,7 +951,7 @@ int Mesh2dAveragingInterpolation(int meshKernelId, /// The input polygons /// int Mesh2dCasulliDerefinementOnPolygon(int meshKernelId, - [In] DisposableGeometryList geometryListPolygon); + DisposableGeometryList geometryListPolygon); /// @@ -927,8 +960,8 @@ int Mesh2dCasulliDerefinementOnPolygon(int meshKernelId, /// Id of the mesh state /// The elements to be removed /// Error code - int Mesh2dCasulliDerefinementElements([In] int meshKernelId, - [In][Out] ref DisposableGeometryList geometryListElements); + int Mesh2dCasulliDerefinementElements(int meshKernelId, + ref DisposableGeometryList geometryListElements); /// /// Get the list of elements that will be removed after applying the Casulli de-refinement algorithm to a mesh on polygon @@ -937,9 +970,9 @@ int Mesh2dCasulliDerefinementElements([In] int meshKernelId, /// The input polygon /// The elements to be removed /// Error code - int Mesh2dCasulliDerefinementElementsOnPolygon([In] int meshKernelId, - [In] DisposableGeometryList geometryListPolygon, - [In][Out] ref DisposableGeometryList geometryListElements); + int Mesh2dCasulliDerefinementElementsOnPolygon(int meshKernelId, + DisposableGeometryList geometryListPolygon, + ref DisposableGeometryList geometryListElements); /// /// Refine a whole mesh using the Casulli algorithm @@ -955,7 +988,7 @@ int Mesh2dCasulliDerefinementElementsOnPolygon([In] int meshKernelId, /// The input polygons /// int Mesh2dCasulliRefinementOnPolygon(int meshKernelId, - [In] DisposableGeometryList geometryListPolygon); + DisposableGeometryList geometryListPolygon); /// /// Perform inner orthogonalization iteration @@ -987,7 +1020,7 @@ int Mesh2dComputeOrthogonalization(int meshKernelId, /// The mesh to merge to the the current domain /// Fraction of the shortest edge (along an edge to be connected) to use when determining neighbour edge closeness /// Error code - int Mesh2dConnectMeshes([In] int meshKernelId, in DisposableMesh2D disposableMesh2D, double searchFraction); + int Mesh2dConnectMeshes(int meshKernelId, in DisposableMesh2D disposableMesh2D, double searchFraction); /// /// Converts the projection of a mesh2d @@ -996,9 +1029,9 @@ int Mesh2dComputeOrthogonalization(int meshKernelId, /// The new projection for the mesh /// The UTM zone and information string /// Error code - int Mesh2dConvertProjection([In] int meshKernelId, - [In] ProjectionOptions projection, - [In] string zone); + int Mesh2dConvertProjection(int meshKernelId, + ProjectionOptions projection, + string zone); /// /// Converts a mesh into a curvilinear grid, with the grid expanding outward from a specified starting point. @@ -1008,9 +1041,9 @@ int Mesh2dConvertProjection([In] int meshKernelId, /// The x coordinate of the point identifying the face where to start the conversion /// The y coordinate of the point identifying the face where to start the conversion /// Error code - int Mesh2dConvertCurvilinear([In] int meshKernelId, - [In] double startingFaceCoordinateX, - [In] double startingFaceCoordinateY); + int Mesh2dConvertCurvilinear(int meshKernelId, + double startingFaceCoordinateX, + double startingFaceCoordinateY); /// /// Count the number of hanging edges in a mesh2d. @@ -1070,14 +1103,14 @@ int Mesh2dDeleteEdge(int meshKernelId, double xCoordinate, double yCoordinate, d /// Id of the grid state /// The index of the edge to delete /// true if the edge has been deleted, false if not - int Mesh2dDeleteEdgeByIndex(int meshKernelId, [In] int edgeIndex); + int Mesh2dDeleteEdgeByIndex(int meshKernelId, int edgeIndex); /// /// Deletes all hanging edges. An hanging edge is an edge where one of the two nodes is not connected. /// /// The id of the mesh state /// Error code - int Mesh2dDeleteHangingEdges([In] int meshKernelId); + int Mesh2dDeleteHangingEdges(int meshKernelId); /// /// Deletes a node with specified @@ -1626,7 +1659,7 @@ int Mesh2dRefineBasedOnSamples(int meshKernelId, in DisposableGeometryList dispo /// The id of the mesh state /// The polylines describing the network /// Error code - int Network1dSet([In] int meshKernelId, in DisposableGeometryList polylines); + int Network1dSet(int meshKernelId, in DisposableGeometryList polylines); /// /// Convert network chainages to mesh1d nodes and edges diff --git a/src/MeshKernelNET/Api/MeshKernelApi.cs b/src/MeshKernelNET/Api/MeshKernelApi.cs index 0fe5b61..70645fc 100644 --- a/src/MeshKernelNET/Api/MeshKernelApi.cs +++ b/src/MeshKernelNET/Api/MeshKernelApi.cs @@ -4,6 +4,7 @@ using System.Runtime.InteropServices; using MeshKernelNET.Helpers; using MeshKernelNET.Native; +using NetTopologySuite.Operation.Valid; namespace MeshKernelNET.Api { @@ -214,11 +215,6 @@ public int CurvilinearFinalizeLineShift(int meshKernelId) return MeshKernelDll.CurvilinearFinalizeLineShift(meshKernelId); } - public int CurvilinearFinalizeOrthogonalize(int meshKernelId) - { - return MeshKernelDll.CurvilinearFinalizeOrthogonalize(meshKernelId); - } - public int CurvilinearGridGetData(int meshKernelId, out DisposableCurvilinearGrid disposableCurvilinearGrid) { var curvilinearGrid = new CurvilinearGridNative(); @@ -362,13 +358,6 @@ public int CurvilinearInitializeOrthogonalGridFromSplines(int meshKernelId, ref splinesToCurvilinearParametersNative); } - public int CurvilinearInitializeOrthogonalize(int meshKernelId, - in OrthogonalizationParameters orthogonalizationParameters) - { - var orthogonalizationParametersNative = orthogonalizationParameters.ToOrthogonalizationParametersNative(); - return MeshKernelDll.CurvilinearInitializeOrthogonalize(meshKernelId, ref orthogonalizationParametersNative); - } - public int CurvilinearInsertFace(int meshKernelId, double xCoordinate, double yCoordinate) { return MeshKernelDll.CurvilinearInsertFace(meshKernelId, xCoordinate, yCoordinate); @@ -460,9 +449,20 @@ public int CurvilinearMoveNodeLineShift(int meshKernelId, return MeshKernelDll.CurvilinearMoveNodeLineShift(meshKernelId, xFromCoordinate, yFromCoordinate, xToCoordinate, yToCoordinate); } - public int CurvilinearOrthogonalize(int meshKernelId) + public int CurvilinearOrthogonalize(int meshKernelId, + ref OrthogonalizationParameters orthogonalizationParameters, + double xLowerLeftCorner, + double yLowerLeftCorner, + double xUpperRightCorner, + double yUpperRightCorner) { - return MeshKernelDll.CurvilinearOrthogonalize(meshKernelId); + var orthogonalizationParametersNative = orthogonalizationParameters.ToOrthogonalizationParametersNative(); + return MeshKernelDll.CurvilinearOrthogonalize(meshKernelId, + ref orthogonalizationParametersNative, + xLowerLeftCorner, + yLowerLeftCorner, + xUpperRightCorner, + yUpperRightCorner); } public int CurvilinearRefine(int meshKernelId, @@ -499,30 +499,70 @@ public int CurvilinearSetBlockLineShift(int meshKernelId, yUpperRightCorner); } - public int CurvilinearSetBlockOrthogonalize(int meshKernelId, - double xLowerLeftCorner, - double yLowerLeftCorner, - double xUpperRightCorner, - double yUpperRightCorner) - { - return MeshKernelDll.CurvilinearSetBlockOrthogonalize(meshKernelId, - xLowerLeftCorner, - yLowerLeftCorner, - xUpperRightCorner, - yUpperRightCorner); - } - - public int CurvilinearSetFrozenLinesOrthogonalize(int meshKernelId, + public int CurvilinearFrozenLineAdd(int meshKernelId, double xFirstGridLineNode, double yFirstGridLineNode, double xSecondGridLineNode, - double yUpperRightCorner) + double ySecondGridLineNode, + ref int frozenLineId) + { + return MeshKernelDll.CurvilinearFrozenLineAdd(meshKernelId, + xFirstGridLineNode, + yFirstGridLineNode, + xSecondGridLineNode, + ySecondGridLineNode, + ref frozenLineId); + } + + public int CurvilinearFrozenLineDelete(int meshKernelId, int frozenLineId) + { + return MeshKernelDll.CurvilinearFrozenLineDelete(meshKernelId, frozenLineId); + } + public int CurvilinearFrozenLineIsValid(int meshKernelId, int frozenLineId, ref bool isValid) { - return MeshKernelDll.CurvilinearSetFrozenLinesOrthogonalize(meshKernelId, - xFirstGridLineNode, - yFirstGridLineNode, - xSecondGridLineNode, - yUpperRightCorner); + return MeshKernelDll.CurvilinearFrozenLineIsValid(meshKernelId, frozenLineId, ref isValid); + } + + public int CurvilinearFrozenLineGet(int meshKernelId, + int frozenLineId, + ref double xFirstGridLineNode, + ref double yFirstGridLineNode, + ref double xSecondGridLineNode, + ref double ySecondGridLineNode) + { + return MeshKernelDll.CurvilinearFrozenLineGet(meshKernelId, + frozenLineId, + ref xFirstGridLineNode, + ref yFirstGridLineNode, + ref xSecondGridLineNode, + ref ySecondGridLineNode); + } + + public int CurvilinearFrozenLinesGetCount(int meshKernelId, ref int numFrozenLines) + { + return MeshKernelDll.CurvilinearFrozenLinesGetCount(meshKernelId, ref numFrozenLines); + } + + public int CurvilinearFrozenLinesGetIds(int meshKernelId, out int[] frozenLinesIds) + { + int numFrozenLines = -1; + MeshKernelDll.CurvilinearFrozenLinesGetCount(meshKernelId, ref numFrozenLines); + if (numFrozenLines < 0) + { + frozenLinesIds = null; + return -1; + } + + frozenLinesIds = new int[numFrozenLines]; + if (numFrozenLines == 0) + { + return 0; + } + IntPtr frozenLinesIdsPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)) * frozenLinesIds.Length); + int success = MeshKernelDll.CurvilinearFrozenLinesGetIds(meshKernelId, frozenLinesIdsPtr); + Marshal.Copy(frozenLinesIdsPtr, frozenLinesIds, 0, frozenLinesIds.Length); + Marshal.FreeCoTaskMem(frozenLinesIdsPtr); + return success; } public int CurvilinearSetLineLineShift(int meshKernelId, diff --git a/src/MeshKernelNET/Native/MeshKernelDll.cs b/src/MeshKernelNET/Native/MeshKernelDll.cs index f6546c8..8f6329d 100644 --- a/src/MeshKernelNET/Native/MeshKernelDll.cs +++ b/src/MeshKernelNET/Native/MeshKernelDll.cs @@ -280,14 +280,6 @@ public static extern int CurvilinearDerefine([In] int meshKernelId, [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_finalize_line_shift", CallingConvention = CallingConvention.Cdecl)] public static extern int CurvilinearFinalizeLineShift([In] int meshKernelId); - /// - /// Finalizes the curvilinear orthogonalization algorithm - /// - /// Id of the mesh state - /// Error code - [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_finalize_orthogonalize", CallingConvention = CallingConvention.Cdecl)] - public static extern int CurvilinearFinalizeOrthogonalize([In] int meshKernelId); - /// /// Gets the curvilinear grid data as a CurvilinearGrid struct (converted as set of edges and nodes) /// @@ -373,16 +365,6 @@ internal static extern int CurvilinearInitializeOrthogonalGridFromSplines([In] i [In] ref CurvilinearParametersNative curvilinearParametersNative, [In] ref SplinesToCurvilinearParametersNative splinesToCurvilinearParameters); - /// - /// Initializes the orthogonal curvilinear algorithm - /// - /// The id of the mesh state - /// The orthogonalization parameters to use in the algorithm - /// Error code - [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_initialize_orthogonalize", CallingConvention = CallingConvention.Cdecl)] - internal static extern int CurvilinearInitializeOrthogonalize([In] int meshKernelId, - [In] ref OrthogonalizationParametersNative orthogonalizationParameters); - /// /// Inserts a new face on a curvilinear grid. The new face will be inserted on top of the closest edge by linear /// extrapolation. @@ -530,10 +512,20 @@ internal static extern int CurvilinearMoveNodeLineShift([In] int meshKernelId, /// /// Orthogonalize a curvilinear grid /// - /// The id of the mesh state + /// The id of the mesh state + /// orthogonalizationParameters The orthogonalization parameters to use in the algorithm + /// xLowerLeftCorner The x coordinate of the lower left corner of the block to orthogonalize + /// yLowerLeftCorner The y coordinate of the lower left corner of the block to orthogonalize + /// xUpperRightCorner The x coordinate of the upper right corner of the block to orthogonalize + /// yUpperRightCorner The y coordinate of the upper right corner of the block to orthogonalize /// Error code [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_orthogonalize", CallingConvention = CallingConvention.Cdecl)] - internal static extern int CurvilinearOrthogonalize([In] int meshKernelId); + internal static extern int CurvilinearOrthogonalize([In] int meshKernelId, + [In] ref OrthogonalizationParametersNative orthogonalizationParameters, + [In] double xLowerLeftCorner, + [In] double yLowerLeftCorner, + [In] double xUpperRightCorner, + [In] double yUpperRightCorner); /// /// Directional curvilinear grid refinement. Additional gridlines are added perpendicularly to the segment defined by @@ -587,36 +579,78 @@ internal static extern int CurvilinearSetBlockLineShift([In] int meshKernelId, [In] double yUpperRightCorner); /// - /// efine a block on the curvilinear grid where to perform orthogonalization - /// - /// The meshKernelId of the block to orthogonalize - /// The xLowerLeftCorner of the block to orthogonalize - /// The yLowerLeftCorner of the block to orthogonalize - /// The xUpperRightCorner of the block to orthogonalize - /// The yUpperRightCorner of the block to orthogonalize - /// Error code - [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_set_block_orthogonalize", CallingConvention = CallingConvention.Cdecl)] - internal static extern int CurvilinearSetBlockOrthogonalize([In] int meshKernelId, - [In] double xLowerLeftCorner, - [In] double yLowerLeftCorner, - [In] double xUpperRightCorner, - [In] double yUpperRightCorner); - - /// - /// Freezes a line in the curvilinear orthogonalization process + /// Adds a frozen in the meshkernel state. A frozen line is stored as a pair of coordinates. + /// The actual edges to freeze are computed during each algorithm execution, as they may change (for example, after a refinement operation). /// /// The id of the mesh state /// The x coordinate of the first point of the line to freeze /// The y coordinate of the first point of the line to freeze /// The x coordinate of the second point of the line to freeze /// The y coordinate of the second point of the line to freeze + /// The id of the frozen line, unique for each frozen line and meshkernel id. It will not be re-issued again for another frozen line + /// Error code + [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_frozen_line_add", CallingConvention = CallingConvention.Cdecl)] + internal static extern int CurvilinearFrozenLineAdd([In] int meshKernelId, + [In] double xFirstGridLineNode, + [In] double yFirstGridLineNode, + [In] double xSecondGridLineNode, + [In] double ySecondGridLineNode, + [In][Out] ref int frozenLineId); + + /// + /// Deletes a frozen line in the meshkernel state + /// + /// The id of the mesh state + /// The id of the frozen line to delete + /// Error code + [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_frozen_line_delete", CallingConvention = CallingConvention.Cdecl)] + internal static extern int CurvilinearFrozenLineDelete([In] int meshKernelId, [In] int frozenLineId); + + /// + /// Checks if a frozen line is valid + /// + /// The id of the mesh state + /// The id of the frozen line to check + /// True if the provided id is valid + /// Error code + [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_frozen_line_is_valid", CallingConvention = CallingConvention.Cdecl)] + internal static extern int CurvilinearFrozenLineIsValid([In] int meshKernelId, [In] int frozenLineId, [In][Out] ref bool isValid); + + /// + /// Gets the coordinates of the frozen line + /// + /// The id of the mesh state + /// The id of the frozen line to delete + /// The x coordinate of the first point of the frozen line + /// The y coordinate of the first point of the frozen line + /// The x coordinate of the second point of the frozen line + /// The x coordinate of the second point of the frozen line + /// Error code + [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_frozen_line_get", CallingConvention = CallingConvention.Cdecl)] + internal static extern int CurvilinearFrozenLineGet([In] int meshKernelId, + [In] int frozenLineId, + [In][Out] ref double xFirstFrozenLineCoordinate, + [In][Out] ref double yFirstFrozenLineCoordinate, + [In][Out] ref double xSecondFrozenLineCoordinate, + [In][Out] ref double ySecondFrozenLineCoordinate); + + /// + /// Gets the number of stored frozen lines in the state + /// + /// The id of the mesh state + /// The number of stored frozen lines in the state + /// Error code + [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_frozen_lines_get_count", CallingConvention = CallingConvention.Cdecl)] + internal static extern int CurvilinearFrozenLinesGetCount([In] int meshKernelId, [In][Out] ref int numFrozenLines); + + /// + /// Gets the ids of the frozen lines. + /// + /// The id of the mesh state + /// The frozen line ids /// Error code - [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_set_frozen_lines_orthogonalize", CallingConvention = CallingConvention.Cdecl)] - internal static extern int CurvilinearSetFrozenLinesOrthogonalize([In] int meshKernelId, - [In] double xFirstGridLineNode, - [In] double yFirstGridLineNode, - [In] double xSecondGridLineNode, - [In] double ySecondGridLineNode); + [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_frozen_lines_get_ids", CallingConvention = CallingConvention.Cdecl)] + internal static extern int CurvilinearFrozenLinesGetIds([In] int meshKernelId, [In][Out] IntPtr frozenLinesIds); /// /// Sets the start and end nodes of the line to shift @@ -639,10 +673,10 @@ internal static extern int CurvilinearSetLineLineShift([In] int meshKernelId, /// /// The meshKernelId of the block to orthogonalize /// The number of smoothing iterations to perform - /// The x coordinate of the lower left corner of the block to smooth - /// The y coordinate of the lower left corner of the block to smooth - /// The x coordinate of the right corner of the block to smooth - /// The y coordinate of the upper right corner of the block to smooth + /// The x coordinate of the lower left corner + /// The y coordinate of the lower left corner + /// The x coordinate of the upper right corner + /// The y coordinate of the upper right corner /// Error code [DllImport(MeshKernelDllName, EntryPoint = "mkernel_curvilinear_smoothing", CallingConvention = CallingConvention.Cdecl)] internal static extern int CurvilinearSmoothing([In] int meshKernelId, diff --git a/test/MeshKernelNETTest/Api/MeshKernelCurvilinearTest.cs b/test/MeshKernelNETTest/Api/MeshKernelCurvilinearTest.cs index 05218a5..fd72a27 100644 --- a/test/MeshKernelNETTest/Api/MeshKernelCurvilinearTest.cs +++ b/test/MeshKernelNETTest/Api/MeshKernelCurvilinearTest.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel.Design; using GeoAPI.Geometries; using MeshKernelNET.Api; using NetTopologySuite.Algorithm; @@ -562,12 +563,22 @@ public void CurvilinearOrthogonalizeWithFrozenLineThroughAPI() Assert.AreEqual(0, api.CurvilinearSet(id, grid)); // Execute var orthogonalizationParameters = OrthogonalizationParameters.CreateDefault(); - Assert.AreEqual(0, api.CurvilinearInitializeOrthogonalize(id, orthogonalizationParameters)); - Assert.AreEqual(0, api.CurvilinearSetFrozenLinesOrthogonalize(id, 20.0, 0.0, 20.0, 10.0), 0); - Assert.AreEqual(0, api.CurvilinearFinalizeOrthogonalize(id)); + int frozenLineId = -1; + Assert.AreEqual(0, api.CurvilinearFrozenLineAdd(id, + 10.0, + 0.0, + 10.0, + 10.0, + ref frozenLineId)); + Assert.AreEqual(0, frozenLineId); + Assert.AreEqual(0, api.CurvilinearOrthogonalize(id, + ref orthogonalizationParameters, + 20.0, + 0.0, + 20.0, + 10.0)); // Assert - int gridOut = api.CurvilinearGridGetData(id, out curvilinearGrid); Assert.NotNull(gridOut); } @@ -593,11 +604,14 @@ public void CurvilinearSmoothingThroughAPI() id = api.AllocateState(0); Assert.AreEqual(0, api.CurvilinearSet(id, grid)); + // Execute + int frozenLineId = -1; + Assert.AreEqual(0, api.CurvilinearFrozenLineAdd(id, 10.0,0.0,10.0,10.0, ref frozenLineId)); + Assert.AreEqual(0, frozenLineId); Assert.AreEqual(0, api.CurvilinearSmoothing(id, 10, 10.0, 20.0, 30.0, 20.0)); // Assert - Assert.AreEqual(0, api.CurvilinearGridGetData(id, out curvilinearGrid)); } finally @@ -773,15 +787,13 @@ public void CurvilinearOrthogonalizeOnBlockThroughAPI() { // Prepare id = api.AllocateState(0); - Assert.AreEqual(0, api.CurvilinearSet(id, grid)); + // Execute var orthogonalizationParameters = OrthogonalizationParameters.CreateDefault(); - Assert.AreEqual(0, api.CurvilinearInitializeOrthogonalize(id, orthogonalizationParameters)); - Assert.AreEqual(0, api.CurvilinearSetBlockOrthogonalize(id, 0.0, 0.0, 30.0, 30.0), 0); - Assert.AreEqual(0, api.CurvilinearFinalizeOrthogonalize(id)); - // Assert + Assert.AreEqual(0, api.CurvilinearOrthogonalize(id, ref orthogonalizationParameters, 0.0, 0.0, 30.0, 30.0), 0); + // Assert Assert.AreEqual(0, api.CurvilinearGridGetData(id, out curvilinearGrid)); Assert.AreEqual((5, 5), (curvilinearGrid.NumM, curvilinearGrid.NumN)); } @@ -1425,6 +1437,165 @@ public void CurvilinearGetNodeLocationIndex_DoesNotFindNearest_OutsideBoundingBo // Assert Assert.That(actualIndex,Is.EqualTo(expectedIndex)); } - + + [Test] + public void CurvilinearSetAndDeleteFrozenLines_ShouldSetAndDeleteFrozenLines() + { + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int forzenLineId = -1; + + // Set and delete + int returnCode = api.CurvilinearFrozenLineAdd(id, + 0.0, + 0.0, + 0.0, + 2.0, + ref forzenLineId); + Assert.That(forzenLineId, Is.EqualTo(0)); + + returnCode = api.CurvilinearFrozenLineDelete(id, forzenLineId); + Assert.That(returnCode, Is.EqualTo(0)); + + returnCode = api.CurvilinearFrozenLineAdd(id, + 0.0, + 0.0, + 0.0, + 2.0, + ref forzenLineId); + Assert.That(returnCode, Is.EqualTo(0)); + + // Id is always increasing + Assert.That(forzenLineId, Is.EqualTo(1)); + + } + + [Test] + public void CurvilinearFrozenLineAdd_ShouldReturnValidId() + { + // Arrange + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + + // Act + int returnCode = api.CurvilinearFrozenLineAdd(id, 0.0, 0.0, 0.0, 2.0, ref frozenLineId); + + // Assert + Assert.That(returnCode, Is.EqualTo(0)); + Assert.That(frozenLineId, Is.EqualTo(0)); + } + + [Test] + public void CurvilinearFrozenLinesGetCount_ShouldReturnCorrectCount() + { + // Arrange + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + api.CurvilinearFrozenLineAdd(id, 0.0, 0.0, 0.0, 2.0, ref frozenLineId); + + // Act + int numFrozenLines = 0; + int returnCode = api.CurvilinearFrozenLinesGetCount(id, ref numFrozenLines); + + // Assert + Assert.That(returnCode, Is.EqualTo(0)); + Assert.That(numFrozenLines, Is.EqualTo(1)); + } + + [Test] + public void CurvilinearFrozenLinesGetIds_ShouldReturnCorrectIds() + { + // Arrange + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + api.CurvilinearFrozenLineAdd(id, 0.0, 0.0, 0.0, 2.0, ref frozenLineId); + + // Act + int numFrozenLines = 1; + int[] frozenLinesIds; + int returnCode = api.CurvilinearFrozenLinesGetIds(id, out frozenLinesIds); + + // Assert + Assert.That(returnCode, Is.EqualTo(0)); + Assert.That(frozenLinesIds[0], Is.EqualTo(frozenLineId)); + } + + [Test] + public void CurvilinearFrozenLineValid_ShouldReturnTrueForValidLine() + { + // Arrange + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + api.CurvilinearFrozenLineAdd(id, 0.0, 0.0, 0.0, 2.0, ref frozenLineId); + + // Act + bool isValid = false; + int returnCode = api.CurvilinearFrozenLineIsValid(id, frozenLineId, ref isValid); + + // Assert + Assert.That(returnCode, Is.EqualTo(0)); + Assert.That(isValid, Is.True); + } + + [Test] + public void CurvilinearFrozenLineGet_ShouldReturnCorrectCoordinates() + { + // Arrange + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + api.CurvilinearFrozenLineAdd(id, 0.0, 0.0, 0.0, 2.0, ref frozenLineId); + + // Act + double xFirstGridLineNode = 0.0; + double yFirstGridLineNode = 0.0; + double xSecondGridLineNode = 0.0; + double ySecondGridLineNode = 0.0; + int returnCode = api.CurvilinearFrozenLineGet(id, frozenLineId, ref xFirstGridLineNode, ref yFirstGridLineNode, ref xSecondGridLineNode, ref ySecondGridLineNode); + + // Assert + Assert.That(returnCode, Is.EqualTo(0)); + Assert.That(xFirstGridLineNode, Is.EqualTo(0.0).Within(1e-9)); + Assert.That(yFirstGridLineNode, Is.EqualTo(0.0).Within(1e-9)); + Assert.That(xSecondGridLineNode, Is.EqualTo(0.0).Within(1e-9)); + Assert.That(ySecondGridLineNode, Is.EqualTo(2.0).Within(1e-9)); + } + + [Test] + public void CurvilinearFrozenLineAdd_ShouldIncrementId() + { + // Arrange + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + api.CurvilinearFrozenLineAdd(id, 0.0, 0.0, 0.0, 2.0, ref frozenLineId); + + // Act + int newFrozenLineId = -1; + int returnCode = api.CurvilinearFrozenLineAdd(id, 1.0, 1.0, 1.0, 3.0, ref newFrozenLineId); + + // Assert + Assert.That(returnCode, Is.EqualTo(0)); + Assert.That(newFrozenLineId, Is.GreaterThan(frozenLineId)); + } + + [Test] + public void CurvilinearSetAndDeleteFrozenLinesTwice_ShouldAddAndDeleteFrozenLineAndReturnErrorCode() + { + CreateGrid(5, 4, 1.0, 1.0, 1.0, 1.0); + int frozenLineId = -1; + + // Set and delete + int returnCode = api.CurvilinearFrozenLineAdd(id, + 0.0, + 0.0, + 0.0, + 2.0, + ref frozenLineId); + Assert.That(frozenLineId, Is.EqualTo(0)); + + returnCode = api.CurvilinearFrozenLineDelete(id, frozenLineId); + Assert.That(returnCode, Is.EqualTo(0)); + returnCode = api.CurvilinearFrozenLineDelete(id, frozenLineId); + Assert.That(returnCode, Is.EqualTo(1)); + } + } }