Skip to content

Commit

Permalink
GRIDEDIT-1393: bug fix
Browse files Browse the repository at this point in the history
  • Loading branch information
lucacarniato committed Sep 11, 2024
1 parent 019995a commit f38b1f5
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 20 deletions.
26 changes: 20 additions & 6 deletions libs/MeshKernel/src/Polygon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,31 @@ bool meshkernel::Polygon::Contains(const Point& pnt) const
void meshkernel::Polygon::SnapToLandBoundary(const size_t startIndex, const size_t endIndex, const LandBoundary& landBoundary)
{

if (startIndex > endIndex || endIndex >= m_nodes.size())
if (startIndex < 0 || startIndex >= m_nodes.size())
{
throw ConstraintError("The indices are not valid: {}, {}.", startIndex, endIndex);
throw ConstraintError("The start index is not valid: {}.", startIndex);
}

// snap polygon section to land boundary
for (size_t i = startIndex; i <= endIndex; ++i)
if (endIndex < 0 || endIndex >= m_nodes.size())
{
if (m_nodes[i].IsValid())
throw ConstraintError("The end index is not valid: {}.", endIndex);
}

const auto numNodes = Size();
for (auto i = 0u; i < numNodes; i++)
{
// Adjust currentIndex for wrap-around
const auto currentIndex = (startIndex + i) % numNodes;

if (m_nodes[currentIndex].IsValid())
{
m_nodes[i] = landBoundary.FindNearestPoint(m_nodes[i], m_projection);
m_nodes[currentIndex] = landBoundary.FindNearestPoint(m_nodes[currentIndex], m_projection);
}

// Break the loop if we have reached the lastIndex
if (currentIndex == endIndex)
{
break;
}
}

Expand Down
6 changes: 0 additions & 6 deletions libs/MeshKernel/src/Polygons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,6 @@ void Polygons::SnapToLandBoundary(const LandBoundary& landBoundary, UInt startIn
endIndex = static_cast<UInt>(m_enclosures[0].Outer().Size()) - 1;
}

// TODO is it valid to snap a single point to the land boundary?
if (startIndex >= endIndex)
{
throw ConstraintError("The start index is greater than the end index: {} >= {}.", startIndex, endIndex);
}

const auto [polygonIndex, polygonStartNode, polygonEndNode] = PolygonIndex(startIndex, endIndex);
m_enclosures[polygonIndex].SnapToLandBoundary(polygonStartNode, polygonEndNode, landBoundary);
}
Expand Down
9 changes: 1 addition & 8 deletions libs/MeshKernelApi/src/MeshKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3248,13 +3248,6 @@ namespace meshkernelapi
endIndex);
}

if (startIndex > endIndex)
{
throw meshkernel::ConstraintError("Invalid polygon points range: startIndex greater than endIndex {} > {}",
startIndex,
endIndex);
}

if (endIndex >= polygon.num_coordinates)
{
throw meshkernel::ConstraintError("Invalid polygon points range: endIndex greater than number of polygon coordinates {} >= {}",
Expand All @@ -3276,7 +3269,7 @@ namespace meshkernelapi

const std::vector<meshkernel::Point>& snappedPolygonPoints = polygons.Enclosure(enclosureIndex).Outer().Nodes();

for (int i = startIndex; i <= endIndex; ++i)
for (int i = 0; i < polygon.num_coordinates; ++i)
{
polygon.coordinates_x[i] = snappedPolygonPoints[i].x;
polygon.coordinates_y[i] = snappedPolygonPoints[i].y;
Expand Down
1 change: 1 addition & 0 deletions libs/MeshKernelApi/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(SRC_LIST
${SRC_DIR}/ErrorHandlingTests.cpp
${SRC_DIR}/Mesh2DRefinmentTests.cpp
${SRC_DIR}/Mesh2DTests.cpp
${SRC_DIR}/PolygonTests.cpp
${SRC_DIR}/UndoTests.cpp
)

Expand Down
40 changes: 40 additions & 0 deletions libs/MeshKernelApi/tests/src/PolygonTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "MeshKernelApi/MeshKernel.hpp"
#include <gtest/gtest.h>
#include <random>

// namespace aliases
namespace mk = meshkernel;
namespace mkapi = meshkernelapi;

TEST(PolygonTests, PolygonRefinementTests)
{
int meshKernelId;
auto errorCode = meshkernelapi::mkernel_allocate_state(0, meshKernelId);
ASSERT_EQ(meshkernel::ExitCode::Success, errorCode);

meshkernelapi::GeometryList land;
land.geometry_separator = meshkernel::constants::missing::doubleValue;
std::vector xLand{0.0, 10.0};
std::vector yLand{10.0, 10.0};
land.coordinates_x = xLand.data();
land.coordinates_y = yLand.data();
land.num_coordinates = static_cast<int>(xLand.size());

meshkernelapi::GeometryList polygon;
polygon.geometry_separator = meshkernel::constants::missing::doubleValue;
std::vector xPolygon{1.0, 1.0, 7.0, 7.0, 1.0};
std::vector yPolygon{9.0, 0.0, 0.0, 9.0, 9.0};
polygon.coordinates_x = xPolygon.data();
polygon.coordinates_y = yPolygon.data();
polygon.num_coordinates = static_cast<int>(xPolygon.size());

errorCode = mkernel_polygon_snap_to_landboundary(meshKernelId, land, polygon, 3, 0);
ASSERT_EQ(meshkernel::ExitCode::Success, errorCode);

constexpr double tolerance = 1e-6;
ASSERT_NEAR(10.0, yPolygon[0], tolerance);
ASSERT_NEAR(0.0, yPolygon[1], tolerance);
ASSERT_NEAR(0.0, yPolygon[2], tolerance);
ASSERT_NEAR(10.0, yPolygon[3], tolerance);
ASSERT_NEAR(10.0, yPolygon[4], tolerance);
}

0 comments on commit f38b1f5

Please sign in to comment.