Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GRIDEDIT-1526: Refactor ProjectionsOptions, correct orthogonalization… #386

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
4 changes: 2 additions & 2 deletions libs/MeshKernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ set(
${SRC_DIR}/Entities.cpp
${SRC_DIR}/FlipEdges.cpp
${SRC_DIR}/Hessian.cpp
${SRC_DIR}/LandBoundaries.cpp
${SRC_DIR}/LandBoundary.cpp
${SRC_DIR}/Mesh.cpp
${SRC_DIR}/Mesh1D.cpp
Expand All @@ -60,6 +59,7 @@ set(
${SRC_DIR}/RemoveDisconnectedRegions.cpp
${SRC_DIR}/SamplesHessianCalculator.cpp
${SRC_DIR}/Smoother.cpp
${SRC_DIR}/SnappingMesh2DToLandBoundariesCalculator.cpp
${SRC_DIR}/SplineAlgorithms.cpp
${SRC_DIR}/Splines.cpp
${SRC_DIR}/SplitRowColumnOfMesh.cpp
Expand Down Expand Up @@ -158,7 +158,6 @@ set(
${DOMAIN_INC_DIR}/FlipEdges.hpp
${DOMAIN_INC_DIR}/Formatting.hpp
${DOMAIN_INC_DIR}/Hessian.hpp
${DOMAIN_INC_DIR}/LandBoundaries.hpp
${DOMAIN_INC_DIR}/LandBoundary.hpp
${DOMAIN_INC_DIR}/Mesh.hpp
${DOMAIN_INC_DIR}/Mesh1D.hpp
Expand All @@ -184,6 +183,7 @@ set(
${DOMAIN_INC_DIR}/RemoveDisconnectedRegions.hpp
${DOMAIN_INC_DIR}/SamplesHessianCalculator.hpp
${DOMAIN_INC_DIR}/Smoother.hpp
${DOMAIN_INC_DIR}/SnappingMesh2DToLandBoundariesCalculator.hpp
${DOMAIN_INC_DIR}/SplineAlgorithms.hpp
${DOMAIN_INC_DIR}/Splines.hpp
${DOMAIN_INC_DIR}/SplitRowColumnOfMesh.hpp
Expand Down
8 changes: 4 additions & 4 deletions libs/MeshKernel/include/MeshKernel/FlipEdges.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace meshkernel
{
// Forward declarations
class Mesh2D;
class LandBoundaries;
class SnappingMesh2DToLandBoundariesCalculator;

/// @brief A class used to improve mesh connectivity.
///
Expand All @@ -53,7 +53,7 @@ namespace meshkernel
/// @param[in] triangulateFaces Whether to triangulate all faces or not
/// @param[in] projectToLandBoundary Whether to project to land boundaries or not
FlipEdges(Mesh2D& mesh,
LandBoundaries& landBoundary,
SnappingMesh2DToLandBoundariesCalculator& landBoundary,
bool triangulateFaces,
bool projectToLandBoundary);

Expand Down Expand Up @@ -85,8 +85,8 @@ namespace meshkernel
/// @param[in] nodeIndex The index of the node to process
void DeleteEdgeFromNode(UInt edgeIndex, UInt nodeIndex) const;

Mesh2D& m_mesh; ///< A pointer to the 2D mesh
LandBoundaries& m_landBoundaries; ///< A pointer to the land boundaries
Mesh2D& m_mesh; ///< A pointer to the 2D mesh
SnappingMesh2DToLandBoundariesCalculator& m_snappingToLandBoundariesCalculator; ///< A pointer to the land boundaries

bool m_triangulateFaces = false; ///< Whether to triangulate faces
bool m_projectToLandBoundary = false; ///< Whether to project to land boundary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

#pragma once

#include <MeshKernel/LandBoundaries.hpp>
#include <MeshKernel/SnappingMesh2DToLandBoundariesCalculator.hpp>
#include <MeshKernel/Parameters.hpp>
#include <MeshKernel/UndoActions/UndoAction.hpp>

Expand Down Expand Up @@ -55,7 +55,7 @@ namespace meshkernel
///
/// - An initialization step: The original mesh boundaries are saved. In
/// case the mesh needs to be snapped to the land boundaries, the indices of the land boundaries
/// are mapped to the boundary mesh edges (`LandBoundaries::FindNearestMeshBoundary`).
/// are mapped to the boundary mesh edges (`SnappingMesh2DToLandBoundariesCalculator::FindNearestMeshBoundary`).
///
/// - An outer loop, which itself is composed of the following parts:
///
Expand Down Expand Up @@ -94,8 +94,8 @@ namespace meshkernel
std::unique_ptr<Smoother> smoother,
std::unique_ptr<Orthogonalizer> orthogonalizer,
std::unique_ptr<Polygons> polygon,
std::unique_ptr<LandBoundaries> landBoundaries,
LandBoundaries::ProjectToLandBoundaryOption projectToLandBoundaryOption,
std::unique_ptr<SnappingMesh2DToLandBoundariesCalculator> landBoundaries,
SnappingMesh2DToLandBoundariesCalculator::ProjectionsOptions projectToLandBoundaryOption,
const OrthogonalizationParameters& orthogonalizationParameters);

/// @brief Initializes the object
Expand Down Expand Up @@ -140,13 +140,13 @@ namespace meshkernel
/// @brief Compute nodes local coordinates (comp_local_coords)
void ComputeCoordinates() const;

Mesh2D& m_mesh; ///< A reference to mesh
std::unique_ptr<Smoother> m_smoother; ///< A pointer to the smoother
std::unique_ptr<Orthogonalizer> m_orthogonalizer; ///< A pointer to the orthogonalizer
std::unique_ptr<Polygons> m_polygons; ///< The polygon pointer where to perform the orthogonalization
std::unique_ptr<LandBoundaries> m_landBoundaries; ///< The land boundaries pointer
LandBoundaries::ProjectToLandBoundaryOption m_projectToLandBoundaryOption; ///< The project to land boundary option
OrthogonalizationParameters m_orthogonalizationParameters; ///< The orthogonalization parameters
Mesh2D& m_mesh; ///< A reference to mesh
std::unique_ptr<Smoother> m_smoother; ///< A pointer to the smoother
std::unique_ptr<Orthogonalizer> m_orthogonalizer; ///< A pointer to the orthogonalizer
std::unique_ptr<Polygons> m_polygons; ///< The polygon pointer where to perform the orthogonalization
std::unique_ptr<SnappingMesh2DToLandBoundariesCalculator> m_snappingToLandBoundariesCalculator; ///< The land boundaries pointer
SnappingMesh2DToLandBoundariesCalculator::ProjectionsOptions m_projectOptions; ///< The projection options
OrthogonalizationParameters m_orthogonalizationParameters; ///< The orthogonalization parameters

std::vector<UInt> m_localCoordinatesIndices; ///< Used in sphericalAccurate projection (iloc)
std::vector<Point> m_localCoordinates; ///< Used in sphericalAccurate projection (xloc,yloc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@

#include <memory>

#include <MeshKernel/Entities.hpp>
#include <MeshKernel/LandBoundary.hpp>
#include <MeshKernel/UndoActions/UndoAction.hpp>

Expand All @@ -40,37 +39,53 @@ namespace meshkernel
class Polygons;
class Mesh2D;

/// @brief A class describing land boundaries.
/// @brief A class implementing the snapping mesh to land boundaries algorithm
/// These are used to visualise the land-water interface.
///
/// The main responsibility of this class is to store the land boundary polygons,
/// categorize them based on their proximity to a mesh
/// and provide the functionality to assign each mesh node to the appropriate land boundary polyline.
class LandBoundaries
class SnappingMesh2DToLandBoundariesCalculator
{

public:
/// Enumerator describing the options how to project to the land boundary
enum class ProjectToLandBoundaryOption
/// Enumerator describing the options how to project
enum class ProjectionsOptions
{
DoNotProjectToLandBoundary = 0,
ToOriginalNetBoundary = 1,
OuterMeshBoundaryToLandBoundary = 2,
InnerAndOuterMeshBoundaryToLandBoundary = 3,
WholeMesh = 4
DoNotProject = 0,
ToOriginalMeshBoundary = 1,
OuterMeshBoundaryToLandBoundaries = 2,
InnerAndOuterMeshBoundariesToLandboundaries = 3
};

/// @brief Default constructor
LandBoundaries() = default;
SnappingMesh2DToLandBoundariesCalculator() = default;

/// @brief Default constructor
/// @param[in] landBoundary A vector of points defining the land boundary.
/// @param[in] mesh The current 2d mesh.
/// @param[in] polygons A polygon for selecting part of the land boundaries.
LandBoundaries(const std::vector<Point>& landBoundary,
Mesh2D& mesh,
const Polygons& polygons);
SnappingMesh2DToLandBoundariesCalculator(const std::vector<Point>& landBoundary,
Mesh2D& mesh,
const Polygons& polygons);

/// @brief Find the mesh boundary line closest to the land boundary (find_nearest_meshline).
/// @param[in] projectionOption The option describing the projection to the land boundary.
void FindNearestMeshBoundary(ProjectionsOptions projectionOption);

/// @brief Snap the mesh nodes to land boundaries (snap_to_landboundary)
[[nodiscard]] std::unique_ptr<UndoAction> ComputeSnapping() const;

/// @brief Gets the land boundary segment index for each mesh node
/// @param[in] node The mesh node index
/// @returns The land boundary segment index
UInt LandBoundarySegmentIndex(UInt node) const { return m_meshNodesLandBoundarySegments[node]; }

/// @brief Get the land boundary used by the calculator
/// @returns A reference to the land boundary used by the calculator
const LandBoundary& LandBoundary() const { return m_landBoundary; }

private:
/// @brief The portion of the boundary segments close enough to the mesh boundary are flagged (admin_landboundary_segments)
///
/// This method uses a Point vector member variable and identifies
Expand All @@ -79,20 +94,6 @@ namespace meshkernel
/// \image html LandBoundarySegmentation_step1.jpg "Land boundary segmentation"
void Administrate();

/// @brief Find the mesh boundary line closest to the land boundary (find_nearest_meshline).
/// @param[in] projectToLandBoundaryOption The option describing the projection to the land boundary.
void FindNearestMeshBoundary(ProjectToLandBoundaryOption projectToLandBoundaryOption);

/// @brief Snap the mesh nodes to land boundaries (snap_to_landboundary)
[[nodiscard]] std::unique_ptr<UndoAction> SnapMeshToLandBoundaries() const;

/// @brief Gets the number of land boundary nodes.
/// @return The number of land boundary nodes.
auto GetNumNodes() const { return m_landBoundary.GetNumNodes(); }

std::vector<UInt> m_meshNodesLandBoundarySegments; ///< Mesh nodes to land boundary mapping (lanseg_map)

private:
/// @brief Build an additional boundary for not assigned nodes (connect_boundary_paths)
/// @param[in] edgeIndex
/// @param[in] initialize
Expand Down Expand Up @@ -122,26 +123,6 @@ namespace meshkernel
/// @param[in] landBoundaryIndex The land boundary polyline index
void ComputeMeshNodeMask(UInt landBoundaryIndex);

/// @brief Mask the mesh nodes to be considered in the shortest path algorithm for the current segmentIndex.
/// It is setting leftIndex, rightIndex, leftEdgeRatio, rightEdgeRatio (masknodes).
//// \image html LandBoundaryNodeFlagging_step2.jpg "Flag the mesh node close to the land boundary"
/// @param[in] segmentIndex
/// @param[in] meshBoundOnly
/// @param[in] startLandBoundaryIndex
/// @param[in] endLandBoundaryIndex
/// @param[out] leftIndex
/// @param[out] rightIndex
/// @param[out] leftEdgeRatio
/// @param[out] rightEdgeRatio
void ComputeMask(UInt segmentIndex,
bool meshBoundOnly,
UInt startLandBoundaryIndex,
UInt endLandBoundaryIndex,
UInt& leftIndex,
UInt& rightIndex,
double& leftEdgeRatio,
double& rightEdgeRatio);

/// @brief Mask all face close to a land boundary, starting from a seed of others and growing from there (maskcells)
/// @param[in] landBoundaryIndex The land boundary polyline index
/// @param[in] initialFaces The initial face seeds
Expand Down Expand Up @@ -183,7 +164,8 @@ namespace meshkernel

Mesh2D& m_mesh; ///< A reference to mesh
const Polygons m_polygons; ///< A copy of the polygons
LandBoundary m_landBoundary; ///< The nodes on the land boundary
meshkernel::LandBoundary m_landBoundary; ///< A copy of the land boundary
std::vector<UInt> m_meshNodesLandBoundarySegments; ///< Mesh nodes to land boundary segments (lanseg_map)
std::vector<Point> m_polygonNodesCache; ///< Array of points (e.g. points of a face)
std::vector<std::pair<UInt, UInt>> m_validLandBoundaries; ///< Start and end indices of valid land boundaries (lanseg_startend)
std::vector<UInt> m_nodeFaceIndices; ///< For each node, the indices of the faces including them
Expand Down
22 changes: 11 additions & 11 deletions libs/MeshKernel/src/FlipEdges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include <MeshKernel/Entities.hpp>
#include <MeshKernel/Exceptions.hpp>
#include <MeshKernel/FlipEdges.hpp>
#include <MeshKernel/LandBoundaries.hpp>
#include <MeshKernel/SnappingMesh2DToLandBoundariesCalculator.hpp>
#include <MeshKernel/Mesh2D.hpp>
#include <MeshKernel/Operations.hpp>
#include <MeshKernel/UndoActions/CompoundUndoAction.hpp>
Expand All @@ -38,16 +38,16 @@ using meshkernel::FlipEdges;
using meshkernel::Mesh2D;

FlipEdges::FlipEdges(Mesh2D& mesh,
LandBoundaries& landBoundary,
SnappingMesh2DToLandBoundariesCalculator& landBoundary,
bool triangulateFaces,
bool projectToLandBoundary) : m_mesh(mesh),
m_landBoundaries(landBoundary),
m_snappingToLandBoundariesCalculator(landBoundary),
m_triangulateFaces(triangulateFaces),
m_projectToLandBoundary(projectToLandBoundary)
{
if (m_projectToLandBoundary)
{
m_landBoundaries.FindNearestMeshBoundary(LandBoundaries::ProjectToLandBoundaryOption::WholeMesh);
m_snappingToLandBoundariesCalculator.FindNearestMeshBoundary(SnappingMesh2DToLandBoundariesCalculator::ProjectionsOptions::OuterMeshBoundaryToLandBoundaries);
}
}

Expand Down Expand Up @@ -353,9 +353,9 @@ int FlipEdges::ComputeTopologyFunctional(UInt edge,
auto nL = static_cast<int>(m_mesh.m_nodesNumEdges[nodeLeft]) - static_cast<int>(OptimalNumberOfConnectedNodes(nodeLeft));
auto nR = static_cast<int>(m_mesh.m_nodesNumEdges[nodeRight]) - static_cast<int>(OptimalNumberOfConnectedNodes(nodeRight));

if (m_projectToLandBoundary && m_landBoundaries.GetNumNodes() > 0)
if (m_projectToLandBoundary && m_snappingToLandBoundariesCalculator.LandBoundary().GetNumNodes() > 0)
{
if (m_landBoundaries.m_meshNodesLandBoundarySegments[firstNode] != constants::missing::uintValue && m_landBoundaries.m_meshNodesLandBoundarySegments[secondNode] != constants::missing::uintValue)
if (m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(firstNode) != constants::missing::uintValue && m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(secondNode) != constants::missing::uintValue)
{
// Edge is associated with a land boundary -> keep the edge
return largeTopologyFunctionalValue;
Expand Down Expand Up @@ -390,7 +390,7 @@ int FlipEdges::ComputeTopologyFunctional(UInt edge,

int FlipEdges::DifferenceFromOptimum(UInt nodeIndex, UInt firstNode, UInt secondNode) const
{
if (m_landBoundaries.m_meshNodesLandBoundarySegments[nodeIndex] == constants::missing::uintValue)
if (m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(nodeIndex) == constants::missing::uintValue)
{
return static_cast<int>(m_mesh.m_nodesNumEdges[nodeIndex]) - static_cast<int>(OptimalNumberOfConnectedNodes(nodeIndex));
}
Expand Down Expand Up @@ -448,7 +448,7 @@ int FlipEdges::DifferenceFromOptimum(UInt nodeIndex, UInt firstNode, UInt second
auto otherNode = OtherNodeOfEdge(m_mesh.GetEdge(edgeIndex), nodeIndex);

UInt num = 1;
while (m_landBoundaries.m_meshNodesLandBoundarySegments[otherNode] == constants::missing::uintValue &&
while (m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(otherNode) == constants::missing::uintValue &&
!m_mesh.IsEdgeOnBoundary(edgeIndex) &&
currentEdgeIndexInNodeEdges != edgeIndexConnectingSecondNode)
{
Expand All @@ -459,7 +459,7 @@ int FlipEdges::DifferenceFromOptimum(UInt nodeIndex, UInt firstNode, UInt second
}

UInt firstEdgeInPathIndex = constants::missing::uintValue;
if (m_landBoundaries.m_meshNodesLandBoundarySegments[otherNode] != constants::missing::uintValue ||
if (m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(otherNode) != constants::missing::uintValue ||
m_mesh.IsEdgeOnBoundary(edgeIndex))
{
firstEdgeInPathIndex = edgeIndex;
Expand All @@ -473,7 +473,7 @@ int FlipEdges::DifferenceFromOptimum(UInt nodeIndex, UInt firstNode, UInt second
edgeIndex = m_mesh.m_nodesEdges[nodeIndex][currentEdgeIndexInNodeEdges];
otherNode = OtherNodeOfEdge(m_mesh.GetEdge(edgeIndex), nodeIndex);
num = num + 1;
while (m_landBoundaries.m_meshNodesLandBoundarySegments[otherNode] == constants::missing::uintValue &&
while (m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(otherNode) == constants::missing::uintValue &&
!m_mesh.IsEdgeOnBoundary(edgeIndex) &&
currentEdgeIndexInNodeEdges != edgeIndexConnectingFirstNode &&
edgeIndex != firstEdgeInPathIndex)
Expand All @@ -488,7 +488,7 @@ int FlipEdges::DifferenceFromOptimum(UInt nodeIndex, UInt firstNode, UInt second
}
}

if ((m_landBoundaries.m_meshNodesLandBoundarySegments[otherNode] != constants::missing::uintValue ||
if ((m_snappingToLandBoundariesCalculator.LandBoundarySegmentIndex(otherNode) != constants::missing::uintValue ||
m_mesh.IsEdgeOnBoundary(edgeIndex)) &&
edgeIndex != firstEdgeInPathIndex)
{
Expand Down
Loading
Loading