00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
00026 #ifndef _PreComp_
00027 # include <algorithm>
00028 #endif
00029
00030
00031
00032 #include "PointsGrid.h"
00033
00034 using namespace Points;
00035
00036 PointsGrid::PointsGrid (const PointKernel &rclM)
00037 : _pclPoints(&rclM),
00038 _ulCtElements(0),
00039 _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
00040 _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00041 _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00042 {
00043 RebuildGrid();
00044 }
00045
00046 PointsGrid::PointsGrid (void)
00047 : _pclPoints(NULL),
00048 _ulCtElements(0),
00049 _ulCtGridsX(POINTS_CT_GRID), _ulCtGridsY(POINTS_CT_GRID), _ulCtGridsZ(POINTS_CT_GRID),
00050 _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00051 _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00052 {
00053 }
00054
00055 PointsGrid::PointsGrid (const PointKernel &rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ)
00056 : _pclPoints(&rclM),
00057 _ulCtElements(0),
00058 _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
00059 _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00060 _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00061 {
00062 Rebuild(ulX, ulY, ulZ);
00063 }
00064
00065 PointsGrid::PointsGrid (const PointKernel &rclM, int iCtGridPerAxis)
00066 : _pclPoints(&rclM),
00067 _ulCtElements(0),
00068 _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
00069 _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00070 _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00071 {
00072 Rebuild(iCtGridPerAxis);
00073 }
00074
00075 PointsGrid::PointsGrid (const PointKernel &rclM, double fGridLen)
00076 : _pclPoints(&rclM),
00077 _ulCtElements(0),
00078 _ulCtGridsX(0), _ulCtGridsY(0), _ulCtGridsZ(0),
00079 _fGridLenX(0.0f), _fGridLenY(0.0f), _fGridLenZ(0.0f),
00080 _fMinX(0.0f), _fMinY(0.0f), _fMinZ(0.0f)
00081 {
00082 Base::BoundBox3d clBBPts;
00083 for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
00084 clBBPts &= (*it);
00085 Rebuild(std::max<unsigned long>((unsigned long)(clBBPts.LengthX() / fGridLen), 1),
00086 std::max<unsigned long>((unsigned long)(clBBPts.LengthY() / fGridLen), 1),
00087 std::max<unsigned long>((unsigned long)(clBBPts.LengthZ() / fGridLen), 1));
00088 }
00089
00090 void PointsGrid::Attach (const PointKernel &rclM)
00091 {
00092 _pclPoints = &rclM;
00093 RebuildGrid();
00094 }
00095
00096 void PointsGrid::Clear (void)
00097 {
00098 _aulGrid.clear();
00099 _pclPoints = NULL;
00100 }
00101
00102 void PointsGrid::Rebuild (unsigned long ulX, unsigned long ulY, unsigned long ulZ)
00103 {
00104 _ulCtGridsX = ulX;
00105 _ulCtGridsY = ulY;
00106 _ulCtGridsZ = ulZ;
00107 _ulCtElements = HasElements();
00108 RebuildGrid();
00109 }
00110
00111 void PointsGrid::Rebuild (unsigned long ulPerGrid, unsigned long ulMaxGrid)
00112 {
00113 _ulCtElements = HasElements();
00114 CalculateGridLength(ulPerGrid, ulMaxGrid);
00115 RebuildGrid();
00116 }
00117
00118 void PointsGrid::Rebuild (int iCtGridPerAxis)
00119 {
00120 _ulCtElements = HasElements();
00121 CalculateGridLength(iCtGridPerAxis);
00122 RebuildGrid();
00123 }
00124
00125 void PointsGrid::InitGrid (void)
00126 {
00127 assert(_pclPoints != NULL);
00128
00129 unsigned long i, j;
00130
00131
00132
00133 if ((_ulCtGridsX == 0) || (_ulCtGridsX == 0) || (_ulCtGridsX == 0))
00134 CalculateGridLength(POINTS_CT_GRID, POINTS_MAX_GRIDS);
00135
00136
00137
00138 {
00139 Base::BoundBox3d clBBPts;
00140 for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
00141 clBBPts &= (*it);
00142
00143 double fLengthX = clBBPts.LengthX();
00144 double fLengthY = clBBPts.LengthY();
00145 double fLengthZ = clBBPts.LengthZ();
00146
00147 {
00148
00149
00150 _fGridLenX = (1.0f + fLengthX) / double(_ulCtGridsX);
00151 _fMinX = clBBPts.MinX - 0.5f;
00152 }
00153
00154 {
00155 _fGridLenY = (1.0f + fLengthY) / double(_ulCtGridsY);
00156 _fMinY = clBBPts.MinY - 0.5f;
00157 }
00158
00159 {
00160 _fGridLenZ = (1.0f + fLengthZ) / double(_ulCtGridsZ);
00161 _fMinZ = clBBPts.MinZ - 0.5f;
00162 }
00163 }
00164
00165
00166 _aulGrid.clear();
00167 _aulGrid.resize(_ulCtGridsX);
00168 for (i = 0; i < _ulCtGridsX; i++)
00169 {
00170 _aulGrid[i].resize(_ulCtGridsY);
00171 for (j = 0; j < _ulCtGridsY; j++)
00172 _aulGrid[i][j].resize(_ulCtGridsZ);
00173 }
00174 }
00175
00176 unsigned long PointsGrid::InSide (const Base::BoundBox3d &rclBB, std::vector<unsigned long> &raulElements, bool bDelDoubles) const
00177 {
00178 unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ;
00179
00180 raulElements.clear();
00181
00182
00183 Position(Base::Vector3d(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
00184 Position(Base::Vector3d(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 raulElements.insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
00193 }
00194 }
00195 }
00196
00197 if (bDelDoubles == true)
00198 {
00199
00200 std::sort(raulElements.begin(), raulElements.end());
00201 raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end());
00202 }
00203
00204 return raulElements.size();
00205 }
00206
00207 unsigned long PointsGrid::InSide (const Base::BoundBox3d &rclBB, std::vector<unsigned long> &raulElements, const Base::Vector3d &rclOrg, float fMaxDist, bool bDelDoubles) const
00208 {
00209 unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ;
00210 double fGridDiag = GetBoundBox(0, 0, 0).CalcDiagonalLength();
00211 double fMinDistP2 = (fGridDiag * fGridDiag) + (fMaxDist * fMaxDist);
00212
00213 raulElements.clear();
00214
00215
00216 Position(Base::Vector3d(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
00217 Position(Base::Vector3d(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
00218
00219 for (i = ulMinX; i <= ulMaxX; i++)
00220 {
00221 for (j = ulMinY; j <= ulMaxY; j++)
00222 {
00223 for (k = ulMinZ; k <= ulMaxZ; k++)
00224 {
00225 if (Base::DistanceP2(GetBoundBox(i, j, k).CalcCenter(), rclOrg) < fMinDistP2)
00226 raulElements.insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
00227 }
00228 }
00229 }
00230
00231 if (bDelDoubles == true)
00232 {
00233
00234 std::sort(raulElements.begin(), raulElements.end());
00235 raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end());
00236 }
00237
00238 return raulElements.size();
00239 }
00240
00241 unsigned long PointsGrid::InSide (const Base::BoundBox3d &rclBB, std::set<unsigned long> &raulElements) const
00242 {
00243 unsigned long i, j, k, ulMinX, ulMinY, ulMinZ, ulMaxX, ulMaxY, ulMaxZ;
00244
00245 raulElements.clear();
00246
00247
00248 Position(Base::Vector3d(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
00249 Position(Base::Vector3d(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
00250
00251 for (i = ulMinX; i <= ulMaxX; i++)
00252 {
00253 for (j = ulMinY; j <= ulMaxY; j++)
00254 {
00255 for (k = ulMinZ; k <= ulMaxZ; k++)
00256 {
00257 raulElements.insert(_aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
00258 }
00259 }
00260 }
00261
00262 return raulElements.size();
00263 }
00264
00265 void PointsGrid::Position (const Base::Vector3d &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00266 {
00267 if (rclPoint.x <= _fMinX)
00268 rulX = 0;
00269 else
00270 rulX = std::min<unsigned long>((unsigned long)((rclPoint.x - _fMinX) / _fGridLenX), _ulCtGridsX - 1);
00271
00272 if (rclPoint.y <= _fMinY)
00273 rulY = 0;
00274 else
00275 rulY = std::min<unsigned long>((unsigned long)((rclPoint.y - _fMinY) / _fGridLenY), _ulCtGridsY - 1);
00276
00277 if (rclPoint.z <= _fMinZ)
00278 rulZ = 0;
00279 else
00280 rulZ = std::min<unsigned long>((unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ), _ulCtGridsZ - 1);
00281 }
00282
00283 void PointsGrid::CalculateGridLength (unsigned long ulCtGrid, unsigned long ulMaxGrids)
00284 {
00285
00286
00287
00288 Base::BoundBox3d clBBPtsEnlarged;
00289 for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
00290 clBBPtsEnlarged &= (*it);
00291 double fVolElem;
00292
00293 if (_ulCtElements > (ulMaxGrids * ulCtGrid))
00294 fVolElem = (clBBPtsEnlarged.LengthX() * clBBPtsEnlarged.LengthY() * clBBPtsEnlarged.LengthZ()) / float(ulMaxGrids * ulCtGrid);
00295 else
00296 fVolElem = (clBBPtsEnlarged.LengthX() * clBBPtsEnlarged.LengthY() * clBBPtsEnlarged.LengthZ()) / float(_ulCtElements);
00297
00298 double fVol = fVolElem * float(ulCtGrid);
00299 double fGridLen = float(pow((float)fVol,(float) 1.0f / 3.0f));
00300
00301 _ulCtGridsX = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthX() / fGridLen), 1);
00302 _ulCtGridsY = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthY() / fGridLen), 1);
00303 _ulCtGridsZ = std::max<unsigned long>((unsigned long)(clBBPtsEnlarged.LengthZ() / fGridLen), 1);
00304 }
00305
00306 void PointsGrid::CalculateGridLength (int iCtGridPerAxis)
00307 {
00308 if (iCtGridPerAxis<=0)
00309 {
00310 CalculateGridLength(POINTS_CT_GRID, POINTS_MAX_GRIDS);
00311 return;
00312 }
00313
00314
00315
00316
00317 Base::BoundBox3d clBBPts;
00318 for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
00319 clBBPts &= (*it);
00320
00321 double fLenghtX = clBBPts.LengthX();
00322 double fLenghtY = clBBPts.LengthY();
00323 double fLenghtZ = clBBPts.LengthZ();
00324
00325 double fLenghtD = clBBPts.CalcDiagonalLength();
00326
00327 double fLengthTol = 0.05f * fLenghtD;
00328
00329 bool bLenghtXisZero = (fLenghtX <= fLengthTol);
00330 bool bLenghtYisZero = (fLenghtY <= fLengthTol);
00331 bool bLenghtZisZero = (fLenghtZ <= fLengthTol);
00332
00333 int iFlag = 0;
00334
00335 int iMaxGrids = 1;
00336
00337 if (bLenghtXisZero)
00338 iFlag += 1;
00339 else
00340 iMaxGrids *= iCtGridPerAxis;
00341
00342 if (bLenghtYisZero)
00343 iFlag += 2;
00344 else
00345 iMaxGrids *= iCtGridPerAxis;
00346
00347 if (bLenghtZisZero)
00348 iFlag += 4;
00349 else
00350 iMaxGrids *= iCtGridPerAxis;
00351
00352 unsigned long ulGridsFacets = 10;
00353
00354 double fFactorVolumen = 40.0;
00355 double fFactorArea = 10.0;
00356
00357 switch (iFlag)
00358 {
00359 case 0:
00360 {
00361 double fVolumen = fLenghtX * fLenghtY * fLenghtZ;
00362
00363 double fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements);
00364
00365 if ((fVolumenGrid * iMaxGrids) < fVolumen)
00366 fVolumenGrid = fVolumen / (float)iMaxGrids;
00367
00368 double fLengthGrid = float(pow((float)fVolumenGrid,(float) 1.0f / 3.0f));
00369
00370 _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
00371 _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
00372 _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
00373
00374 } break;
00375 case 1:
00376 {
00377 _ulCtGridsX = 1;
00378
00379 double fArea = fLenghtY * fLenghtZ;
00380
00381 double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
00382
00383 if ((fAreaGrid * iMaxGrids) < fArea)
00384 fAreaGrid = fArea / (double)iMaxGrids;
00385
00386 double fLengthGrid = double(sqrt(fAreaGrid));
00387
00388 _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
00389 _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
00390 } break;
00391 case 2:
00392 {
00393 _ulCtGridsY = 1;
00394
00395 double fArea = fLenghtX * fLenghtZ;
00396
00397 double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
00398
00399 if ((fAreaGrid * iMaxGrids) < fArea)
00400 fAreaGrid = fArea / (double)iMaxGrids;
00401
00402 double fLengthGrid = double(sqrt(fAreaGrid));
00403
00404 _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
00405 _ulCtGridsZ = std::max<unsigned long>((unsigned long)(fLenghtZ / fLengthGrid), 1);
00406 } break;
00407 case 3:
00408 {
00409 _ulCtGridsX = 1;
00410 _ulCtGridsY = 1;
00411 _ulCtGridsZ = iMaxGrids;
00412 } break;
00413 case 4:
00414 {
00415 _ulCtGridsZ = 1;
00416
00417 double fArea = fLenghtX * fLenghtY;
00418
00419 double fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
00420
00421 if ((fAreaGrid * iMaxGrids) < fArea)
00422 fAreaGrid = fArea / (float)iMaxGrids;
00423
00424 double fLengthGrid = double(sqrt(fAreaGrid));
00425
00426 _ulCtGridsX = std::max<unsigned long>((unsigned long)(fLenghtX / fLengthGrid), 1);
00427 _ulCtGridsY = std::max<unsigned long>((unsigned long)(fLenghtY / fLengthGrid), 1);
00428 } break;
00429 case 5:
00430 {
00431 _ulCtGridsX = 1;
00432 _ulCtGridsZ = 1;
00433 _ulCtGridsY = iMaxGrids;
00434 } break;
00435 case 6:
00436 {
00437 _ulCtGridsY = 1;
00438 _ulCtGridsZ = 1;
00439 _ulCtGridsX = iMaxGrids;
00440 } break;
00441 case 7:
00442 {
00443 _ulCtGridsX = iMaxGrids;
00444 _ulCtGridsY = iMaxGrids;
00445 _ulCtGridsZ = iMaxGrids;
00446 } break;
00447 }
00448 }
00449
00450 void PointsGrid::SearchNearestFromPoint (const Base::Vector3d &rclPt, std::set<unsigned long> &raclInd) const
00451 {
00452 raclInd.clear();
00453 Base::BoundBox3d clBB = GetBoundBox();
00454
00455 if (clBB.IsInBox(rclPt) == true)
00456 {
00457 unsigned long ulX, ulY, ulZ;
00458 Position(rclPt, ulX, ulY, ulZ);
00459
00460 unsigned long ulLevel = 0;
00461 while (raclInd.size() == 0)
00462 GetHull(ulX, ulY, ulZ, ulLevel++, raclInd);
00463 GetHull(ulX, ulY, ulZ, ulLevel, raclInd);
00464 }
00465 else
00466 {
00467 Base::BoundBox3d::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.CalcCenter() - rclPt);
00468 switch (tSide)
00469 {
00470 case Base::BoundBox3d::RIGHT:
00471 {
00472 int nX = 0;
00473 while (raclInd.size() == 0)
00474 {
00475 for (unsigned long i = 0; i < _ulCtGridsY; i++)
00476 {
00477 for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00478 raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
00479 }
00480 nX++;
00481 }
00482 break;
00483 }
00484 case Base::BoundBox3d::LEFT:
00485 {
00486 int nX = _ulCtGridsX - 1;
00487 while (raclInd.size() == 0)
00488 {
00489 for (unsigned long i = 0; i < _ulCtGridsY; i++)
00490 {
00491 for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00492 raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
00493 }
00494 nX++;
00495 }
00496 break;
00497 }
00498 case Base::BoundBox3d::TOP:
00499 {
00500 int nY = 0;
00501 while (raclInd.size() == 0)
00502 {
00503 for (unsigned long i = 0; i < _ulCtGridsX; i++)
00504 {
00505 for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00506 raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
00507 }
00508 nY++;
00509 }
00510 break;
00511 }
00512 case Base::BoundBox3d::BOTTOM:
00513 {
00514 int nY = _ulCtGridsY - 1;
00515 while (raclInd.size() == 0)
00516 {
00517 for (unsigned long i = 0; i < _ulCtGridsX; i++)
00518 {
00519 for (unsigned long j = 0; j < _ulCtGridsZ; j++)
00520 raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
00521 }
00522 nY--;
00523 }
00524 break;
00525 }
00526 case Base::BoundBox3d::BACK:
00527 {
00528 int nZ = 0;
00529 while (raclInd.size() == 0)
00530 {
00531 for (unsigned long i = 0; i < _ulCtGridsX; i++)
00532 {
00533 for (unsigned long j = 0; j < _ulCtGridsY; j++)
00534 raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
00535 }
00536 nZ++;
00537 }
00538 break;
00539 }
00540 case Base::BoundBox3d::FRONT:
00541 {
00542 int nZ = _ulCtGridsZ - 1;
00543 while (raclInd.size() == 0)
00544 {
00545 for (unsigned long i = 0; i < _ulCtGridsX; i++)
00546 {
00547 for (unsigned long j = 0; j < _ulCtGridsY; j++)
00548 raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
00549 }
00550 nZ--;
00551 }
00552 break;
00553 }
00554
00555 default:
00556 break;
00557 }
00558 }
00559 }
00560
00561 void PointsGrid::GetHull (unsigned long ulX, unsigned long ulY, unsigned long ulZ,
00562 unsigned long ulDistance, std::set<unsigned long> &raclInd) const
00563 {
00564 int nX1 = std::max<int>(0, int(ulX) - int(ulDistance));
00565 int nY1 = std::max<int>(0, int(ulY) - int(ulDistance));
00566 int nZ1 = std::max<int>(0, int(ulZ) - int(ulDistance));
00567 int nX2 = std::min<int>(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance));
00568 int nY2 = std::min<int>(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance));
00569 int nZ2 = std::min<int>(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance));
00570
00571 int i, j;
00572
00573
00574 for (i = nX1; i <= nX2; i++)
00575 {
00576 for (j = nY1; j <= nY2; j++)
00577 GetElements(i, j, nZ1, raclInd);
00578 }
00579
00580 for (i = nX1; i <= nX2; i++)
00581 {
00582 for (j = nY1; j <= nY2; j++)
00583 GetElements(i, j, nZ2, raclInd);
00584 }
00585
00586 for (i = nY1; i <= nY2; i++)
00587 {
00588 for (j = (nZ1+1); j <= (nZ2-1); j++)
00589 GetElements(nX1, i, j, raclInd);
00590 }
00591
00592 for (i = nY1; i <= nY2; i++)
00593 {
00594 for (j = (nZ1+1); j <= (nZ2-1); j++)
00595 GetElements(nX2, i, j, raclInd);
00596 }
00597
00598 for (i = (nX1+1); i <= (nX2-1); i++)
00599 {
00600 for (j = (nZ1+1); j <= (nZ2-1); j++)
00601 GetElements(i, nY1, j, raclInd);
00602 }
00603
00604 for (i = (nX1+1); i <= (nX2-1); i++)
00605 {
00606 for (j = (nZ1+1); j <= (nZ2-1); j++)
00607 GetElements(i, nY2, j, raclInd);
00608 }
00609 }
00610
00611 unsigned long PointsGrid::GetElements (unsigned long ulX, unsigned long ulY, unsigned long ulZ,
00612 std::set<unsigned long> &raclInd) const
00613 {
00614 const std::set<unsigned long> &rclSet = _aulGrid[ulX][ulY][ulZ];
00615 if (rclSet.size() > 0)
00616 {
00617 raclInd.insert(rclSet.begin(), rclSet.end());
00618 return rclSet.size();
00619 }
00620
00621 return 0;
00622 }
00623
00624 void PointsGrid::AddPoint (const Base::Vector3d &rclPt, unsigned long ulPtIndex, float fEpsilon)
00625 {
00626 unsigned long ulX, ulY, ulZ;
00627 Pos(Base::Vector3d(rclPt.x, rclPt.y, rclPt.z), ulX, ulY, ulZ);
00628 if ( (ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ) )
00629 _aulGrid[ulX][ulY][ulZ].insert(ulPtIndex);
00630 }
00631
00632 void PointsGrid::Validate (const PointKernel &rclPoints)
00633 {
00634 if (_pclPoints != &rclPoints)
00635 Attach(rclPoints);
00636 else if (rclPoints.size() != _ulCtElements)
00637 RebuildGrid();
00638 }
00639
00640 void PointsGrid::Validate (void)
00641 {
00642 if (_pclPoints == NULL)
00643 return;
00644
00645 if (_pclPoints->size() != _ulCtElements)
00646 RebuildGrid();
00647 }
00648
00649 bool PointsGrid::Verify() const
00650 {
00651 if ( !_pclPoints )
00652 return false;
00653 if (_pclPoints->size() != _ulCtElements)
00654 return false;
00655
00656 PointsGridIterator it(*this);
00657 for ( it.Init(); it.More(); it.Next() )
00658 {
00659 std::vector<unsigned long> aulElements;
00660 it.GetElements( aulElements );
00661 for ( std::vector<unsigned long>::iterator itP = aulElements.begin(); itP != aulElements.end(); ++itP )
00662 {
00663 const Base::Vector3d& cP = _pclPoints->getPoint(*itP);
00664 if ( it.GetBoundBox().IsInBox( cP ) == false )
00665 return false;
00666 }
00667 }
00668
00669 return true;
00670 }
00671
00672 void PointsGrid::RebuildGrid (void)
00673 {
00674 _ulCtElements = _pclPoints->size();
00675
00676 InitGrid();
00677
00678
00679
00680 unsigned long i = 0;
00681 for (PointKernel::const_iterator it = _pclPoints->begin(); it != _pclPoints->end(); ++it )
00682 {
00683 AddPoint(*it, i++);
00684 }
00685 }
00686
00687 void PointsGrid::Pos (const Base::Vector3d &rclPoint, unsigned long &rulX, unsigned long &rulY, unsigned long &rulZ) const
00688 {
00689 rulX = (unsigned long)((rclPoint.x - _fMinX) / _fGridLenX);
00690 rulY = (unsigned long)((rclPoint.y - _fMinY) / _fGridLenY);
00691 rulZ = (unsigned long)((rclPoint.z - _fMinZ) / _fGridLenZ);
00692 }
00693
00694 unsigned long PointsGrid::FindElements (const Base::Vector3d &rclPoint, std::set<unsigned long>& aulElements) const
00695 {
00696 unsigned long ulX, ulY, ulZ;
00697 Pos(rclPoint, ulX, ulY, ulZ);
00698
00699
00700 if ( (ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ) )
00701 {
00702 return GetElements(ulX, ulY, ulZ, aulElements);
00703 }
00704
00705 return 0;
00706 }
00707
00708
00709
00710 PointsGridIterator::PointsGridIterator (const PointsGrid &rclG)
00711 : _rclGrid(rclG),
00712 _ulX(0), _ulY(0), _ulZ(0),
00713 _clPt(0.0f, 0.0f, 0.0f), _clDir(0.0f, 0.0f, 0.0f),
00714 _bValidRay(false),
00715 _fMaxSearchArea (FLOAT_MAX)
00716
00717 {
00718 }
00719
00720 bool PointsGridIterator::InitOnRay (const Base::Vector3d &rclPt, const Base::Vector3d &rclDir, float fMaxSearchArea,
00721 std::vector<unsigned long> &raulElements)
00722 {
00723 bool ret = InitOnRay (rclPt, rclDir, raulElements);
00724 _fMaxSearchArea = fMaxSearchArea;
00725 return ret;
00726 }
00727
00728 bool PointsGridIterator::InitOnRay (const Base::Vector3d &rclPt, const Base::Vector3d &rclDir,
00729 std::vector<unsigned long> &raulElements)
00730 {
00731
00732 _cSearchPositions.clear();
00733
00734 _fMaxSearchArea = FLOAT_MAX;
00735
00736 raulElements.clear();
00737
00738 _clPt = rclPt;
00739 _clDir = rclDir;
00740 _bValidRay = false;
00741
00742
00743 if ((_rclGrid.GetBoundBox().IsInBox(rclPt)) == true)
00744 {
00745 _rclGrid.Position(rclPt, _ulX, _ulY, _ulZ);
00746 raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
00747 _bValidRay = true;
00748 }
00749 else
00750 {
00751 Base::Vector3d cP0, cP1;
00752 if (_rclGrid.GetBoundBox().IntersectWithLine(rclPt, rclDir, cP0, cP1) == true)
00753 {
00754 if ((cP0 - rclPt).Length() < (cP1 - rclPt).Length())
00755 _rclGrid.Position(cP0, _ulX, _ulY, _ulZ);
00756 else
00757 _rclGrid.Position(cP1, _ulX, _ulY, _ulZ);
00758
00759 raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
00760 _bValidRay = true;
00761 }
00762 }
00763
00764 return _bValidRay;
00765 }
00766
00767 bool PointsGridIterator::NextOnRay (std::vector<unsigned long> &raulElements)
00768 {
00769 if (_bValidRay == false)
00770 return false;
00771
00772 raulElements.clear();
00773
00774 Base::Vector3d clIntersectPoint;
00775
00776
00777 Base::BoundBox3d::SIDE tSide = _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ).GetSideFromRay(_clPt, _clDir, clIntersectPoint);
00778
00779
00780
00781 if ((_clPt-clIntersectPoint).Length() > _fMaxSearchArea)
00782 {
00783 _bValidRay = false;
00784 }
00785 else
00786 {
00787 switch (tSide)
00788 {
00789 case Base::BoundBox3d::LEFT: _ulX--; break;
00790 case Base::BoundBox3d::RIGHT: _ulX++; break;
00791 case Base::BoundBox3d::BOTTOM: _ulY--; break;
00792 case Base::BoundBox3d::TOP: _ulY++; break;
00793 case Base::BoundBox3d::FRONT: _ulZ--; break;
00794 case Base::BoundBox3d::BACK: _ulZ++; break;
00795
00796 default:
00797 case Base::BoundBox3d::INVALID:
00798 _bValidRay = false;
00799 break;
00800 }
00801
00802 GridElement pos(_ulX, _ulY, _ulZ);
00803 if ( _cSearchPositions.find( pos ) != _cSearchPositions.end() )
00804 _bValidRay = false;
00805 }
00806
00807 if ((_bValidRay == true) && (_rclGrid.CheckPos(_ulX, _ulY, _ulZ) == true))
00808 {
00809 GridElement pos(_ulX, _ulY, _ulZ); _cSearchPositions.insert(pos);
00810 raulElements.insert(raulElements.end(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(), _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end());
00811 }
00812 else
00813 _bValidRay = false;
00814
00815 return _bValidRay;
00816 }