#pragma once #include "collections.h" // IWYU pragma: keep IterableCollection #include "geoDataMesh.h" #include "surface.h" #include #include class GeoData : public GeoDataMesh { private: const OpenMesh::Helpers::Property surface {this}; public: static GeoData loadFromAsciiGrid(const std::filesystem::path &); static GeoData createFlat(GlobalPosition2D lower, GlobalPosition2D upper, GlobalDistance h); using IntersectionLocation = std::pair; using IntersectionResult = std::optional; [[nodiscard]] IntersectionResult intersectRay(const Ray &) const; [[nodiscard]] IntersectionResult intersectRay(const Ray &, FaceHandle start) const; struct WalkStep { FaceHandle current; FaceHandle previous {}; HalfedgeHandle exitHalfedge {}; GlobalPosition2D exitPosition {}; }; struct WalkStepCurve : public WalkStep { Angle angle {}; }; template using Consumer = const std::function &; template using Tester = const std::function &; void walk(const PointFace & from, GlobalPosition2D to, Consumer op) const; void walkUntil(const PointFace & from, GlobalPosition2D to, Tester op) const; void walk(const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Consumer op) const; void walkUntil( const PointFace & from, GlobalPosition2D to, GlobalPosition2D centre, Tester op) const; void boundaryWalk(Consumer) const; void boundaryWalk(Consumer, HalfedgeHandle start) const; void boundaryWalkUntil(Tester) const; void boundaryWalkUntil(Tester, HalfedgeHandle start) const; [[nodiscard]] HalfedgeHandle findEntry(GlobalPosition2D from, GlobalPosition2D to) const; struct SetHeightsOpts { static constexpr auto DEFAULT_NEAR_NODE_TOLERANACE = 500.F; static constexpr auto DEFAULT_MAX_SLOPE = 0.5F; const Surface * surface = nullptr; RelativeDistance nearNodeTolerance = DEFAULT_NEAR_NODE_TOLERANACE; RelativeDistance maxSlope = DEFAULT_MAX_SLOPE; }; std::vector setHeights(std::span triangleStrip, const SetHeightsOpts &); [[nodiscard]] auto getExtents() const { return std::tie(lowerExtent, upperExtent); } template requires(std::derived_from) [[nodiscard]] auto getSurface(const HandleT handle) const { assert(handle.is_valid()); return property(surface, handle); } protected: [[nodiscard]] VertexHandle setPoint(GlobalPosition3D point, const SetHeightsOpts &); void updateAllVertexNormals(); template void updateAllVertexNormals(const R &); void updateVertexNormal(VertexHandle); virtual void afterChange(); private: GlobalPosition3D lowerExtent {}, upperExtent {}; };