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 MESH_GRID_H
00025 #define MESH_GRID_H
00026
00027 #include <set>
00028
00029 #include "MeshKernel.h"
00030 #include <Base/Vector3D.h>
00031 #include <Base/BoundBox.h>
00032
00033 #define MESH_CT_GRID 256 // Default value for number of elements per grid
00034 #define MESH_MAX_GRIDS 100000 // Default value for maximum number of grids
00035 #define MESH_CT_GRID_PER_AXIS 20
00036
00037
00038 namespace MeshCore {
00039
00040 class MeshKernel;
00041 class MeshGeomFacet;
00042 class MeshGrid;
00043
00044
00045 #define MESHGRID_BBOX_EXTENSION 10.0f
00046
00055 class MeshExport MeshGrid
00056 {
00057 protected:
00060
00061 MeshGrid (const MeshKernel &rclM);
00063 MeshGrid (void);
00065
00066 public:
00068 virtual ~MeshGrid (void) { }
00069
00070 public:
00073 virtual void Attach (const MeshKernel &rclM);
00075 virtual void Rebuild (unsigned long ulPerGrid = MESH_CT_GRID, unsigned long ulMaxGrid = MESH_MAX_GRIDS);
00077 virtual void Rebuild (int iCtGridPerAxis = MESH_CT_GRID_PER_AXIS);
00079 virtual void Rebuild (unsigned long ulX, unsigned long ulY, unsigned long ulZ);
00080
00084 virtual unsigned long Inside (const Base::BoundBox3f &rclBB, std::vector<unsigned long> &raulElements, bool bDelDoubles = true) const;
00086 virtual unsigned long Inside (const Base::BoundBox3f &rclBB, std::set<unsigned long> &raulElementss) const;
00088 virtual unsigned long Inside (const Base::BoundBox3f &rclBB, std::vector<unsigned long> &raulElements,
00089 const Base::Vector3f &rclOrg, float fMaxDist, bool bDelDoubles = true) const;
00091 void SearchNearestFromPoint (const Base::Vector3f &rclPt, std::set<unsigned long> &rclInd) const;
00093
00097 unsigned long GetElements (unsigned long ulX, unsigned long ulY, unsigned long ulZ, std::set<unsigned long> &raclInd) const;
00098 unsigned long GetElements (const Base::Vector3f &rclPoint, std::vector<unsigned long>& aulFacets) const;
00100
00102 virtual void GetGridLengths (float &rfLenX, float &rfLenY, float &rfLenZ) const
00103 { rfLenX = _fGridLenX; rfLenY = _fGridLenY; rfLenZ = _fGridLenZ; }
00105 virtual void GetCtGrids (unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00106 { rulX = _ulCtGridsX; rulY = _ulCtGridsY; rulZ = _ulCtGridsZ; }
00107
00111 inline Base::BoundBox3f GetBoundBox (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
00113 inline Base::BoundBox3f GetBoundBox (void) const;
00115 inline Base::BoundBox3f GetMeshBoundBox (void) const;
00117
00121 unsigned long GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
00125 bool GetPositionToIndex(unsigned long id, unsigned long& ulX, unsigned long& ulY, unsigned long& ulZ) const;
00127 unsigned long GetCtElements(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00128 { return _aulGrid[ulX][ulY][ulZ].size(); }
00130 virtual void Validate (const MeshKernel &rclM) = 0;
00132 virtual bool Verify() const = 0;
00136 bool CheckPosition (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00139 virtual void Position (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00141 inline bool CheckPos (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const;
00143 void GetHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, unsigned long ulDistance, std::set<unsigned long> &raclInd) const;
00144
00145 protected:
00147 virtual void InitGrid (void);
00149 virtual void Clear (void);
00151 virtual void CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids);
00153 virtual void CalculateGridLength (int iCtGridPerAxis);
00155 virtual void RebuildGrid (void) = 0;
00157 virtual unsigned long HasElements (void) const = 0;
00158
00159 protected:
00160 std::vector<std::vector<std::vector<std::set<unsigned long> > > > _aulGrid;
00161 const MeshKernel* _pclMesh;
00162 unsigned long _ulCtElements;
00163 unsigned long _ulCtGridsX;
00164 unsigned long _ulCtGridsY;
00165 unsigned long _ulCtGridsZ;
00166 float _fGridLenX;
00167 float _fGridLenY;
00168 float _fGridLenZ;
00169 float _fMinX;
00170 float _fMinY;
00171 float _fMinZ;
00173
00174 friend class MeshGridIterator;
00175 };
00176
00181 class MeshExport MeshFacetGrid: public MeshGrid
00182 {
00183 public:
00186
00187 MeshFacetGrid (const MeshKernel &rclM);
00189 MeshFacetGrid (void) : MeshGrid() { }
00191 MeshFacetGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ);
00193 MeshFacetGrid (const MeshKernel &rclM, int iCtGridPerAxis);
00195 MeshFacetGrid (const MeshKernel &rclM, float fGridLen);
00197 virtual ~MeshFacetGrid (void) { }
00199
00203 unsigned long SearchNearestFromPoint (const Base::Vector3f &rclPt) const;
00205 unsigned long SearchNearestFromPoint (const Base::Vector3f &rclPt, float fMaxSearchArea) const;
00207 void SearchNearestFacetInGrid(unsigned long ulX, unsigned long ulY, unsigned long ulZ, const Base::Vector3f &rclPt,
00208 float &rfMinDist, unsigned long &rulFacetInd) const;
00211 void SearchNearestFacetInHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, unsigned long ulDistance,
00212 const Base::Vector3f &rclPt, unsigned long &rulFacetInd, float &rfMinDist) const;
00214
00216 virtual void Validate (const MeshKernel &rclM);
00218 virtual void Validate (void);
00220 virtual bool Verify() const;
00221
00222 protected:
00224 inline void Pos (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00226 inline void PosWithCheck (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00230 inline void AddFacet (const MeshGeomFacet &rclFacet, unsigned long ulFacetIndex, float fEpsilon = 0.0f);
00232 unsigned long HasElements (void) const
00233 { return _pclMesh->CountFacets(); }
00235 virtual void RebuildGrid (void);
00236 };
00237
00242 class MeshExport MeshPointGrid: public MeshGrid
00243 {
00244 public:
00247
00248 MeshPointGrid (void);
00250 MeshPointGrid (const MeshKernel &rclM);
00252 MeshPointGrid (const MeshKernel &rclM, int iCtGridPerAxis);
00254 MeshPointGrid (const MeshKernel &rclM, float fGridLen);
00256 MeshPointGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ);
00258 virtual ~MeshPointGrid (void) {}
00260
00262 unsigned long FindElements(const Base::Vector3f &rclPoint, std::set<unsigned long>& aulElements) const;
00264 virtual void Validate (const MeshKernel &rclM);
00266 virtual void Validate (void);
00268 virtual bool Verify() const;
00269
00270 protected:
00273 void AddPoint (const MeshPoint &rclPt, unsigned long ulPtIndex, float fEpsilon = 0.0f);
00275 void Pos(const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const;
00277 unsigned long HasElements (void) const
00278 { return _pclMesh->CountPoints(); }
00280 virtual void RebuildGrid (void);
00281 };
00282
00287 class MeshExport MeshGridIterator
00288 {
00289 public:
00291 MeshGridIterator (const MeshGrid &rclG);
00293 Base::BoundBox3f GetBoundBox (void) const
00294 { return _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ); }
00296 void GetElements (std::vector<unsigned long> &raulElements) const
00297 {
00298 raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
00299 }
00301 unsigned long GetCtElements() const
00302 {
00303 return _rclGrid.GetCtElements(_ulX, _ulY, _ulZ);
00304 }
00308 void Init (void)
00309 { _ulX = _ulY = _ulZ = 0; }
00311 bool More (void) const
00312 { return (_ulZ < _rclGrid._ulCtGridsZ); }
00314 void Next (void)
00315 {
00316 if (++_ulX >= (_rclGrid._ulCtGridsX)) _ulX = 0; else return;
00317 if (++_ulY >= (_rclGrid._ulCtGridsY)) { _ulY = 0; _ulZ++; } else return;
00318 }
00320
00324 bool InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, std::vector<unsigned long> &raulElements);
00326 bool InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxSearchArea, std::vector<unsigned long> &raulElements);
00328 bool NextOnRay (std::vector<unsigned long> &raulElements);
00330
00332 void GetGridPos (unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00333 { rulX = _ulX; rulY = _ulY; rulZ = _ulZ; }
00334
00335 protected:
00336 const MeshGrid& _rclGrid;
00337 unsigned long _ulX;
00338 unsigned long _ulY;
00339 unsigned long _ulZ;
00340 Base::Vector3f _clPt;
00341 Base::Vector3f _clDir;
00342 bool _bValidRay;
00343 float _fMaxSearchArea;
00345 struct GridElement
00346 {
00347 GridElement( unsigned long x, unsigned long y, unsigned long z)
00348 { this->x = x; this->y = y; this->z = z; }
00349 bool operator < (const GridElement& pos) const
00350 {
00351 if ( x == pos.x)
00352 { if ( y == pos.y) return z < pos.z; else return y < pos.y; }
00353 else
00354 { return x < pos.x; }
00355 }
00356 private:
00357 unsigned long x,y,z;
00358 };
00359 std::set<GridElement> _cSearchPositions;
00360 };
00361
00362
00363
00364 inline Base::BoundBox3f MeshGrid::GetBoundBox (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00365 {
00366 float fX, fY, fZ;
00367
00368 fX = _fMinX + (float(ulX) * _fGridLenX);
00369 fY = _fMinY + (float(ulY) * _fGridLenY);
00370 fZ = _fMinZ + (float(ulZ) * _fGridLenZ);
00371
00372 return Base::BoundBox3f(fX, fY, fZ, fX + _fGridLenX, fY + _fGridLenY, fZ + _fGridLenZ);
00373 }
00374
00375 inline Base::BoundBox3f MeshGrid::GetBoundBox (void) const
00376 {
00377 return Base::BoundBox3f(_fMinX, _fMinY, _fMinZ, _fMinX + (_fGridLenX * float(_ulCtGridsX)),
00378 _fMinY + (_fGridLenY * float(_ulCtGridsY)), _fMinZ + (_fGridLenZ * float(_ulCtGridsZ)));
00379 }
00380
00381 inline Base::BoundBox3f MeshGrid::GetMeshBoundBox (void) const
00382 {
00383 Base::BoundBox3f clBBenlarged = _pclMesh->GetBoundBox();
00384 clBBenlarged.Enlarge(MESHGRID_BBOX_EXTENSION);
00385
00386 return clBBenlarged;
00387 }
00388
00389 inline bool MeshGrid::CheckPos (unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00390 {
00391 return ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ));
00392 }
00393
00394
00395
00396 inline void MeshFacetGrid::Pos (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00397 {
00398 rulX = (unsigned long)((rclPoint.x - _fMinX) / _fGridLenX);
00399 rulY = (unsigned long)((rclPoint.y - _fMinY) / _fGridLenY);
00400 rulZ = (unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ);
00401
00402 assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ));
00403 }
00404
00405 inline void MeshFacetGrid::PosWithCheck (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00406 {
00407 if ( rclPoint.x < _fMinX)
00408 rulX = 0;
00409 else
00410 {
00411 rulX = (unsigned long)((rclPoint.x - _fMinX) / _fGridLenX);
00412 if (rulX >= _ulCtGridsX)
00413 rulX = (_ulCtGridsX-1);
00414 }
00415
00416 if ( rclPoint.y < _fMinY)
00417 rulY = 0;
00418 else
00419 {
00420 rulY = (unsigned long)((rclPoint.y - _fMinY) / _fGridLenY);
00421 if (rulY >= _ulCtGridsY)
00422 rulY = (_ulCtGridsY-1);
00423 }
00424
00425 if ( rclPoint.z < _fMinZ)
00426 rulZ = 0;
00427 else
00428 {
00429 rulZ = (unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ);
00430 if (rulZ >= _ulCtGridsZ)
00431 rulZ = (_ulCtGridsZ-1);
00432 }
00433
00434 assert((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ));
00435 }
00436
00437 inline void MeshFacetGrid::AddFacet (const MeshGeomFacet &rclFacet, unsigned long ulFacetIndex, float fEpsilon)
00438 {
00439 #if 0
00440 unsigned long i, ulX, ulY, ulZ, ulX1, ulY1, ulZ1, ulX2, ulY2, ulZ2;
00441
00442 ulX1 = ulY1 = ulZ1 = ULONG_MAX;
00443 ulX2 = ulY2 = ulZ2 = 0;
00444
00445 for (i = 0; i < 3; i++)
00446 {
00447 Pos(rclFacet._aclPoints[i], ulX, ulY, ulZ);
00448 _aulGrid[ulX][ulY][ulZ].insert(ulFacetIndex);
00449 ulX1 = RSmin<unsigned long>(ulX1, ulX); ulY1 = RSmin<unsigned long>(ulY1, ulY); ulZ1 = RSmin<unsigned long>(ulZ1, ulZ);
00450 ulX2 = RSmax<unsigned long>(ulX2, ulX); ulY2 = RSmax<unsigned long>(ulY2, ulY); ulZ2 = RSmax<unsigned long>(ulZ2, ulZ);
00451 }
00452
00453
00454 if ((ulX1 < ulX2) || (ulY1 < ulY2) || (ulZ1 < ulZ2))
00455 {
00456 for (ulX = ulX1; ulX <= ulX2; ulX++)
00457 {
00458 for (ulY = ulY1; ulY <= ulY2; ulY++)
00459 {
00460 for (ulZ = ulZ1; ulZ <= ulZ2; ulZ++)
00461 {
00462 if (CMeshFacetFunc::BBoxContainFacet(GetBoundBox(ulX, ulY, ulZ), rclFacet) == TRUE)
00463 _aulGrid[ulX][ulY][ulZ].insert(ulFacetIndex);
00464 }
00465 }
00466 }
00467 }
00468 #else
00469 unsigned long ulX, ulY, ulZ;
00470
00471 unsigned long ulX1, ulY1, ulZ1, ulX2, ulY2, ulZ2;
00472
00473 Base::BoundBox3f clBB;
00474
00475 clBB &= rclFacet._aclPoints[0];
00476 clBB &= rclFacet._aclPoints[1];
00477 clBB &= rclFacet._aclPoints[2];
00478
00479
00480
00481
00482
00483 Pos(Base::Vector3f(clBB.MinX,clBB.MinY,clBB.MinZ), ulX1, ulY1, ulZ1);
00484 Pos(Base::Vector3f(clBB.MaxX,clBB.MaxY,clBB.MaxZ), ulX2, ulY2, ulZ2);
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 if ((ulX1 < ulX2) || (ulY1 < ulY2) || (ulZ1 < ulZ2))
00498 {
00499 for (ulX = ulX1; ulX <= ulX2; ulX++)
00500 {
00501 for (ulY = ulY1; ulY <= ulY2; ulY++)
00502 {
00503 for (ulZ = ulZ1; ulZ <= ulZ2; ulZ++)
00504 {
00505 if ( rclFacet.IntersectBoundingBox( GetBoundBox(ulX, ulY, ulZ) ) )
00506 _aulGrid[ulX][ulY][ulZ].insert(ulFacetIndex);
00507 }
00508 }
00509 }
00510 }
00511 else
00512 _aulGrid[ulX1][ulY1][ulZ1].insert(ulFacetIndex);
00513
00514 #endif
00515 }
00516
00517 }
00518
00519 #endif // MESH_GRID_H