| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #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
|
| |
|