|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| #ifndef MESH_GRID_H
|
| #define MESH_GRID_H
|
|
|
| #include <limits>
|
| #include <set>
|
|
|
| #include <Base/BoundBox.h>
|
|
|
| #include "MeshKernel.h"
|
|
|
|
|
| #define MESH_CT_GRID 256
|
| #define MESH_MAX_GRIDS 100000
|
| #define MESH_CT_GRID_PER_AXIS 20
|
|
|
|
|
| namespace MeshCore
|
| {
|
|
|
| class MeshKernel;
|
| class MeshGeomFacet;
|
| class MeshGrid;
|
|
|
| static constexpr float MESHGRID_BBOX_EXTENSION = 10.0F;
|
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| class MeshExport MeshGrid
|
| {
|
| protected:
|
|
|
|
|
|
|
| explicit MeshGrid(const MeshKernel& rclM);
|
|
|
| MeshGrid();
|
| MeshGrid(const MeshGrid&) = default;
|
| MeshGrid(MeshGrid&&) = default;
|
| MeshGrid& operator=(const MeshGrid&) = default;
|
| MeshGrid& operator=(MeshGrid&&) = default;
|
|
|
|
|
| public:
|
|
|
| virtual ~MeshGrid() = default;
|
|
|
| public:
|
| |
|
|
| virtual void Attach(const MeshKernel& rclM);
|
|
|
| virtual void Rebuild(int iCtGridPerAxis = MESH_CT_GRID_PER_AXIS);
|
|
|
| virtual void Rebuild(unsigned long ulX, unsigned long ulY, unsigned long ulZ);
|
|
|
|
|
|
|
|
|
| virtual unsigned long Inside(
|
| const Base::BoundBox3f& rclBB,
|
| std::vector<ElementIndex>& raulElements,
|
| bool bDelDoubles = true
|
| ) const;
|
|
|
| virtual unsigned long Inside(
|
| const Base::BoundBox3f& rclBB,
|
| std::set<ElementIndex>& raulElementss
|
| ) const;
|
|
|
| virtual unsigned long Inside(
|
| const Base::BoundBox3f& rclBB,
|
| std::vector<ElementIndex>& raulElements,
|
| const Base::Vector3f& rclOrg,
|
| float fMaxDist,
|
| bool bDelDoubles = true
|
| ) const;
|
| |
|
|
| void SearchNearestFromPoint(const Base::Vector3f& pnt, std::set<ElementIndex>& indices) const;
|
|
|
|
|
|
|
|
|
|
|
| unsigned long GetElements(
|
| unsigned long ulX,
|
| unsigned long ulY,
|
| unsigned long ulZ,
|
| std::set<ElementIndex>& raclInd
|
| ) const;
|
| unsigned long GetElements(const Base::Vector3f& rclPoint, std::vector<ElementIndex>& aulFacets) const;
|
|
|
|
|
|
|
| virtual void GetGridLengths(float& rfLenX, float& rfLenY, float& rfLenZ) const
|
| {
|
| rfLenX = _fGridLenX;
|
| rfLenY = _fGridLenY;
|
| rfLenZ = _fGridLenZ;
|
| }
|
|
|
| virtual void GetCtGrids(unsigned long& rulX, unsigned long& rulY, unsigned long& rulZ) const
|
| {
|
| rulX = _ulCtGridsX;
|
| rulY = _ulCtGridsY;
|
| rulZ = _ulCtGridsZ;
|
| }
|
|
|
|
|
|
|
|
|
| inline Base::BoundBox3f GetBoundBox(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
|
|
|
| inline Base::BoundBox3f GetBoundBox() const;
|
|
|
| inline Base::BoundBox3f GetMeshBoundBox() const;
|
|
|
| |
| |
| |
|
|
| unsigned long GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
|
| |
| |
|
|
| bool GetPositionToIndex(
|
| unsigned long id,
|
| unsigned long& ulX,
|
| unsigned long& ulY,
|
| unsigned long& ulZ
|
| ) const;
|
|
|
| unsigned long GetCtElements(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
|
| {
|
| return static_cast<unsigned long>(_aulGrid[ulX][ulY][ulZ].size());
|
| }
|
| |
|
|
| virtual void Validate(const MeshKernel& rclM) = 0;
|
|
|
| virtual bool Verify() const = 0;
|
| |
| |
|
|
| bool CheckPosition(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const;
|
| |
|
|
| virtual void Position(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const;
|
|
|
| inline bool CheckPos(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
|
| |
|
|
| void GetHull(
|
| unsigned long ulX,
|
| unsigned long ulY,
|
| unsigned long ulZ,
|
| unsigned long ulDistance,
|
| std::set<ElementIndex>& raclInd
|
| ) const;
|
|
|
| protected:
|
|
|
| virtual void InitGrid();
|
|
|
| virtual void Clear();
|
|
|
| virtual void CalculateGridLength(int iCtGridPerAxis);
|
|
|
| virtual void RebuildGrid() = 0;
|
|
|
| virtual unsigned long HasElements() const = 0;
|
|
|
| protected:
|
|
|
| std::vector<std::vector<std::vector<std::set<ElementIndex>>>> _aulGrid;
|
| const MeshKernel* _pclMesh;
|
| unsigned long _ulCtElements;
|
| unsigned long _ulCtGridsX;
|
| unsigned long _ulCtGridsY;
|
| unsigned long _ulCtGridsZ;
|
| float _fGridLenX;
|
| float _fGridLenY;
|
| float _fGridLenZ;
|
| float _fMinX;
|
| float _fMinY;
|
| float _fMinZ;
|
|
|
|
|
|
|
| friend class MeshGridIterator;
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshFacetGrid: public MeshGrid
|
| {
|
| public:
|
|
|
|
|
|
|
| explicit MeshFacetGrid(const MeshKernel& rclM);
|
|
|
| MeshFacetGrid() = default;
|
|
|
| MeshFacetGrid(const MeshKernel& rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ);
|
|
|
| MeshFacetGrid(const MeshKernel& rclM, int iCtGridPerAxis);
|
|
|
| MeshFacetGrid(const MeshKernel& rclM, float fGridLen);
|
| MeshFacetGrid(const MeshFacetGrid&) = default;
|
| MeshFacetGrid(MeshFacetGrid&&) = default;
|
|
|
| ~MeshFacetGrid() override = default;
|
| MeshFacetGrid& operator=(const MeshFacetGrid&) = default;
|
| MeshFacetGrid& operator=(MeshFacetGrid&&) = default;
|
|
|
|
|
|
|
|
|
|
|
| unsigned long SearchNearestFromPoint(const Base::Vector3f& rclPt) const;
|
|
|
| unsigned long SearchNearestFromPoint(const Base::Vector3f& rclPt, float fMaxSearchArea) const;
|
| |
|
|
| void SearchNearestFacetInGrid(
|
| unsigned long ulX,
|
| unsigned long ulY,
|
| unsigned long ulZ,
|
| const Base::Vector3f& rclPt,
|
| float& rfMinDist,
|
| ElementIndex& rulFacetInd
|
| ) const;
|
| |
|
|
| void SearchNearestFacetInHull(
|
| unsigned long ulX,
|
| unsigned long ulY,
|
| unsigned long ulZ,
|
| unsigned long ulDistance,
|
| const Base::Vector3f& rclPt,
|
| ElementIndex& rulFacetInd,
|
| float& rfMinDist
|
| ) const;
|
|
|
|
|
|
|
| void Validate(const MeshKernel& rclM) override;
|
|
|
| virtual void Validate();
|
|
|
| bool Verify() const override;
|
|
|
| protected:
|
|
|
| inline void Pos(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const;
|
|
|
| inline void PosWithCheck(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const;
|
| |
| |
|
|
| inline void AddFacet(const MeshGeomFacet& rclFacet, ElementIndex ulFacetIndex, float fEpsilon = 0.0F);
|
|
|
| unsigned long HasElements() const override
|
| {
|
| return _pclMesh->CountFacets();
|
| }
|
|
|
| void RebuildGrid() override;
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshPointGrid: public MeshGrid
|
| {
|
| public:
|
|
|
|
|
|
|
| MeshPointGrid();
|
|
|
| explicit MeshPointGrid(const MeshKernel& rclM);
|
|
|
| MeshPointGrid(const MeshKernel& rclM, int iCtGridPerAxis);
|
|
|
| MeshPointGrid(const MeshKernel& rclM, float fGridLen);
|
|
|
| MeshPointGrid(const MeshKernel& rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ);
|
| MeshPointGrid(const MeshPointGrid&) = default;
|
| MeshPointGrid(MeshPointGrid&&) = default;
|
|
|
| ~MeshPointGrid() override = default;
|
| MeshPointGrid& operator=(const MeshPointGrid&) = default;
|
| MeshPointGrid& operator=(MeshPointGrid&&) = default;
|
|
|
|
|
|
|
| unsigned long FindElements(const Base::Vector3f& rclPoint, std::set<ElementIndex>& aulElements) const;
|
|
|
| void Validate(const MeshKernel& rclM) override;
|
|
|
| virtual void Validate();
|
|
|
| bool Verify() const override;
|
|
|
| protected:
|
| |
|
|
| void AddPoint(const MeshPoint& rclPt, ElementIndex ulPtIndex, float fEpsilon = 0.0F);
|
|
|
| void Pos(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const;
|
|
|
| unsigned long HasElements() const override
|
| {
|
| return _pclMesh->CountPoints();
|
| }
|
|
|
| void RebuildGrid() override;
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshGridIterator
|
| {
|
| public:
|
|
|
| explicit MeshGridIterator(const MeshGrid& rclG);
|
|
|
| Base::BoundBox3f GetBoundBox() const
|
| {
|
| return _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ);
|
| }
|
|
|
| void GetElements(std::vector<ElementIndex>& raulElements) const
|
| {
|
| raulElements.insert(
|
| raulElements.end(),
|
| _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(),
|
| _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()
|
| );
|
| }
|
|
|
| unsigned long GetCtElements() const
|
| {
|
| return _rclGrid.GetCtElements(_ulX, _ulY, _ulZ);
|
| }
|
|
|
|
|
|
|
| void Init()
|
| {
|
| _ulX = _ulY = _ulZ = 0;
|
| }
|
|
|
| bool More() const
|
| {
|
| return (_ulZ < _rclGrid._ulCtGridsZ);
|
| }
|
|
|
| void Next()
|
| {
|
| if (++_ulX >= (_rclGrid._ulCtGridsX)) {
|
| _ulX = 0;
|
| }
|
| else {
|
| return;
|
| }
|
| if (++_ulY >= (_rclGrid._ulCtGridsY)) {
|
| _ulY = 0;
|
| _ulZ++;
|
| }
|
| else {
|
| return;
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
| bool InitOnRay(
|
| const Base::Vector3f& rclPt,
|
| const Base::Vector3f& rclDir,
|
| std::vector<ElementIndex>& raulElements
|
| );
|
|
|
| bool InitOnRay(
|
| const Base::Vector3f& rclPt,
|
| const Base::Vector3f& rclDir,
|
| float fMaxSearchArea,
|
| std::vector<ElementIndex>& raulElements
|
| );
|
|
|
| bool NextOnRay(std::vector<ElementIndex>& raulElements);
|
|
|
|
|
|
|
| void GetGridPos(unsigned long& rulX, unsigned long& rulY, unsigned long& rulZ) const
|
| {
|
| rulX = _ulX;
|
| rulY = _ulY;
|
| rulZ = _ulZ;
|
| }
|
|
|
| protected:
|
| const MeshGrid& GetGrid() const
|
| {
|
| return _rclGrid;
|
| }
|
|
|
| private:
|
| const MeshGrid& _rclGrid;
|
| unsigned long _ulX {0};
|
| unsigned long _ulY {0};
|
| unsigned long _ulZ {0};
|
| Base::Vector3f _clPt;
|
| Base::Vector3f _clDir;
|
| bool _bValidRay {false};
|
| float _fMaxSearchArea {std::numeric_limits<float>::max()};
|
|
|
| struct GridElement
|
| {
|
| GridElement(unsigned long x, unsigned long y, unsigned long z)
|
| : x(x)
|
| , y(y)
|
| , z(z)
|
| {}
|
| bool operator<(const GridElement& pos) const
|
| {
|
| if (x == pos.x) {
|
| if (y == pos.y) {
|
| return z < pos.z;
|
| }
|
| return y < pos.y;
|
| }
|
| return x < pos.x;
|
| }
|
|
|
| private:
|
| unsigned long x, y, z;
|
| };
|
| std::set<GridElement> _cSearchPositions;
|
| };
|
|
|
|
|
|
|
| inline Base::BoundBox3f MeshGrid::GetBoundBox(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
|
| {
|
| float fX = _fMinX + (float(ulX) * _fGridLenX);
|
| float fY = _fMinY + (float(ulY) * _fGridLenY);
|
| float fZ = _fMinZ + (float(ulZ) * _fGridLenZ);
|
|
|
| return Base::BoundBox3f(fX, fY, fZ, fX + _fGridLenX, fY + _fGridLenY, fZ + _fGridLenZ);
|
| }
|
|
|
| inline Base::BoundBox3f MeshGrid::GetBoundBox() const
|
| {
|
| return Base::BoundBox3f(
|
| _fMinX,
|
| _fMinY,
|
| _fMinZ,
|
| _fMinX + (_fGridLenX * float(_ulCtGridsX)),
|
| _fMinY + (_fGridLenY * float(_ulCtGridsY)),
|
| _fMinZ + (_fGridLenZ * float(_ulCtGridsZ))
|
| );
|
| }
|
|
|
| inline Base::BoundBox3f MeshGrid::GetMeshBoundBox() const
|
| {
|
| Base::BoundBox3f clBBenlarged = _pclMesh->GetBoundBox();
|
| clBBenlarged.Enlarge(MESHGRID_BBOX_EXTENSION);
|
|
|
| return clBBenlarged;
|
| }
|
|
|
| inline bool MeshGrid::CheckPos(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
|
| {
|
| return ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ));
|
| }
|
|
|
|
|
|
|
| inline void MeshFacetGrid::Pos(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const
|
| {
|
| rulX = static_cast<unsigned long>((rclPoint.x - _fMinX) / _fGridLenX);
|
| rulY = static_cast<unsigned long>((rclPoint.y - _fMinY) / _fGridLenY);
|
| rulZ = static_cast<unsigned long>((rclPoint.z - _fMinZ) / _fGridLenZ);
|
|
|
| assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ));
|
| }
|
|
|
| inline void MeshFacetGrid::PosWithCheck(
|
| const Base::Vector3f& rclPoint,
|
| unsigned long& rulX,
|
| unsigned long& rulY,
|
| unsigned long& rulZ
|
| ) const
|
| {
|
| if (rclPoint.x < _fMinX) {
|
| rulX = 0;
|
| }
|
| else {
|
| rulX = static_cast<unsigned long>((rclPoint.x - _fMinX) / _fGridLenX);
|
| if (rulX >= _ulCtGridsX) {
|
| rulX = (_ulCtGridsX - 1);
|
| }
|
| }
|
|
|
| if (rclPoint.y < _fMinY) {
|
| rulY = 0;
|
| }
|
| else {
|
| rulY = static_cast<unsigned long>((rclPoint.y - _fMinY) / _fGridLenY);
|
| if (rulY >= _ulCtGridsY) {
|
| rulY = (_ulCtGridsY - 1);
|
| }
|
| }
|
|
|
| if (rclPoint.z < _fMinZ) {
|
| rulZ = 0;
|
| }
|
| else {
|
| rulZ = static_cast<unsigned long>((rclPoint.z - _fMinZ) / _fGridLenZ);
|
| if (rulZ >= _ulCtGridsZ) {
|
| rulZ = (_ulCtGridsZ - 1);
|
| }
|
| }
|
|
|
| assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ));
|
| }
|
|
|
| inline void MeshFacetGrid::AddFacet(const MeshGeomFacet& rclFacet, ElementIndex ulFacetIndex, float )
|
| {
|
| unsigned long ulX {};
|
| unsigned long ulY {};
|
| unsigned long ulZ {};
|
|
|
| unsigned long ulX1 {};
|
| unsigned long ulY1 {};
|
| unsigned long ulZ1 {};
|
| unsigned long ulX2 {};
|
| unsigned long ulY2 {};
|
| unsigned long ulZ2 {};
|
|
|
| Base::BoundBox3f clBB;
|
|
|
| clBB.Add(rclFacet._aclPoints[0]);
|
| clBB.Add(rclFacet._aclPoints[1]);
|
| clBB.Add(rclFacet._aclPoints[2]);
|
|
|
|
|
|
|
|
|
|
|
| Pos(Base::Vector3f(clBB.MinX, clBB.MinY, clBB.MinZ), ulX1, ulY1, ulZ1);
|
| Pos(Base::Vector3f(clBB.MaxX, clBB.MaxY, clBB.MaxZ), ulX2, ulY2, ulZ2);
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
|
|
| if ((ulX1 < ulX2) || (ulY1 < ulY2) || (ulZ1 < ulZ2)) {
|
| for (ulX = ulX1; ulX <= ulX2; ulX++) {
|
| for (ulY = ulY1; ulY <= ulY2; ulY++) {
|
| for (ulZ = ulZ1; ulZ <= ulZ2; ulZ++) {
|
| if (rclFacet.IntersectBoundingBox(GetBoundBox(ulX, ulY, ulZ))) {
|
| _aulGrid[ulX][ulY][ulZ].insert(ulFacetIndex);
|
| }
|
| }
|
| }
|
| }
|
| }
|
| else {
|
| _aulGrid[ulX1][ulY1][ulZ1].insert(ulFacetIndex);
|
| }
|
| }
|
|
|
| }
|
|
|
| #endif
|
|
|