00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef POINTS_GRID_H
00025 #define POINTS_GRID_H
00026
00027 #include <set>
00028
00029 #include "Points.h"
00030 #include <Base/Vector3D.h>
00031 #include <Base/BoundBox.h>
00032
00033 #define POINTS_CT_GRID 256 // Default value for number of elements per grid
00034 #define POINTS_MAX_GRIDS 100000 // Default value for maximum number of grids
00035 #define POINTS_CT_GRID_PER_AXIS 20
00036 #define PONTSGRID_BBOX_EXTENSION 10.0f
00037
00038
00039 namespace Points {
00040 class PointsGrid;
00041
00049 class PointsExport PointsGrid
00050 {
00051 public:
00054
00055 PointsGrid (const PointKernel &rclM);
00057 PointsGrid (void);
00059 PointsGrid (const PointKernel &rclM, int iCtGridPerAxis);
00061 PointsGrid (const PointKernel &rclM, double fGridLen);
00063 PointsGrid (const PointKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ);
00065 virtual ~PointsGrid (void) { }
00067
00068 public:
00071 virtual void Attach (const PointKernel &rclM);
00073 virtual void Rebuild (unsigned long ulPerGrid = POINTS_CT_GRID, unsigned long ulMaxGrid = POINTS_MAX_GRIDS);
00075 virtual void Rebuild (int iCtGridPerAxis = POINTS_CT_GRID_PER_AXIS);
00077 virtual void Rebuild (unsigned long ulX, unsigned long ulY, unsigned long ulZ);
00078
00082 virtual unsigned long InSide (const Base::BoundBox3d &rclBB, std::vector<unsigned long> &raulElements, bool bDelDoubles = true) const;
00084 virtual unsigned long InSide (const Base::BoundBox3d &rclBB, std::set<unsigned long> &raulElementss) const;
00086 virtual unsigned long InSide (const Base::BoundBox3d &rclBB, std::vector<unsigned long> &raulElements,
00087 const Base::Vector3d &rclOrg, float fMaxDist, bool bDelDoubles = true) const;
00089 void SearchNearestFromPoint (const Base::Vector3d &rclPt, std::set<unsigned long> &rclInd) const;
00091
00093 virtual void GetGridLengths (double &rfLenX, double &rfLenY, double &rfLenZ) const
00094 { rfLenX = _fGridLenX; rfLenY = _fGridLenY; rfLenZ = _fGridLenZ; }
00096 virtual void GetCtGrids (unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00097 { rulX = _ulCtGridsX; rulY = _ulCtGridsY; rulZ = _ulCtGridsZ; }
00098
00102 inline Base::BoundBox3d GetBoundBox (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
00104 inline Base::BoundBox3d GetBoundBox (void) const;
00106
00107 unsigned long GetCtElements(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00108 { return _aulGrid[ulX][ulY][ulZ].size(); }
00110 unsigned long FindElements(const Base::Vector3d &rclPoint, std::set<unsigned long>& aulElements) const;
00112 virtual void Validate (const PointKernel &rclM);
00114 virtual void Validate (void);
00116 virtual bool Verify() const;
00119 virtual void Position (const Base::Vector3d &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00121 unsigned long GetElements (unsigned long ulX, unsigned long ulY, unsigned long ulZ, std::set<unsigned long> &raclInd) const;
00122
00123 protected:
00125 inline bool CheckPos (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
00127 virtual void InitGrid (void);
00129 virtual void Clear (void);
00131 virtual void CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids);
00133 virtual void CalculateGridLength (int iCtGridPerAxis);
00135 virtual void RebuildGrid (void);
00137 unsigned long HasElements (void) const
00138 { return _pclPoints->size(); }
00140 void GetHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, unsigned long ulDistance, std::set<unsigned long> &raclInd) const;
00141
00142 protected:
00143 std::vector<std::vector<std::vector<std::set<unsigned long> > > > _aulGrid;
00144 const PointKernel* _pclPoints;
00145 unsigned long _ulCtElements;
00146 unsigned long _ulCtGridsX;
00147 unsigned long _ulCtGridsY;
00148 unsigned long _ulCtGridsZ;
00149 double _fGridLenX;
00150 double _fGridLenY;
00151 double _fGridLenZ;
00152 double _fMinX;
00153 double _fMinY;
00154 double _fMinZ;
00156
00157 friend class PointsGridIterator;
00158 friend class PointsGridIteratorStatistic;
00159
00160 public:
00161
00162 protected:
00165 void AddPoint (const Base::Vector3d &rclPt, unsigned long ulPtIndex, float fEpsilon = 0.0f);
00167 void Pos(const Base::Vector3d &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00168 };
00169
00174 class PointsExport PointsGridIterator
00175 {
00176 public:
00178 PointsGridIterator (const PointsGrid &rclG);
00180 Base::BoundBox3d GetBoundBox (void) const
00181 { return _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ); }
00183 void GetElements (std::vector<unsigned long> &raulElements) const
00184 {
00185 raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
00186 }
00190 void Init (void)
00191 { _ulX = _ulY = _ulZ = 0; }
00193 bool More (void) const
00194 { return (_ulZ < _rclGrid._ulCtGridsZ); }
00196 void Next (void)
00197 {
00198 if (++_ulX >= (_rclGrid._ulCtGridsX)) _ulX = 0; else return;
00199 if (++_ulY >= (_rclGrid._ulCtGridsY)) { _ulY = 0; _ulZ++; } else return;
00200 }
00202
00206 bool InitOnRay (const Base::Vector3d &rclPt, const Base::Vector3d &rclDir, std::vector<unsigned long> &raulElements);
00208 bool InitOnRay (const Base::Vector3d &rclPt, const Base::Vector3d &rclDir, float fMaxSearchArea, std::vector<unsigned long> &raulElements);
00210 bool NextOnRay (std::vector<unsigned long> &raulElements);
00212
00214 void GetGridPos (unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00215 { rulX = _ulX; rulY = _ulY; rulZ = _ulZ; }
00216
00217 protected:
00218 const PointsGrid& _rclGrid;
00219 unsigned long _ulX;
00220 unsigned long _ulY;
00221 unsigned long _ulZ;
00222 Base::Vector3d _clPt;
00223 Base::Vector3d _clDir;
00224 bool _bValidRay;
00225 float _fMaxSearchArea;
00227 struct GridElement
00228 {
00229 GridElement( unsigned long x, unsigned long y, unsigned long z)
00230 { this->x = x; this->y = y; this->z = z; }
00231 bool operator < (const GridElement& pos) const
00232 {
00233 if ( x == pos.x)
00234 { if ( y == pos.y) return z < pos.z; else return y < pos.y; }
00235 else
00236 { return x < pos.x; }
00237 }
00238 private:
00239 unsigned long x,y,z;
00240 };
00241 std::set<GridElement> _cSearchPositions;
00242 };
00243
00244
00245
00246 inline Base::BoundBox3d PointsGrid::GetBoundBox (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00247 {
00248 double fX, fY, fZ;
00249
00250 fX = _fMinX + (double(ulX) * _fGridLenX);
00251 fY = _fMinY + (double(ulY) * _fGridLenY);
00252 fZ = _fMinZ + (double(ulZ) * _fGridLenZ);
00253
00254 return Base::BoundBox3d(fX, fY, fZ, fX + _fGridLenX, fY + _fGridLenY, fZ + _fGridLenZ);
00255 }
00256
00257 inline Base::BoundBox3d PointsGrid::GetBoundBox (void) const
00258 {
00259 return Base::BoundBox3d(_fMinX, _fMinY, _fMinZ, _fMinX + (_fGridLenX * double(_ulCtGridsX)),
00260 _fMinY + (_fGridLenY * double(_ulCtGridsY)), _fMinZ + (_fGridLenZ * double(_ulCtGridsZ)));
00261 }
00262
00263 inline bool PointsGrid::CheckPos (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00264 {
00265 return ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ));
00266 }
00267
00268
00269
00270 }
00271
00272 #endif // POINTS_GRID_H