Skip to content

Commit

Permalink
GRIDEDIT-998 solve crash on mesh deletion (#320 | GRIDEDIT-998_crash_…
Browse files Browse the repository at this point in the history
…on_mesh_deletion)
  • Loading branch information
lucacarniato authored May 6, 2024
1 parent 0703dc1 commit 46527aa
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 12 deletions.
17 changes: 13 additions & 4 deletions libs/MeshKernel/include/MeshKernel/BoundingBox.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ namespace meshkernel
};

/// @brief Merge two bounding boxes into a single bounding box that will contain both of the original.
BoundingBox Merge(const BoundingBox& b1, const BoundingBox& b2);
static BoundingBox Merge(const BoundingBox& b1, const BoundingBox& b2);

/// @brief Create a non overlapping bounding box
static BoundingBox CreateNonOverlappingBoundingBox();

} // namespace meshkernel

Expand Down Expand Up @@ -208,12 +211,19 @@ void meshkernel::BoundingBox::Reset(const std::vector<T>& points, size_t start,
m_upperRight = Point(maxx, maxy);
}

inline meshkernel::BoundingBox meshkernel::Merge(const BoundingBox& b1, const BoundingBox& b2)
meshkernel::BoundingBox meshkernel::Merge(const BoundingBox& b1, const BoundingBox& b2)
{
Point lowerLeft{std::min(b1.lowerLeft().x, b2.lowerLeft().x), std::min(b1.lowerLeft().y, b2.lowerLeft().y)};
Point upperRight{std::max(b1.upperRight().x, b2.upperRight().x), std::max(b1.upperRight().y, b2.upperRight().y)};

return BoundingBox(lowerLeft, upperRight);
return {lowerLeft, upperRight};
}

meshkernel::BoundingBox meshkernel::CreateNonOverlappingBoundingBox()
{
Point lowerLeft(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
Point upperRight(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
return {lowerLeft, upperRight};
}

inline meshkernel::Vector meshkernel::BoundingBox::Delta() const
Expand All @@ -223,7 +233,6 @@ inline meshkernel::Vector meshkernel::BoundingBox::Delta() const

inline bool meshkernel::BoundingBox::Overlaps(const BoundingBox& other) const
{

const auto& otherLowerleft = other.lowerLeft();
const auto& otherUpperRight = other.upperRight();
if (m_upperRight.x < otherLowerleft.x ||
Expand Down
26 changes: 18 additions & 8 deletions libs/MeshKernel/src/Mesh2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2246,20 +2246,24 @@ std::unique_ptr<Mesh2D> Mesh2D::Merge(const Mesh2D& mesh1, const Mesh2D& mesh2)

meshkernel::BoundingBox Mesh2D::GetBoundingBox() const
{

Point lowerLeft(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
Point upperRight = -lowerLeft;
Point upperRight(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());

const auto numNodes = GetNumNodes();
for (UInt e = 0; e < numNodes; ++e)
for (UInt n = 0; n < numNodes; ++n)
{
lowerLeft.x = std::min(lowerLeft.x, m_nodes[e].x);
lowerLeft.y = std::min(lowerLeft.y, m_nodes[e].y);
upperRight.x = std::max(upperRight.x, m_nodes[e].x);
upperRight.y = std::max(upperRight.y, m_nodes[e].y);
[[unlikely]] if (!m_nodes[n].IsValid())
{
continue;
}

lowerLeft.x = std::min(lowerLeft.x, m_nodes[n].x);
lowerLeft.y = std::min(lowerLeft.y, m_nodes[n].y);
upperRight.x = std::max(upperRight.x, m_nodes[n].x);
upperRight.y = std::max(upperRight.y, m_nodes[n].y);
}

return BoundingBox(lowerLeft, upperRight);
return {lowerLeft, upperRight};
}

std::vector<meshkernel::BoundingBox> Mesh2D::GetEdgesBoundingBoxes() const
Expand All @@ -2268,6 +2272,12 @@ std::vector<meshkernel::BoundingBox> Mesh2D::GetEdgesBoundingBoxes() const
result.reserve(GetNumEdges());
for (const auto& e : m_edges)
{
if (e.first == constants::missing::uintValue || e.second == constants::missing::uintValue)
{
result.emplace_back(CreateNonOverlappingBoundingBox());
continue;
}

result.emplace_back(BoundingBox::CreateBoundingBox(m_nodes[e.first], m_nodes[e.second]));
}

Expand Down
72 changes: 72 additions & 0 deletions libs/MeshKernel/tests/src/Mesh2DTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1338,3 +1338,75 @@ TEST(Mesh2D, Mesh2DToCurvilinear_WithMixedMesh_ShouldCreatePartialCurvilinearMes
ASSERT_EQ(0.0, curvilinearGrid->GetNode(2, 2).x);
ASSERT_EQ(20.0, curvilinearGrid->GetNode(2, 2).y);
}

TEST(Mesh2D, GetBoundingBox_WithANonEmptyMesh_ShouldGetAValidBoundingBox)
{
// Prepare
const auto mesh = MakeRectangularMeshForTesting(10,
10,
10.0,
10.0,
meshkernel::Projection::cartesian);
// Execute
const auto boundingBox = mesh->GetBoundingBox();

// Assert
ASSERT_EQ(boundingBox.lowerLeft().x, 0.0);
ASSERT_EQ(boundingBox.lowerLeft().y, 0.0);
ASSERT_EQ(boundingBox.upperRight().x, 10.0);
ASSERT_EQ(boundingBox.upperRight().y, 10.0);
}

TEST(Mesh2D, GetBoundingBox_WithAnEmptyMesh_ShouldGetAnEmptyBoundingBox)
{
// Prepare
const auto mesh = MakeRectangularMeshForTesting(10,
10,
10.0,
10.0,
meshkernel::Projection::cartesian);

const auto polygon = meshkernel::Polygons({}, meshkernel::Projection::cartesian);
const auto deletionOption = meshkernel::Mesh2D::DeleteMeshOptions::InsideNotIntersected;

meshkernel::Point lowerLeft(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
meshkernel::Point upperRight(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());

// Execute
auto undoAction = mesh->DeleteMesh(polygon, deletionOption, false);
auto boundingBox = mesh->GetBoundingBox();

// Assert
ASSERT_EQ(boundingBox.lowerLeft().x, lowerLeft.x);
ASSERT_EQ(boundingBox.lowerLeft().y, lowerLeft.y);
ASSERT_EQ(boundingBox.upperRight().x, upperRight.x);
ASSERT_EQ(boundingBox.upperRight().y, upperRight.y);
}

TEST(Mesh2D, GetEdgesBoundingBox_WithAnInvalidEdge_ShouldGetOneInvalidEdgeBoundingBox)
{
// Prepare
const auto mesh = MakeRectangularMeshForTesting(10,
10,
10.0,
10.0,
meshkernel::Projection::cartesian);
// Execute
const auto undoAction = mesh->DeleteEdge(0);
const auto edgesBoundingBoxes = mesh->GetEdgesBoundingBoxes();

// Assert
meshkernel::Point lowerLeft(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
meshkernel::Point upperRight(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());

const double tolerance = 1e-6;
ASSERT_NEAR(edgesBoundingBoxes[0].lowerLeft().x, lowerLeft.x, tolerance);
ASSERT_NEAR(edgesBoundingBoxes[0].lowerLeft().y, lowerLeft.y, tolerance);
ASSERT_NEAR(edgesBoundingBoxes[0].upperRight().x, upperRight.x, tolerance);
ASSERT_NEAR(edgesBoundingBoxes[0].upperRight().y, upperRight.y, tolerance);

ASSERT_NEAR(edgesBoundingBoxes[1].lowerLeft().x, 0.0, tolerance);
ASSERT_NEAR(edgesBoundingBoxes[1].lowerLeft().y, 1.1111111111111112, tolerance);
ASSERT_NEAR(edgesBoundingBoxes[1].upperRight().x, 1.1111111111111112, tolerance);
ASSERT_NEAR(edgesBoundingBoxes[1].upperRight().y, 1.1111111111111112, tolerance);
}

0 comments on commit 46527aa

Please sign in to comment.