Grid.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2005 Imetric 3D GmbH                                    *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
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 //#define MESHGRID_BBOX_EXTENSION 1.0e-3f
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   // friends
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   // falls Facet ueber mehrere BB reicht
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   //float fDiagonalLength = clBB.CalcDiagonalLength();
00480 
00481   //clBB.Enlarge(fEpsilon*fDiagonalLength);
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   if (ulX1 > 0) ulX1--;
00488   if (ulY1 > 0) ulY1--;
00489   if (ulZ1 > 0) ulZ1--;
00490   
00491   if (ulX2 < (_ulCtGridsX-1)) ulX2++;
00492   if (ulY2 < (_ulCtGridsY-1)) ulY2++;
00493   if (ulZ2 < (_ulCtGridsZ-1)) ulZ2++;
00494   */
00495 
00496   // falls Facet ueber mehrere BB reicht
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 } // namespace MeshCore
00518 
00519 #endif // MESH_GRID_H

Generated on Wed Nov 23 19:00:16 2011 for FreeCAD by  doxygen 1.6.1