Grid.cpp

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 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <algorithm>
00028 #endif
00029 
00030 #include "Grid.h"
00031 #include "Iterator.h"
00032 
00033 #include "MeshKernel.h"
00034 #include "Algorithm.h"
00035 #include "Tools.h"
00036 
00037 using namespace MeshCore;
00038 
00039 MeshGrid::MeshGrid (const MeshKernel &rclM)
00040 : _pclMesh(&rclM),
00041   _ulCtElements(0),
00042   _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
00043   _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00044   _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00045 {
00046 }
00047 
00048 MeshGrid::MeshGrid (void)
00049 : _pclMesh(NULL),
00050   _ulCtElements(0),
00051   _ulCtGridsX(MESH_CT_GRID), _ulCtGridsY(MESH_CT_GRID), _ulCtGridsZ(MESH_CT_GRID),
00052   _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00053   _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00054 {
00055 }
00056 
00057 void MeshGrid::Attach (const MeshKernel &rclM)
00058 {
00059   _pclMesh = &rclM;
00060   RebuildGrid();
00061 }
00062 
00063 void MeshGrid::Clear (void)
00064 {
00065   _aulGrid.clear();
00066   _pclMesh = NULL;  
00067 }
00068 
00069 void MeshGrid::Rebuild (unsigned long ulX, unsigned long ulY, unsigned long ulZ)
00070 {
00071   _ulCtGridsX = ulX;
00072   _ulCtGridsY = ulY;
00073   _ulCtGridsZ = ulZ;
00074   _ulCtElements = HasElements();
00075   RebuildGrid();
00076 }
00077 
00078 void MeshGrid::Rebuild (unsigned long ulPerGrid, unsigned long ulMaxGrid)
00079 {
00080   _ulCtElements = HasElements();
00081   CalculateGridLength(ulPerGrid, ulMaxGrid);
00082   RebuildGrid();
00083 }
00084 
00085 void MeshGrid::Rebuild (int iCtGridPerAxis)
00086 {
00087   _ulCtElements = HasElements();
00088   CalculateGridLength(iCtGridPerAxis);
00089   RebuildGrid();
00090 }
00091 
00092 void MeshGrid::InitGrid (void)
00093 {
00094   assert(_pclMesh != NULL);
00095 
00096   unsigned long i, j;
00097 
00098   // Grid Laengen berechnen wenn nicht initialisiert
00099   //
00100   if ((_ulCtGridsX == 0) || (_ulCtGridsX == 0) || (_ulCtGridsX == 0))
00101     CalculateGridLength(MESH_CT_GRID, MESH_MAX_GRIDS);
00102 
00103   // Grid Laengen und Offset bestimmen
00104   //
00105   {
00106   Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
00107 
00108   float fLengthX = clBBMesh.LengthX(); 
00109   float fLengthY = clBBMesh.LengthY();
00110   float fLengthZ = clBBMesh.LengthZ();
00111 
00112   {
00113     // Offset fGridLen/2
00114     //
00115     _fGridLenX = (1.0f + fLengthX) / float(_ulCtGridsX);
00116     _fMinX = clBBMesh.MinX - 0.5f;
00117   }
00118 
00119   {
00120     _fGridLenY = (1.0f + fLengthY) / float(_ulCtGridsY);
00121     _fMinY = clBBMesh.MinY - 0.5f;
00122   }
00123 
00124   {
00125     _fGridLenZ = (1.0f + fLengthZ) / float(_ulCtGridsZ);
00126     _fMinZ = clBBMesh.MinZ - 0.5f;
00127   }
00128   }
00129 
00130   // Daten-Struktur anlegen
00131   _aulGrid.clear();
00132   _aulGrid.resize(_ulCtGridsX);
00133   for (i = 0; i < _ulCtGridsX; i++)
00134   {
00135     _aulGrid[i].resize(_ulCtGridsY);
00136     for (j = 0; j < _ulCtGridsY; j++)
00137       _aulGrid[i][j].resize(_ulCtGridsZ);
00138   }
00139 }
00140 
00141 unsigned long MeshGrid::Inside (const Base::BoundBox3f &rclBB, std::vector<unsigned long> &raulElements,
00142                                 bool bDelDoubles) const
00143 {
00144   unsigned long i, j, k, ulMinX, ulMinY, ulMinZ,  ulMaxX, ulMaxY, ulMaxZ;
00145   
00146   raulElements.clear();
00147 
00148   // Grid-Boxen zur naehreren Auswahl
00149   Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
00150   Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
00151 
00152   for (i = ulMinX; i <= ulMaxX; i++)
00153   {
00154     for (j = ulMinY; j <= ulMaxY; j++)
00155     {
00156       for (k = ulMinZ; k <= ulMaxZ; k++)
00157       {
00158         raulElements.insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
00159       }
00160     }
00161   }  
00162 
00163   if (bDelDoubles == true)
00164   {
00165     // doppelte Nennungen entfernen
00166     std::sort(raulElements.begin(), raulElements.end());
00167     raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end());  
00168   }
00169 
00170   return raulElements.size();
00171 }
00172 
00173 unsigned long MeshGrid::Inside (const Base::BoundBox3f &rclBB, std::vector<unsigned long> &raulElements,
00174                                 const Base::Vector3f &rclOrg, float fMaxDist, bool bDelDoubles) const
00175 {
00176   unsigned long i, j, k, ulMinX, ulMinY, ulMinZ,  ulMaxX, ulMaxY, ulMaxZ;
00177   float  fGridDiag  = GetBoundBox(0, 0, 0).CalcDiagonalLength();
00178   float  fMinDistP2 = (fGridDiag * fGridDiag) + (fMaxDist * fMaxDist);
00179 
00180   raulElements.clear();
00181 
00182   // Grid-Boxen zur naehreren Auswahl
00183   Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
00184   Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
00185 
00186   for (i = ulMinX; i <= ulMaxX; i++)
00187   {
00188     for (j = ulMinY; j <= ulMaxY; j++)
00189     {
00190       for (k = ulMinZ; k <= ulMaxZ; k++)
00191       {
00192         if (Base::DistanceP2(GetBoundBox(i, j, k).CalcCenter(), rclOrg) < fMinDistP2)
00193           raulElements.insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
00194       }
00195     }
00196   }  
00197 
00198   if (bDelDoubles == true)
00199   {
00200     // doppelte Nennungen entfernen
00201     std::sort(raulElements.begin(), raulElements.end());
00202     raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end());  
00203   }
00204 
00205   return raulElements.size();
00206 }
00207 
00208 unsigned long MeshGrid::Inside (const Base::BoundBox3f &rclBB, std::set<unsigned long> &raulElements) const
00209 {
00210   unsigned long i, j, k, ulMinX, ulMinY, ulMinZ,  ulMaxX, ulMaxY, ulMaxZ;
00211   
00212   raulElements.clear();
00213 
00214   // Grid-Boxen zur naehreren Auswahl
00215   Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
00216   Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
00217 
00218   for (i = ulMinX; i <= ulMaxX; i++)
00219   {
00220     for (j = ulMinY; j <= ulMaxY; j++)
00221     {
00222       for (k = ulMinZ; k <= ulMaxZ; k++)
00223       {
00224         raulElements.insert(_aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
00225       }
00226     }
00227   }  
00228 
00229   return raulElements.size();
00230 }
00231 
00232 bool MeshGrid::CheckPosition (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00233 {
00234   rulX = (unsigned long)((rclPoint.x - _fMinX) / _fGridLenX);
00235   rulY = (unsigned long)((rclPoint.y - _fMinY) / _fGridLenY);
00236   rulZ = (unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ);
00237 
00238   if ( (rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ) )
00239     return true;
00240 
00241   return false;
00242 }
00243 
00244 void MeshGrid::Position (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00245 {
00246   if (rclPoint.x <= _fMinX)
00247     rulX = 0;
00248   else
00249     rulX = std::min<unsigned long>((unsigned long)((rclPoint.x - _fMinX) / _fGridLenX), _ulCtGridsX - 1);
00250 
00251   if (rclPoint.y <= _fMinY)
00252     rulY = 0;
00253   else
00254     rulY = std::min<unsigned long>((unsigned long)((rclPoint.y - _fMinY) / _fGridLenY), _ulCtGridsY - 1);
00255 
00256   if (rclPoint.z <= _fMinZ)
00257     rulZ = 0;
00258   else
00259     rulZ = std::min<unsigned long>((unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ), _ulCtGridsZ - 1);
00260 }
00261 
00262 void MeshGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids)
00263 {
00264   // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen
00265   // pro Grid sollen ca. 10 (?!?!) Facets liegen
00266   // bzw. max Grids sollten 10000 nicht ueberschreiten
00267   Base::BoundBox3f clBBMeshEnlarged = _pclMesh->GetBoundBox();
00268   float fVolElem;
00269 
00270   if (_ulCtElements > (ulMaxGrids * ulCtGrid))
00271     fVolElem = (clBBMeshEnlarged.LengthX() * clBBMeshEnlarged.LengthY() * clBBMeshEnlarged.LengthZ()) / float(ulMaxGrids * ulCtGrid);
00272   else
00273     fVolElem = (clBBMeshEnlarged.LengthX() * clBBMeshEnlarged.LengthY() * clBBMeshEnlarged.LengthZ()) / float(_ulCtElements);
00274 
00275   float fVol     = fVolElem * float(ulCtGrid);
00276   float fGridLen = float(pow((float)fVol,(float) 1.0f / 3.0f));
00277 
00278   _ulCtGridsX = std::max<unsigned long>((unsigned long)(clBBMeshEnlarged.LengthX() / fGridLen), 1);
00279   _ulCtGridsY = std::max<unsigned long>((unsigned long)(clBBMeshEnlarged.LengthY() / fGridLen), 1);
00280   _ulCtGridsZ = std::max<unsigned long>((unsigned long)(clBBMeshEnlarged.LengthZ() / fGridLen), 1);
00281 }
00282 
00283 void MeshGrid::CalculateGridLength (int iCtGridPerAxis)
00284 {
00285   if (iCtGridPerAxis<=0)
00286   {
00287     CalculateGridLength(MESH_CT_GRID, MESH_MAX_GRIDS);
00288     return;
00289   }
00290 
00291   // Grid Laengen bzw. Anzahl der Grids pro Dimension berechnen
00292   // pro Grid sollen ca. 10 (?!?!) Facets liegen
00293   // bzw. max Grids sollten 10000 nicht ueberschreiten
00294   Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
00295 
00296   float fLenghtX = clBBMesh.LengthX();
00297   float fLenghtY = clBBMesh.LengthY();
00298   float fLenghtZ = clBBMesh.LengthZ();
00299 
00300   float fLenghtD = clBBMesh.CalcDiagonalLength();
00301 
00302   float fLengthTol = 0.05f * fLenghtD;
00303 
00304   bool bLenghtXisZero = (fLenghtX <= fLengthTol);
00305   bool bLenghtYisZero = (fLenghtY <= fLengthTol);
00306   bool bLenghtZisZero = (fLenghtZ <= fLengthTol);
00307 
00308   int iFlag  = 0;
00309 
00310   int iMaxGrids = 1;
00311 
00312   if (bLenghtXisZero)  
00313     iFlag += 1; 
00314   else
00315     iMaxGrids *= iCtGridPerAxis;
00316 
00317   if (bLenghtYisZero) 
00318     iFlag += 2;
00319   else
00320     iMaxGrids *= iCtGridPerAxis;
00321 
00322   if (bLenghtZisZero)
00323     iFlag += 4; 
00324   else
00325     iMaxGrids *= iCtGridPerAxis;
00326   
00327   unsigned long ulGridsFacets =   10;
00328 
00329   float fFactorVolumen = 40.0;
00330   float fFactorArea    = 10.0;
00331 
00332   switch (iFlag)
00333   {
00334   case 0:
00335     {
00336       float fVolumen = fLenghtX * fLenghtY * fLenghtZ;
00337 
00338       float fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements);
00339 
00340       if ((fVolumenGrid * iMaxGrids) < fVolumen)
00341         fVolumenGrid = fVolumen / (float)iMaxGrids;
00342 
00343       float fLengthGrid = float(pow((float)fVolumenGrid,(float) 1.0f / 3.0f));
00344 
00345       _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
00346       _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
00347       _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
00348       
00349     } break;
00350   case 1:
00351     {
00352       _ulCtGridsX = 1; // bLenghtXisZero
00353       
00354       float fArea = fLenghtY * fLenghtZ;
00355 
00356       float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
00357 
00358       if ((fAreaGrid * iMaxGrids) < fArea)
00359         fAreaGrid = fArea / (float)iMaxGrids;
00360 
00361       float fLengthGrid = float(sqrt(fAreaGrid));
00362 
00363       _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
00364       _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
00365     } break;
00366   case 2:
00367     {
00368       _ulCtGridsY = 1; // bLenghtYisZero
00369   
00370       float fArea = fLenghtX * fLenghtZ;
00371 
00372       float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
00373 
00374       if ((fAreaGrid * iMaxGrids) < fArea)
00375         fAreaGrid = fArea / (float)iMaxGrids;
00376 
00377       float fLengthGrid = float(sqrt(fAreaGrid));
00378 
00379       _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
00380       _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
00381     } break;
00382   case 3:
00383     {
00384       _ulCtGridsX = 1; // bLenghtXisZero
00385       _ulCtGridsY = 1; // bLenghtYisZero
00386       _ulCtGridsZ = iMaxGrids; // bLenghtYisZero
00387     } break;
00388   case 4:
00389     {
00390       _ulCtGridsZ = 1; // bLenghtZisZero
00391       
00392       float fArea = fLenghtX * fLenghtY;
00393 
00394       float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
00395 
00396       if ((fAreaGrid * iMaxGrids) < fArea)
00397         fAreaGrid = fArea / (float)iMaxGrids;
00398 
00399       float fLengthGrid = float(sqrt(fAreaGrid));
00400 
00401       _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
00402       _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
00403     } break;
00404   case 5:
00405     {
00406       _ulCtGridsX = 1; // bLenghtXisZero
00407       _ulCtGridsZ = 1; // bLenghtZisZero
00408       _ulCtGridsY = iMaxGrids; // bLenghtYisZero
00409     } break;
00410   case 6:
00411     {
00412       _ulCtGridsY = 1; // bLenghtYisZero
00413       _ulCtGridsZ = 1; // bLenghtZisZero
00414       _ulCtGridsX = iMaxGrids; // bLenghtYisZero
00415     } break;
00416   case 7:
00417     {
00418       _ulCtGridsX = iMaxGrids; // bLenghtXisZero
00419       _ulCtGridsY = iMaxGrids; // bLenghtYisZero
00420       _ulCtGridsZ = iMaxGrids; // bLenghtZisZero
00421     } break;
00422   }
00423 }
00424 
00425 void MeshGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt, std::set<unsigned long> &raclInd) const
00426 {
00427   raclInd.clear();
00428   Base::BoundBox3f  clBB = GetBoundBox();
00429 
00430   if (clBB.IsInBox(rclPt) == true)
00431   { // Punkt liegt innerhalb
00432     unsigned long ulX, ulY, ulZ;
00433     Position(rclPt, ulX, ulY, ulZ);
00434     //int nX = ulX, nY = ulY, nZ = ulZ;
00435     unsigned long ulLevel = 0;
00436     while (raclInd.size() == 0)
00437       GetHull(ulX, ulY, ulZ, ulLevel++, raclInd);
00438     GetHull(ulX, ulY, ulZ, ulLevel, raclInd);
00439   }
00440   else
00441   { // Punkt ausserhalb
00442     Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.CalcCenter() - rclPt);
00443     switch (tSide)
00444     {
00445       case Base::BoundBox3f::RIGHT:
00446       {
00447         int nX = 0;
00448         while (raclInd.size() == 0)
00449         {
00450           for (unsigned long i = 0; i < _ulCtGridsY; i++)
00451           {
00452             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00453               raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
00454           }
00455           nX++;
00456         }
00457         break;
00458       }
00459       case Base::BoundBox3f::LEFT:
00460       {
00461         int nX = _ulCtGridsX - 1;
00462         while (raclInd.size() == 0)
00463         {
00464           for (unsigned long i = 0; i < _ulCtGridsY; i++)
00465           {
00466             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00467               raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
00468           }
00469           nX++;
00470         }
00471         break;
00472       }
00473       case Base::BoundBox3f::TOP:
00474       {
00475         int nY = 0;
00476         while (raclInd.size() == 0)
00477         {
00478           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00479           {
00480             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00481               raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
00482           }
00483           nY++;
00484         }
00485         break;
00486       }
00487       case Base::BoundBox3f::BOTTOM:
00488       {
00489         int nY = _ulCtGridsY - 1;
00490         while (raclInd.size() == 0)
00491         {
00492           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00493           {
00494             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00495               raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
00496           }
00497           nY--;
00498         }
00499         break;
00500       }
00501       case Base::BoundBox3f::BACK:
00502       {
00503         int nZ = 0;
00504         while (raclInd.size() == 0)
00505         {
00506           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00507           {
00508             for (unsigned long j = 0; j < _ulCtGridsY; j++)
00509               raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
00510           }
00511           nZ++;
00512         }
00513         break;
00514       }
00515       case Base::BoundBox3f::FRONT:
00516       {
00517         int nZ = _ulCtGridsZ - 1;
00518         while (raclInd.size() == 0)
00519         {
00520           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00521           {
00522             for (unsigned long j = 0; j < _ulCtGridsY; j++)
00523               raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
00524           }
00525           nZ--;
00526         }
00527         break;
00528       }
00529 
00530       default:
00531         break;
00532     }
00533   }
00534 }
00535 
00536 void MeshGrid::GetHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, 
00537                         unsigned long ulDistance, std::set<unsigned long> &raclInd) const
00538 {
00539   int nX1 = std::max<int>(0, int(ulX) - int(ulDistance));
00540   int nY1 = std::max<int>(0, int(ulY) - int(ulDistance));
00541   int nZ1 = std::max<int>(0, int(ulZ) - int(ulDistance));
00542   int nX2 = std::min<int>(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance));
00543   int nY2 = std::min<int>(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance));
00544   int nZ2 = std::min<int>(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance));
00545 
00546   int i, j;
00547 
00548   // top plane
00549   for (i = nX1; i <= nX2; i++)
00550   {
00551     for (j = nY1; j <= nY2; j++)
00552       GetElements(i, j, nZ1, raclInd);
00553   }
00554   // bottom plane
00555   for (i = nX1; i <= nX2; i++)
00556   {
00557     for (j = nY1; j <= nY2; j++)
00558       GetElements(i, j, nZ2, raclInd);
00559   }
00560   // left plane
00561   for (i = nY1; i <= nY2; i++)
00562   {
00563     for (j = (nZ1+1); j <= (nZ2-1); j++)
00564       GetElements(nX1, i, j, raclInd);
00565   }
00566   // right plane
00567   for (i = nY1; i <= nY2; i++)
00568   {
00569     for (j = (nZ1+1); j <= (nZ2-1); j++)
00570       GetElements(nX2, i, j, raclInd);
00571   }
00572   // front plane
00573   for (i = (nX1+1); i <= (nX2-1); i++)
00574   {
00575     for (j = (nZ1+1); j <= (nZ2-1); j++)
00576       GetElements(i, nY1, j, raclInd);
00577   }
00578   // back plane
00579   for (i = (nX1+1); i <= (nX2-1); i++)
00580   {
00581     for (j = (nZ1+1); j <= (nZ2-1); j++)
00582       GetElements(i, nY2, j, raclInd);
00583   }
00584 }
00585 
00586 unsigned long MeshGrid::GetElements (unsigned long ulX, unsigned long ulY, unsigned long ulZ,  
00587                                      std::set<unsigned long> &raclInd) const
00588 {
00589   const std::set<unsigned long> &rclSet = _aulGrid[ulX][ulY][ulZ];
00590   if (rclSet.size() > 0)
00591   {
00592     raclInd.insert(rclSet.begin(), rclSet.end());
00593     return rclSet.size();
00594   }
00595 
00596   return 0;
00597 }
00598 
00599 unsigned long MeshGrid::GetElements(const Base::Vector3f &rclPoint, std::vector<unsigned long>& aulFacets) const
00600 {
00601   unsigned long ulX, ulY, ulZ;
00602   if (!CheckPosition(rclPoint, ulX, ulY, ulZ))
00603     return 0;
00604 
00605   aulFacets.resize(_aulGrid[ulX][ulY][ulZ].size());
00606 
00607   std::copy(_aulGrid[ulX][ulY][ulZ].begin(), _aulGrid[ulX][ulY][ulZ].end(), aulFacets.begin());
00608   return aulFacets.size();
00609 }
00610 
00611 unsigned long MeshGrid::GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
00612 {
00613   if ( !CheckPos(ulX, ulY, ulZ) )
00614     return ULONG_MAX;
00615   return (ulZ * _ulCtGridsY + ulY) * _ulCtGridsX + ulX;
00616 }
00617 
00618 bool MeshGrid::GetPositionToIndex(unsigned long id, unsigned long& ulX, unsigned long& ulY, unsigned long& ulZ) const
00619 {
00620   ulX = id % _ulCtGridsX;
00621   ulY = (id/_ulCtGridsX)%_ulCtGridsY;
00622   ulZ = id/(_ulCtGridsX*_ulCtGridsY);
00623 
00624   if ( !CheckPos(ulX, ulY, ulZ) )
00625   {
00626     ulX = ULONG_MAX;
00627     ulY = ULONG_MAX;
00628     ulZ = ULONG_MAX;
00629     return false;
00630   }
00631 
00632   return true;
00633 }
00634 
00635 // ----------------------------------------------------------------
00636 
00637 MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM)
00638 : MeshGrid(rclM)
00639 {
00640   RebuildGrid();
00641 }
00642 
00643 MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM, int iCtGridPerAxis)
00644 : MeshGrid(rclM)
00645 {
00646   Rebuild(iCtGridPerAxis);
00647 }
00648 
00649 MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ)
00650 : MeshGrid(rclM)
00651 {
00652   Rebuild(ulX, ulY, ulZ);
00653 }
00654 
00655 MeshFacetGrid::MeshFacetGrid (const MeshKernel &rclM, float fGridLen)
00656 : MeshGrid(rclM)
00657 {
00658   Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
00659   Rebuild(std::max<unsigned long>((unsigned long)(clBBMesh.LengthX() / fGridLen), 1),
00660           std::max<unsigned long>((unsigned long)(clBBMesh.LengthY() / fGridLen), 1),
00661           std::max<unsigned long>((unsigned long)(clBBMesh.LengthZ() / fGridLen), 1));
00662 }
00663 
00664 void MeshFacetGrid::Validate (const MeshKernel &rclMesh)
00665 {
00666   if (_pclMesh != &rclMesh)
00667     Attach(rclMesh);
00668   else if (rclMesh.CountFacets() != _ulCtElements)
00669     RebuildGrid();
00670 }
00671 
00672 void MeshFacetGrid::Validate (void)
00673 {
00674   if (_pclMesh == NULL)
00675     return;
00676 
00677   if (_pclMesh->CountFacets() != _ulCtElements)
00678     RebuildGrid();
00679 }
00680 
00681 bool MeshFacetGrid::Verify() const
00682 {
00683   if ( !_pclMesh ) 
00684     return false; // no mesh attached
00685   if (_pclMesh->CountFacets() != _ulCtElements)
00686     return false; // not up-to-date
00687 
00688   MeshGridIterator it(*this);
00689   MeshFacetIterator cF(*_pclMesh);
00690   for ( it.Init(); it.More(); it.Next() )
00691   {
00692     std::vector<unsigned long> aulElements;
00693     it.GetElements( aulElements );
00694     for ( std::vector<unsigned long>::iterator itF = aulElements.begin(); itF != aulElements.end(); ++itF )
00695     {
00696       cF.Set( *itF );
00697       if ( cF->IntersectBoundingBox( it.GetBoundBox() ) == false )
00698         return false; // no intersection between facet although the facet is in grid
00699     }
00700   }
00701 
00702   return true;
00703 }
00704 
00705 void MeshFacetGrid::RebuildGrid (void)
00706 {
00707   _ulCtElements = _pclMesh->CountFacets();
00708 
00709   InitGrid();
00710  
00711   // Daten-Struktur fuellen
00712   MeshFacetIterator clFIter(*_pclMesh);
00713 
00714   unsigned long i = 0;
00715   for (clFIter.Init(); clFIter.More(); clFIter.Next())
00716   {
00717 //    AddFacet(*clFIter, i++, 2.0f);
00718     AddFacet(*clFIter, i++);
00719   }
00720 
00721 }
00722 
00723 unsigned long MeshFacetGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt) const
00724 {
00725   unsigned long ulFacetInd = ULONG_MAX;
00726   float fMinDist    = FLOAT_MAX;
00727   Base::BoundBox3f  clBB = GetBoundBox();
00728 
00729   if (clBB.IsInBox(rclPt) == true)
00730   { // Punkt liegt innerhalb
00731     unsigned long ulX, ulY, ulZ;
00732     Position(rclPt, ulX, ulY, ulZ);
00733     float fMinGridDist = std::min<float>(std::min<float>(_fGridLenX, _fGridLenY), _fGridLenZ);
00734     unsigned long ulDistance = 0;
00735     while (fMinDist > (fMinGridDist * float(ulDistance)))
00736     {
00737       SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist);
00738       ulDistance++;
00739     }
00740     SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist);
00741   }
00742   else
00743   { // Punkt ausserhalb
00744     Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.CalcCenter() - rclPt);
00745     switch (tSide)
00746     {
00747       case Base::BoundBox3f::RIGHT:
00748       {
00749         int nX = 0;
00750         while ((fMinDist > ((clBB.MinX - rclPt.x) + ((float)(nX) * _fGridLenX))) && ((unsigned long)(nX) < _ulCtGridsX))
00751         {
00752           for (unsigned long i = 0; i < _ulCtGridsY; i++)
00753           {
00754             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00755               SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd);
00756           }
00757           nX++;
00758         }
00759         break;
00760       }
00761       case Base::BoundBox3f::LEFT:
00762       {
00763         int nX = _ulCtGridsX - 1;
00764         while ((fMinDist > ((rclPt.x - clBB.MinX) + (float(nX) * _fGridLenX))) && (nX >= 0))
00765         {
00766           for (unsigned long i = 0; i < _ulCtGridsY; i++)
00767           {
00768             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00769               SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd);
00770           }
00771           nX--;
00772         }
00773         break;
00774       }
00775       case Base::BoundBox3f::TOP:
00776       {
00777         int nY = 0;
00778         while ((fMinDist > ((clBB.MinY - rclPt.y) + ((float)(nY) * _fGridLenY))) && ((unsigned long)(nY) < _ulCtGridsY))
00779         {
00780           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00781           {
00782             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00783               SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd);
00784           }
00785           nY++;
00786         }
00787         break;
00788       }
00789       case Base::BoundBox3f::BOTTOM:
00790       {
00791         int nY = _ulCtGridsY - 1;
00792         while ((fMinDist > ((rclPt.y - clBB.MinY) + (float(nY) * _fGridLenY))) && (nY >= 0))
00793         {
00794           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00795           {
00796             for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00797               SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd);
00798           }
00799           nY--;
00800         }
00801         break;
00802       }
00803       case Base::BoundBox3f::BACK:
00804       {
00805         int nZ = 0;
00806         while ((fMinDist > ((clBB.MinZ - rclPt.z) + ((float)(nZ) * _fGridLenZ))) && ((unsigned long)(nZ) < _ulCtGridsZ))
00807         {
00808           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00809           {
00810             for (unsigned long j = 0; j < _ulCtGridsY; j++)
00811               SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd);
00812           }
00813           nZ++;
00814         }
00815         break;
00816       }
00817       case Base::BoundBox3f::FRONT:
00818       {
00819         int nZ = _ulCtGridsZ - 1;
00820         while ((fMinDist > ((rclPt.z - clBB.MinZ) + ((float)(nZ) * _fGridLenZ))) && (nZ >= 0))
00821         {
00822           for (unsigned long i = 0; i < _ulCtGridsX; i++)
00823           {
00824             for (unsigned long j = 0; j < _ulCtGridsY; j++)
00825               SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd);
00826           }
00827           nZ--;
00828         }
00829         break;
00830       }
00831       default:
00832         break;
00833     }
00834   }
00835 
00836   return ulFacetInd;
00837 }
00838 
00839 unsigned long MeshFacetGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt, float fMaxSearchArea) const
00840 {
00841   std::vector<unsigned long> aulFacets;
00842   unsigned long ulFacetInd = ULONG_MAX;
00843   float fMinDist   = fMaxSearchArea;
00844 
00845   MeshAlgorithm clFTool(*_pclMesh);
00846 
00847   Base::BoundBox3f clBB(rclPt.x - fMaxSearchArea, rclPt.y - fMaxSearchArea, rclPt.z - fMaxSearchArea,
00848            rclPt.x + fMaxSearchArea, rclPt.y + fMaxSearchArea, rclPt.z + fMaxSearchArea);
00849 
00850   Inside(clBB, aulFacets, rclPt, fMaxSearchArea, true);
00851 
00852   for (std::vector<unsigned long>::const_iterator pI = aulFacets.begin(); pI != aulFacets.end(); pI++)
00853   {    
00854     float fDist;
00855 
00856     if (clFTool.Distance(rclPt, *pI, fMinDist, fDist) == true)
00857     {
00858       fMinDist   = fDist;
00859       ulFacetInd = *pI;
00860     }
00861   }
00862 
00863   return ulFacetInd;
00864 }
00865 
00866 void MeshFacetGrid::SearchNearestFacetInHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ, 
00867                                               unsigned long ulDistance, const Base::Vector3f &rclPt,
00868                                               unsigned long &rulFacetInd, float &rfMinDist) const
00869 {
00870   int nX1 = std::max<int>(0, int(ulX) - int(ulDistance));
00871   int nY1 = std::max<int>(0, int(ulY) - int(ulDistance));
00872   int nZ1 = std::max<int>(0, int(ulZ) - int(ulDistance));
00873   int nX2 = std::min<int>(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance));
00874   int nY2 = std::min<int>(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance));
00875   int nZ2 = std::min<int>(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance));
00876 
00877   int i, j;
00878 
00879   // top plane
00880   for (i = nX1; i <= nX2; i++)
00881   {
00882     for (j = nY1; j <= nY2; j++)
00883       SearchNearestFacetInGrid(i, j, nZ1, rclPt, rfMinDist, rulFacetInd);
00884   }
00885   // bottom plane
00886   for (i = nX1; i <= nX2; i++)
00887   {
00888     for (j = nY1; j <= nY2; j++)
00889       SearchNearestFacetInGrid(i, j, nZ2, rclPt, rfMinDist, rulFacetInd);
00890   }
00891   // left plane
00892   for (i = nY1; i <= nY2; i++)
00893   {
00894     for (j = (nZ1+1); j <= (nZ2-1); j++)
00895       SearchNearestFacetInGrid(nX1, i, j, rclPt, rfMinDist, rulFacetInd);
00896   }
00897   // right plane
00898   for (i = nY1; i <= nY2; i++)
00899   {
00900     for (j = (nZ1+1); j <= (nZ2-1); j++)
00901       SearchNearestFacetInGrid(nX2, i, j, rclPt, rfMinDist, rulFacetInd);
00902   }
00903   // front plane
00904   for (i = (nX1+1); i <= (nX2-1); i++)
00905   {
00906     for (j = (nZ1+1); j <= (nZ2-1); j++)
00907       SearchNearestFacetInGrid(i, nY1, j, rclPt, rfMinDist, rulFacetInd);
00908   }
00909   // back plane
00910   for (i = (nX1+1); i <= (nX2-1); i++)
00911   {
00912     for (j = (nZ1+1); j <= (nZ2-1); j++)
00913       SearchNearestFacetInGrid(i, nY2, j, rclPt, rfMinDist, rulFacetInd);
00914   }
00915 }
00916 
00917 void MeshFacetGrid::SearchNearestFacetInGrid(unsigned long ulX, unsigned long ulY, unsigned long ulZ, 
00918                                              const Base::Vector3f &rclPt, float &rfMinDist,
00919                                              unsigned long &rulFacetInd) const
00920 {
00921   const std::set<unsigned long> &rclSet = _aulGrid[ulX][ulY][ulZ];
00922   for (std::set<unsigned long>::const_iterator pI = rclSet.begin(); pI != rclSet.end(); pI++)
00923   {
00924     float fDist = _pclMesh->GetFacet(*pI).DistanceToPoint(rclPt);
00925     if (fDist < rfMinDist)
00926     {
00927       rfMinDist   = fDist;
00928       rulFacetInd = *pI;
00929     }
00930   }
00931 }
00932 
00933 //----------------------------------------------------------------------------
00934 
00935 MeshPointGrid::MeshPointGrid (const MeshKernel &rclM) 
00936  : MeshGrid(rclM) 
00937 {
00938   RebuildGrid();
00939 }
00940 
00941 MeshPointGrid::MeshPointGrid (void)
00942  : MeshGrid() 
00943 {
00944 }
00945 
00946 MeshPointGrid::MeshPointGrid (const MeshKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ)
00947  : MeshGrid(rclM) 
00948 {
00949   Rebuild(ulX, ulY, ulZ);
00950 }
00951 
00952 MeshPointGrid::MeshPointGrid (const MeshKernel &rclM, int   iCtGridPerAxis)
00953   : MeshGrid(rclM) 
00954 {
00955   Rebuild(iCtGridPerAxis);
00956 }
00957 
00958 MeshPointGrid::MeshPointGrid (const MeshKernel &rclM, float fGridLen)
00959   : MeshGrid(rclM)
00960 {
00961   Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
00962   Rebuild(std::max<unsigned long>((unsigned long)(clBBMesh.LengthX() / fGridLen), 1),
00963           std::max<unsigned long>((unsigned long)(clBBMesh.LengthY() / fGridLen), 1),
00964           std::max<unsigned long>((unsigned long)(clBBMesh.LengthZ() / fGridLen), 1));
00965 }
00966 
00967 void MeshPointGrid::AddPoint (const MeshPoint &rclPt, unsigned long ulPtIndex, float fEpsilon)
00968 {
00969   unsigned long ulX, ulY, ulZ;
00970   Pos(Base::Vector3f(rclPt.x, rclPt.y, rclPt.z), ulX, ulY, ulZ);
00971   if ( (ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ) )
00972     _aulGrid[ulX][ulY][ulZ].insert(ulPtIndex);
00973 }
00974 
00975 void MeshPointGrid::Validate (const MeshKernel &rclMesh)
00976 {
00977   if (_pclMesh != &rclMesh)
00978     Attach(rclMesh);
00979   else if (rclMesh.CountPoints() != _ulCtElements)
00980     RebuildGrid();
00981 }
00982 
00983 void MeshPointGrid::Validate (void)
00984 {
00985   if (_pclMesh == NULL)
00986     return;
00987 
00988   if (_pclMesh->CountPoints() != _ulCtElements)
00989     RebuildGrid();
00990 }
00991 
00992 bool MeshPointGrid::Verify() const
00993 {
00994   if ( !_pclMesh ) 
00995     return false; // no mesh attached
00996   if (_pclMesh->CountFacets() != _ulCtElements)
00997     return false; // not up-to-date
00998 
00999   MeshGridIterator it(*this);
01000   MeshPointIterator cP(*_pclMesh);
01001   for ( it.Init(); it.More(); it.Next() )
01002   {
01003     std::vector<unsigned long> aulElements;
01004     it.GetElements( aulElements );
01005     for ( std::vector<unsigned long>::iterator itP = aulElements.begin(); itP != aulElements.end(); ++itP )
01006     {
01007       cP.Set( *itP );
01008       if ( it.GetBoundBox().IsInBox( *cP ) == false )
01009         return false; // point doesn't lie inside the grid element
01010     }
01011   }
01012 
01013   return true;
01014 }
01015 
01016 void MeshPointGrid::RebuildGrid (void)
01017 {
01018   _ulCtElements = _pclMesh->CountPoints();
01019 
01020   InitGrid();
01021  
01022   // Daten-Struktur fuellen
01023 
01024   MeshPointIterator cPIter(*_pclMesh);
01025 
01026   unsigned long i = 0;
01027   for (cPIter.Init(); cPIter.More(); cPIter.Next())
01028   {
01029     AddPoint(*cPIter, i++);
01030   }
01031 }
01032 
01033 void MeshPointGrid::Pos (const Base::Vector3f &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
01034 {
01035   rulX = (unsigned long)((rclPoint.x - _fMinX) / _fGridLenX);
01036   rulY = (unsigned long)((rclPoint.y - _fMinY) / _fGridLenY);
01037   rulZ = (unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ);
01038 }
01039 
01040 unsigned long MeshPointGrid::FindElements (const Base::Vector3f &rclPoint, std::set<unsigned long>& aulElements) const
01041 {
01042   unsigned long ulX, ulY, ulZ;
01043   Pos(rclPoint, ulX, ulY, ulZ);
01044 
01045   // check if the given point is inside the grid structure
01046   if ( (ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ) )
01047   {
01048     return GetElements(ulX, ulY, ulZ, aulElements);
01049   }
01050 
01051   return 0;
01052 }
01053 
01054 // ----------------------------------------------------------------
01055 
01056 MeshGridIterator::MeshGridIterator (const MeshGrid &rclG)
01057 : _rclGrid(rclG),
01058   _ulX(0), _ulY(0), _ulZ(0),
01059   _clPt(0.0f, 0.0f, 0.0f), _clDir(0.0f, 0.0f, 0.0f),
01060   _bValidRay(false),
01061   _fMaxSearchArea (FLOAT_MAX)
01062 
01063 {
01064 }
01065 
01066 bool MeshGridIterator::InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, float fMaxSearchArea,
01067                                   std::vector<unsigned long> &raulElements)
01068 {
01069   bool ret = InitOnRay (rclPt, rclDir, raulElements);
01070   _fMaxSearchArea = fMaxSearchArea;
01071   return ret;
01072 }
01073 
01074 bool MeshGridIterator::InitOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir,
01075                                   std::vector<unsigned long> &raulElements)
01076 {
01077   // needed in NextOnRay() to avoid an infinite loop
01078   _cSearchPositions.clear();
01079 
01080   _fMaxSearchArea = FLOAT_MAX;
01081 
01082   raulElements.clear();        
01083 
01084   _clPt      = rclPt;
01085   _clDir     = rclDir;
01086   _bValidRay = false;
01087 
01088   // liegt Punkt innerhalb globalen BB
01089   if ((_rclGrid.GetBoundBox().IsInBox(rclPt)) == true)
01090   {  // Voxel bestimmen, indem der Startpunkt liegt
01091     _rclGrid.Position(rclPt, _ulX, _ulY, _ulZ);
01092     raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
01093     _bValidRay = true;
01094   }
01095   else
01096   { // Startpunkt ausserhalb
01097     Base::Vector3f cP0, cP1;
01098     if (_rclGrid.GetBoundBox().IntersectWithLine(rclPt, rclDir, cP0, cP1) == true)
01099     {  // naechsten Punkt bestimmen
01100       if ((cP0 - rclPt).Length() < (cP1 - rclPt).Length())
01101         _rclGrid.Position(cP0, _ulX, _ulY, _ulZ);
01102       else
01103         _rclGrid.Position(cP1, _ulX, _ulY, _ulZ);
01104 
01105       raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
01106       _bValidRay = true;
01107     }
01108   }
01109 
01110   return _bValidRay;
01111 }
01112 
01113 bool MeshGridIterator::NextOnRay (std::vector<unsigned long> &raulElements)
01114 {
01115   if (_bValidRay == false)
01116     return false;  // nicht initialisiert oder Strahl ausgetreten
01117   
01118   raulElements.clear();
01119 
01120   Base::Vector3f clIntersectPoint;
01121 
01122   // naechstes anliegende BB auf dem Suchstrahl suchen
01123   Base::BoundBox3f::SIDE tSide = _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ).GetSideFromRay(_clPt, _clDir, clIntersectPoint);
01124 
01125   // Suchbereich
01126   //
01127   if ((_clPt-clIntersectPoint).Length() > _fMaxSearchArea)
01128   {
01129       _bValidRay = false;
01130   }
01131   else
01132   {
01133     switch (tSide)
01134     {
01135     case Base::BoundBox3f::LEFT:   _ulX--;  break;
01136     case Base::BoundBox3f::RIGHT:  _ulX++;  break;
01137     case Base::BoundBox3f::BOTTOM: _ulY--;  break;
01138     case Base::BoundBox3f::TOP:    _ulY++;  break;
01139     case Base::BoundBox3f::FRONT:  _ulZ--;  break;
01140     case Base::BoundBox3f::BACK:   _ulZ++;  break;
01141 
01142     default:
01143     case Base::BoundBox3f::INVALID:
01144       _bValidRay = false;
01145       break;
01146     }
01147 
01148     GridElement pos(_ulX, _ulY, _ulZ);
01149     if ( _cSearchPositions.find( pos ) != _cSearchPositions.end() )
01150       _bValidRay = false; // grid element already visited => result from GetSideFromRay invalid
01151   }
01152 
01153   if ((_bValidRay == true) && (_rclGrid.CheckPos(_ulX, _ulY, _ulZ) == true))
01154   {
01155     GridElement pos(_ulX, _ulY, _ulZ); _cSearchPositions.insert(pos);
01156     raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()); 
01157   }
01158   else
01159     _bValidRay = false;  // Strahl ausgetreten
01160 
01161   return _bValidRay;
01162 }

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