MeshKernel
Mesh2D.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2021.
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation version 3.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // contact: delft3d.support@deltares.nl
18 // Stichting Deltares
19 // P.O. Box 177
20 // 2600 MH Delft, The Netherlands
21 //
22 // All indications and logos of, and references to, "Delft3D" and "Deltares"
23 // are registered trademarks of Stichting Deltares, and remain the property of
24 // Stichting Deltares. All rights reserved.
25 //
26 //------------------------------------------------------------------------------
27 
28 #pragma once
29 #include <array>
30 #include <ranges>
31 #include <utility>
32 #include <vector>
33 
34 #include <MeshKernel/Entities.hpp>
35 #include <MeshKernel/Mesh.hpp>
36 #include <MeshKernel/Polygon.hpp>
37 #include <MeshKernel/UndoActions/CompoundUndoAction.hpp>
38 #include <MeshKernel/UndoActions/SphericalCoordinatesOffsetAction.hpp>
39 #include <MeshKernel/UndoActions/UndoAction.hpp>
40 
43 namespace meshkernel
44 {
45  // Forward declarations
46  class CurvilinearGrid;
47  class Polygons;
48  class GeometryList;
49 
55  class Mesh2D final : public Mesh
56  {
57  public:
58  using Mesh::CommitAction;
59  using Mesh::RestoreAction;
60 
63  {
64  InsideNotIntersected = 0,
65  InsideAndIntersected = 1,
66  FacesWithIncludedCircumcenters = 2
67  };
68 
70  enum class NodeTypes
71  {
72  internalNode,
73  onRing,
74  cornerNode,
75  hangingNode,
76  other
77  };
78 
80  enum class Property
81  {
82  Orthogonality = 0,
83  EdgeLength = 1
84  };
85 
87  ~Mesh2D() override = default;
88 
90  Mesh2D();
91 
94  explicit Mesh2D(Projection projection);
95 
100  Mesh2D(const std::vector<Edge>& edges,
101  const std::vector<Point>& nodes,
102  Projection projection);
103 
110  Mesh2D(const std::vector<Edge>& edges,
111  const std::vector<Point>& nodes,
112  const std::vector<std::vector<UInt>>& faceNodes,
113  const std::vector<UInt>& numFaceNodes,
114  Projection projection);
115 
120  Mesh2D(const std::vector<Point>& nodes, const Polygons& polygons, Projection projection);
121 
123  void Administrate(CompoundUndoAction* undoAction = nullptr) override;
124 
126  void ComputeCircumcentersMassCentersAndFaceAreas(bool computeMassCenters = false);
127 
129  void FindFaces();
130 
134  void FindFacesGivenFaceNodesMapping(const std::vector<std::vector<UInt>>& faceNodes,
135  const std::vector<UInt>& numFaceNodes);
136 
140  [[nodiscard]] std::unique_ptr<SphericalCoordinatesOffsetAction> OffsetSphericalCoordinates(double minx, double maxx);
141 
143  void CommitAction(const SphericalCoordinatesOffsetAction& undoAction);
144 
148  void RestoreAction(const SphericalCoordinatesOffsetAction& undoAction);
149 
156  std::vector<Point>& polygonNodesCache,
157  std::vector<UInt>& localNodeIndicesCache,
158  std::vector<UInt>& globalEdgeIndicesCache) const;
159 
163  void ComputeFaceClosedPolygon(UInt faceIndex, std::vector<Point>& polygonNodesCache) const;
164 
169  [[nodiscard]] Point ComputeFaceCircumenter(std::vector<Point>& polygon,
170  const std::vector<UInt>& edgesNumFaces) const;
171 
174  [[nodiscard]] std::vector<Point> GetObtuseTrianglesCenters();
175 
179  [[nodiscard]] std::vector<UInt> GetEdgesCrossingSmallFlowEdges(double smallFlowEdgesThreshold);
180 
184  [[nodiscard]] std::vector<Point> GetFlowEdgesCenters(const std::vector<UInt>& edges) const;
185 
208  [[nodiscard]] std::unique_ptr<meshkernel::UndoAction> DeleteSmallFlowEdges(double smallFlowEdgesThreshold);
209 
227  [[nodiscard]] std::unique_ptr<UndoAction> DeleteSmallTrianglesAtBoundaries(double minFractionalAreaTriangles);
228 
230  void ComputeNodeNeighbours();
231 
234  [[nodiscard]] std::vector<double> GetOrthogonality() const;
235 
238  [[nodiscard]] std::vector<double> GetSmoothness() const;
239 
242  void ComputeAspectRatios(std::vector<double>& aspectRatios);
243 
245  void ClassifyNodes();
246 
248  [[nodiscard]] std::unique_ptr<UndoAction> DeleteDegeneratedTriangles();
249 
251  [[nodiscard]] std::unique_ptr<UndoAction> TriangulateFaces();
252 
257  void MakeDualFace(UInt node, double enlargementFactor, std::vector<Point>& dualFace);
258 
262  [[nodiscard]] std::vector<UInt> SortedFacesAroundNode(UInt node) const;
263 
267  [[nodiscard]] std::vector<Point> ComputeBoundaryPolygons(const std::vector<Point>& polygon);
268 
274  void WalkBoundaryFromNode(const Polygon& polygon,
275  std::vector<bool>& isVisited,
276  UInt& currentNode,
277  std::vector<Point>& meshBoundaryPolygon) const;
278 
281  [[nodiscard]] std::vector<UInt> GetHangingEdges() const;
282 
284  [[nodiscard]] std::unique_ptr<UndoAction> DeleteHangingEdges();
285 
289  [[nodiscard]] std::vector<UInt> PointFaceIndices(const std::vector<Point>& points);
290 
296  [[nodiscard]] std::unique_ptr<UndoAction> DeleteMesh(const Polygons& polygon, DeleteMeshOptions deletionOption, bool invertDeletion);
297 
305  [[nodiscard]] std::vector<bool> FilterBasedOnMetric(Location location, Property property, double minValue, double maxValue) const;
306 
311  [[nodiscard]] std::tuple<UInt, UInt> IsSegmentCrossingABoundaryEdge(const Point& firstPoint, const Point& secondPoint) const;
312 
318  [[nodiscard]] std::vector<int> MaskEdgesOfFacesInPolygon(const Polygons& polygons, bool invertSelection, bool includeIntersected) const;
319 
323  [[nodiscard]] std::vector<int> NodeMaskFromEdgeMask(std::vector<int> const& edgeMask) const;
324 
329  [[nodiscard]] std::vector<int> NodeMaskFromPolygon(const Polygons& polygons, bool inside) const;
330 
334  UInt FindOppositeEdge(const UInt faceId, const UInt edgeId) const;
335 
340  UInt NextFace(const UInt faceId, const UInt edgeId) const;
341 
343 
349  static std::unique_ptr<Mesh2D> Merge(const Mesh2D& mesh1, const Mesh2D& mesh2);
350 
354  [[nodiscard]] BoundingBox GetBoundingBox() const;
355 
359  [[nodiscard]] std::vector<BoundingBox> GetEdgesBoundingBoxes() const;
360 
365  void FindFacesConnectedToNode(UInt nodeIndex, std::vector<UInt>& sharedFaces) const;
366 
371  void GetConnectingNodes(UInt nodeIndex, std::vector<UInt>& connectedNodes) const;
372 
379  void FindNodesSharedByFaces(UInt nodeIndex, const std::vector<UInt>& sharedFaces, std::vector<UInt>& connectedNodes, std::vector<std::vector<UInt>>& faceNodeMapping) const;
380 
385  UInt IsStartOrEnd(const UInt edgeId, const UInt nodeId) const;
386 
391  UInt IsLeftOrRight(const UInt elementId, const UInt edgeId) const;
392 
396  UInt FindCommonFace(const UInt edge1, const UInt edge2) const;
397 
398  private:
399  // orthogonalization
400  static constexpr double m_minimumEdgeLength = 1e-4;
401  static constexpr double m_curvilinearToOrthogonalRatio = 0.5;
402  static constexpr double m_minimumCellArea = 1e-12;
403  static constexpr double m_weightCircumCenter = 1.0;
404  static constexpr UInt m_maximumNumberOfHangingNodesAlongEdge = 5;
405 
407  using HangingNodeIndexArray = std::array<UInt, m_maximumNumberOfHangingNodesAlongEdge>;
408 
410  void ComputeAverageAreOfNeighbouringFaces(const UInt faceId, UInt& numNonBoundaryFaces, double& averageOtherFacesArea) const;
411 
413  void FindSmallestCornerAngle(const UInt faceId,
414  double& minCosPhiSmallTriangle,
415  UInt& nodeToPreserve,
416  UInt& firstNodeToMerge,
417  UInt& secondNodeToMerge,
418  UInt& thirdEdgeSmallTriangle) const;
419 
421  void DeleteSmallTriangle(const UInt nodeToPreserve,
422  const UInt firstNodeToMerge,
423  const UInt secondNodeToMerge,
424  bool& nodesMerged,
425  CompoundUndoAction& undoAction);
426 
428  void FindNodesToDelete(const Polygons& polygon,
429  const bool invertDeletion,
430  std::vector<bool>& isNodeInsidePolygon,
431  std::vector<bool>& deleteNode) const;
432 
434  void DeletedMeshNodesAndEdges(const std::function<bool(UInt)>& excludedFace,
435  std::vector<bool>& deleteNode,
436  CompoundUndoAction& deleteMeshAction);
437 
439  std::vector<int> ComputeNodeMask(const Polygons& polygons) const;
440 
442  std::vector<int> ComputeEdgeMask(const std::vector<int>& nodeMask,
443  bool includeIntersected) const;
444 
446  void RemoveIntersected(const std::vector<int>& edgeMask,
447  std::vector<int>& secondEdgeMask) const;
448 
450  void InvertSelection(const std::vector<int>& edgeMask,
451  std::vector<int>& secondEdgeMask) const;
452 
454  std::vector<bool> FindFacesEntirelyInsidePolygon(const std::vector<bool>& isNodeInsidePolygon) const;
455 
460  [[nodiscard]] std::unique_ptr<UndoAction> DeleteMeshFaces(const Polygons& polygon, bool invertDeletion);
461 
472  void FindFacesRecursive(UInt startNode,
473  UInt node,
474  UInt previousEdge,
475  UInt numClosingEdges,
476  std::vector<UInt>& edges,
477  std::vector<UInt>& nodes,
478  std::vector<UInt>& sortedEdges,
479  std::vector<UInt>& sortedNodes,
480  std::vector<Point>& nodalValues);
481 
486  [[nodiscard]] bool HasTriangleNoAcuteAngles(const std::vector<UInt>& faceNodes, const std::vector<Point>& nodes) const;
487 
491  bool HasDuplicateNodes(const UInt numClosingEdges, const std::vector<UInt>& node, std::vector<UInt>& sortedNodes) const;
492 
496  bool HasDuplicateEdgeFaces(const UInt numClosingEdges, const std::vector<UInt>& edges, std::vector<UInt>& sortedEdgesFaces) const;
497 
499  void ResizeAndInitializeFaceVectors();
500 
504  void DoAdministrationGivenFaceNodesMapping(const std::vector<std::vector<UInt>>& faceNodes,
505  const std::vector<UInt>& numFaceNodes);
506 
509  void DoAdministration(CompoundUndoAction* undoAction = nullptr);
510 
512  void InitialiseBoundaryNodeClassification();
513 
515  void ClassifyNode(const UInt nodeId);
516 
518  UInt CountNumberOfValidEdges(const std::vector<UInt>& edgesNumFaces, const UInt numNodes) const;
519 
521  void ComputeMidPointsAndNormals(const std::vector<Point>& polygon,
522  const std::vector<UInt>& edgesNumFaces,
523  const UInt numNodes,
524  std::array<Point, m_maximumNumberOfNodesPerFace>& middlePoints,
525  std::array<Point, m_maximumNumberOfNodesPerFace>& normals,
526  UInt& pointCount) const;
527 
529  Point ComputeCircumCentre(const Point& centerOfMass,
530  const UInt pointCount,
531  const std::array<Point, m_maximumNumberOfNodesPerFace>& middlePoints,
532  const std::array<Point, m_maximumNumberOfNodesPerFace>& normals) const;
533 
535  void ComputeAverageFlowEdgesLength(std::vector<double>& edgesLength,
536  std::vector<double>& averageFlowEdgesLength) const;
537 
539  void ComputeAverageEdgeLength(const std::vector<double>& edgesLength,
540  const std::vector<double>& averageFlowEdgesLength,
541  std::vector<bool>& curvilinearGridIndicator,
542  std::vector<std::array<double, 2>>& averageEdgesLength,
543  std::vector<double>& aspectRatios) const;
544  };
545 
546 } // namespace meshkernel
meshkernel::Projection
Projection
Enumerator describing the supported projections.
Definition: Definitions.hpp:41
meshkernel::Mesh2D::DeleteHangingEdges
std::unique_ptr< UndoAction > DeleteHangingEdges()
Deletes the hanging edges.
meshkernel::Mesh2D::NodeTypes
NodeTypes
Enumerator describing the different node types.
Definition: Mesh2D.hpp:70
meshkernel::Mesh2D::IsLeftOrRight
UInt IsLeftOrRight(const UInt elementId, const UInt edgeId) const
Determine if the element lies on the left or right side of the edge.
meshkernel::Mesh2D::GetHangingEdges
std::vector< UInt > GetHangingEdges() const
Gets the hanging edges.
meshkernel::Mesh2D::TriangulateFaces
std::unique_ptr< UndoAction > TriangulateFaces()
Transform non-triangular faces in triangular faces.
meshkernel::Mesh::RestoreAction
void RestoreAction(const ResetNodeAction &undoAction)
Undo the reset node action.
meshkernel::Mesh2D::ComputeFaceCircumenter
Point ComputeFaceCircumenter(std::vector< Point > &polygon, const std::vector< UInt > &edgesNumFaces) const
For a closed polygon, compute the circumcenter of a face (getcircumcenter)
meshkernel::Mesh2D::DeleteDegeneratedTriangles
std::unique_ptr< UndoAction > DeleteDegeneratedTriangles()
Deletes coinciding triangles.
meshkernel::Mesh2D::MakeDualFace
void MakeDualFace(UInt node, double enlargementFactor, std::vector< Point > &dualFace)
Make a dual face around the node, enlarged by a factor.
meshkernel::Mesh2D::DeleteMeshOptions
DeleteMeshOptions
Enumerator describing the different options to delete a mesh.
Definition: Mesh2D.hpp:62
meshkernel::Mesh2D::NextFace
UInt NextFace(const UInt faceId, const UInt edgeId) const
Get the next face adjacent to the edge on the opposite side.
meshkernel::Mesh2D
A class derived from Mesh, which describes unstructures 2d meshes.
Definition: Mesh2D.hpp:55
meshkernel::Mesh2D::ComputeNodeNeighbours
void ComputeNodeNeighbours()
Computes m_nodesNodes, see class members.
meshkernel::BoundingBox
A class defining a bounding box.
Definition: BoundingBox.hpp:39
meshkernel::Mesh2D::ComputeFaceClosedPolygon
void ComputeFaceClosedPolygon(UInt faceIndex, std::vector< Point > &polygonNodesCache) const
For a face create a closed polygon.
meshkernel::Mesh2D::FindNodesSharedByFaces
void FindNodesSharedByFaces(UInt nodeIndex, const std::vector< UInt > &sharedFaces, std::vector< UInt > &connectedNodes, std::vector< std::vector< UInt >> &faceNodeMapping) const
Find all unique nodes.
meshkernel::Point
A struct describing a point in a two-dimensional space.
Definition: Point.hpp:40
meshkernel::Location
Location
Mesh locations enumeration.
Definition: Definitions.hpp:74
meshkernel::Mesh2D::IsSegmentCrossingABoundaryEdge
std::tuple< UInt, UInt > IsSegmentCrossingABoundaryEdge(const Point &firstPoint, const Point &secondPoint) const
Inquire if a segment is crossing a face.
meshkernel::Mesh2D::CommitAction
void CommitAction(const SphericalCoordinatesOffsetAction &undoAction)
Apply the coordinate offset action.
meshkernel::Mesh2D::FindFacesConnectedToNode
void FindFacesConnectedToNode(UInt nodeIndex, std::vector< UInt > &sharedFaces) const
Find all faces that have the given node as a vertex.
meshkernel::Mesh2D::GetOrthogonality
std::vector< double > GetOrthogonality() const
Get the orthogonality values, the inner product of edges and segments connecting the face circumcente...
meshkernel::Polygon
A closed polygon.
Definition: Polygon.hpp:45
meshkernel::Mesh2D::IsStartOrEnd
UInt IsStartOrEnd(const UInt edgeId, const UInt nodeId) const
Determine if the node is at the start or end of the edge.
meshkernel::Mesh2D::ClassifyNodes
void ClassifyNodes()
Classifies the nodes (makenetnodescoding)
meshkernel::Mesh2D::DeleteMesh
std::unique_ptr< UndoAction > DeleteMesh(const Polygons &polygon, DeleteMeshOptions deletionOption, bool invertDeletion)
Deletes a mesh in a polygon, using several options (delnet)
meshkernel::Mesh2D::DeleteSmallFlowEdges
std::unique_ptr< meshkernel::UndoAction > DeleteSmallFlowEdges(double smallFlowEdgesThreshold)
Deletes small flow edges (removesmallflowlinks, part 1)
meshkernel::Mesh2D::RestoreAction
void RestoreAction(const SphericalCoordinatesOffsetAction &undoAction)
Undo the coordinate offset action.
meshkernel::Mesh2D::MaskEdgesOfFacesInPolygon
std::vector< int > MaskEdgesOfFacesInPolygon(const Polygons &polygons, bool invertSelection, bool includeIntersected) const
Masks the edges of all faces entirely included in all polygons.
meshkernel::Mesh2D::GetEdgesBoundingBoxes
std::vector< BoundingBox > GetEdgesBoundingBoxes() const
Get the bounding boxes of the mesh edges.
meshkernel::Mesh2D::GetObtuseTrianglesCenters
std::vector< Point > GetObtuseTrianglesCenters()
Gets the mass centers of obtuse triangles.
meshkernel
Contains the logic of the C++ static library.
Definition: AveragingInterpolation.hpp:36
meshkernel::Mesh2D::Property
Property
Enumerator for different properties on a 2D mesh.
Definition: Mesh2D.hpp:80
meshkernel::Mesh2D::NodeMaskFromPolygon
std::vector< int > NodeMaskFromPolygon(const Polygons &polygons, bool inside) const
Mask all nodes included in all polygons.
meshkernel::Mesh2D::DeleteSmallTrianglesAtBoundaries
std::unique_ptr< UndoAction > DeleteSmallTrianglesAtBoundaries(double minFractionalAreaTriangles)
Deletes small triangles at the boundaries (removesmallflowlinks, part 2)
meshkernel::Mesh2D::OffsetSphericalCoordinates
std::unique_ptr< SphericalCoordinatesOffsetAction > OffsetSphericalCoordinates(double minx, double maxx)
Offset the x coordinates if m_projection is spherical.
meshkernel::Mesh2D::ComputeCircumcentersMassCentersAndFaceAreas
void ComputeCircumcentersMassCentersAndFaceAreas(bool computeMassCenters=false)
Compute face circumcenters.
meshkernel::Mesh2D::FindOppositeEdge
UInt FindOppositeEdge(const UInt faceId, const UInt edgeId) const
Find edge on the opposite side of the element.
meshkernel::Mesh2D::FindFacesGivenFaceNodesMapping
void FindFacesGivenFaceNodesMapping(const std::vector< std::vector< UInt >> &faceNodes, const std::vector< UInt > &numFaceNodes)
Find remaining face information given the face nodes mapping.
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::Mesh2D::Administrate
void Administrate(CompoundUndoAction *undoAction=nullptr) override
Perform complete administration.
meshkernel::Mesh2D::GetBoundingBox
BoundingBox GetBoundingBox() const
Get the mesh bounding box.
meshkernel::Mesh2D::ComputeAspectRatios
void ComputeAspectRatios(std::vector< double > &aspectRatios)
Gets the aspect ratios (the ratios edges lengths to flow edges lengths)
meshkernel::Mesh2D::GetEdgesCrossingSmallFlowEdges
std::vector< UInt > GetEdgesCrossingSmallFlowEdges(double smallFlowEdgesThreshold)
Gets the edges crossing the small flow edges.
meshkernel::Mesh2D::Merge
static std::unique_ptr< Mesh2D > Merge(const Mesh2D &mesh1, const Mesh2D &mesh2)
Merges mesh connectivity.
meshkernel::Polygons
A class containing a list of polygonaly enclosed regions.
Definition: Polygons.hpp:44
meshkernel::Mesh2D::FindFaces
void FindFaces()
Constructs the face nodes mapping, face mass centers and areas.
meshkernel::Mesh2D::FindCommonFace
UInt FindCommonFace(const UInt edge1, const UInt edge2) const
Find the id of the element that is common to both edges.
meshkernel::Mesh2D::WalkBoundaryFromNode
void WalkBoundaryFromNode(const Polygon &polygon, std::vector< bool > &isVisited, UInt &currentNode, std::vector< Point > &meshBoundaryPolygon) const
Constructs a polygon from the meshboundary, by walking through the mesh.
meshkernel::Mesh2D::~Mesh2D
~Mesh2D() override=default
Default destructor.
meshkernel::Mesh2D::GetConnectingNodes
void GetConnectingNodes(UInt nodeIndex, std::vector< UInt > &connectedNodes) const
Get indices of all nodes that are connected directly to a give node along connected edges.
meshkernel::Mesh::CommitAction
void CommitAction(const ResetNodeAction &undoAction)
Apply the reset node action.
meshkernel::Mesh2D::PointFaceIndices
std::vector< UInt > PointFaceIndices(const std::vector< Point > &points)
For a collection of points, compute the face indices including them.
meshkernel::Mesh2D::GetFlowEdgesCenters
std::vector< Point > GetFlowEdgesCenters(const std::vector< UInt > &edges) const
Gets the flow edges centers from the crossing edges.
meshkernel::Mesh2D::ComputeBoundaryPolygons
std::vector< Point > ComputeBoundaryPolygons(const std::vector< Point > &polygon)
Convert all mesh boundaries to a vector of polygon nodes, including holes (copynetboundstopol)
meshkernel::Mesh2D::FilterBasedOnMetric
std::vector< bool > FilterBasedOnMetric(Location location, Property property, double minValue, double maxValue) const
This method generates a mask indicating which locations are within the specified range of the given m...
meshkernel::Mesh2D::SortedFacesAroundNode
std::vector< UInt > SortedFacesAroundNode(UInt node) const
Sorts the faces around a node, sorted in counter clock wise order.
meshkernel::Mesh
A class describing an unstructured mesh. This class contains the shared functionality between 1d or 2...
Definition: Mesh.hpp:98
meshkernel::Mesh2D::Mesh2D
Mesh2D()
Default constructor.
meshkernel::Mesh2D::ComputeFaceClosedPolygonWithLocalMappings
void ComputeFaceClosedPolygonWithLocalMappings(UInt faceIndex, std::vector< Point > &polygonNodesCache, std::vector< UInt > &localNodeIndicesCache, std::vector< UInt > &globalEdgeIndicesCache) const
For a face create a closed polygon and fill local mapping caches (get_cellpolygon)
meshkernel::Mesh2D::m_maxNumNeighbours
UInt m_maxNumNeighbours
Maximum number of neighbours.
Definition: Mesh2D.hpp:342
meshkernel::Mesh2D::GetSmoothness
std::vector< double > GetSmoothness() const
Gets the smoothness values, ratios of the face areas.
meshkernel::Mesh2D::NodeMaskFromEdgeMask
std::vector< int > NodeMaskFromEdgeMask(std::vector< int > const &edgeMask) const
From the edge mask compute the node mask.