| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| |
|
| | #include <algorithm>
|
| | #include <cmath>
|
| | #include <limits>
|
| |
|
| | #include "Algorithm.h"
|
| | #include "Grid.h"
|
| | #include "Iterator.h"
|
| | #include "MeshKernel.h"
|
| |
|
| |
|
| | using namespace MeshCore;
|
| |
|
| | MeshGrid::MeshGrid(const MeshKernel& rclM)
|
| | : _pclMesh(&rclM)
|
| | , _ulCtElements(0)
|
| | , _ulCtGridsX(0)
|
| | , _ulCtGridsY(0)
|
| | , _ulCtGridsZ(0)
|
| | , _fGridLenX(0.0F)
|
| | , _fGridLenY(0.0F)
|
| | , _fGridLenZ(0.0F)
|
| | , _fMinX(0.0F)
|
| | , _fMinY(0.0F)
|
| | , _fMinZ(0.0F)
|
| | {}
|
| |
|
| | MeshGrid::MeshGrid()
|
| | : _pclMesh(nullptr)
|
| | , _ulCtElements(0)
|
| | , _ulCtGridsX(MESH_CT_GRID)
|
| | , _ulCtGridsY(MESH_CT_GRID)
|
| | , _ulCtGridsZ(MESH_CT_GRID)
|
| | , _fGridLenX(0.0F)
|
| | , _fGridLenY(0.0F)
|
| | , _fGridLenZ(0.0F)
|
| | , _fMinX(0.0F)
|
| | , _fMinY(0.0F)
|
| | , _fMinZ(0.0F)
|
| | {}
|
| |
|
| | void MeshGrid::Attach(const MeshKernel& rclM)
|
| | {
|
| | _pclMesh = &rclM;
|
| | RebuildGrid();
|
| | }
|
| |
|
| | void MeshGrid::Clear()
|
| | {
|
| | _aulGrid.clear();
|
| | _pclMesh = nullptr;
|
| | }
|
| |
|
| | void MeshGrid::Rebuild(unsigned long ulX, unsigned long ulY, unsigned long ulZ)
|
| | {
|
| | _ulCtGridsX = ulX;
|
| | _ulCtGridsY = ulY;
|
| | _ulCtGridsZ = ulZ;
|
| | _ulCtElements = HasElements();
|
| | RebuildGrid();
|
| | }
|
| |
|
| | void MeshGrid::Rebuild(int iCtGridPerAxis)
|
| | {
|
| | _ulCtElements = HasElements();
|
| | CalculateGridLength(iCtGridPerAxis);
|
| | RebuildGrid();
|
| | }
|
| |
|
| | void MeshGrid::InitGrid()
|
| | {
|
| | assert(_pclMesh);
|
| |
|
| |
|
| |
|
| | if ((_ulCtGridsX == 0) || (_ulCtGridsY == 0) || (_ulCtGridsZ == 0)) {
|
| | CalculateGridLength(MESH_CT_GRID_PER_AXIS);
|
| | }
|
| |
|
| |
|
| |
|
| | {
|
| | Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
|
| |
|
| | float fLengthX = clBBMesh.LengthX();
|
| | float fLengthY = clBBMesh.LengthY();
|
| | float fLengthZ = clBBMesh.LengthZ();
|
| |
|
| | {
|
| |
|
| |
|
| | _fGridLenX = (1.0F + fLengthX) / float(_ulCtGridsX);
|
| | _fMinX = clBBMesh.MinX - 0.5F;
|
| | }
|
| |
|
| | {
|
| | _fGridLenY = (1.0F + fLengthY) / float(_ulCtGridsY);
|
| | _fMinY = clBBMesh.MinY - 0.5F;
|
| | }
|
| |
|
| | {
|
| | _fGridLenZ = (1.0F + fLengthZ) / float(_ulCtGridsZ);
|
| | _fMinZ = clBBMesh.MinZ - 0.5F;
|
| | }
|
| | }
|
| |
|
| |
|
| | _aulGrid.clear();
|
| | _aulGrid.resize(_ulCtGridsX);
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | _aulGrid[i].resize(_ulCtGridsY);
|
| | for (unsigned long j = 0; j < _ulCtGridsY; j++) {
|
| | _aulGrid[i][j].resize(_ulCtGridsZ);
|
| | }
|
| | }
|
| | }
|
| |
|
| | unsigned long MeshGrid::Inside(
|
| | const Base::BoundBox3f& rclBB,
|
| | std::vector<ElementIndex>& raulElements,
|
| | bool bDelDoubles
|
| | ) const
|
| | {
|
| | unsigned long ulMinX {};
|
| | unsigned long ulMinY {};
|
| | unsigned long ulMinZ {};
|
| | unsigned long ulMaxX {};
|
| | unsigned long ulMaxY {};
|
| | unsigned long ulMaxZ {};
|
| |
|
| | raulElements.clear();
|
| |
|
| |
|
| | Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
|
| | Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
|
| |
|
| | for (auto i = ulMinX; i <= ulMaxX; i++) {
|
| | for (auto j = ulMinY; j <= ulMaxY; j++) {
|
| | for (auto k = ulMinZ; k <= ulMaxZ; k++) {
|
| | raulElements
|
| | .insert(raulElements.end(), _aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
|
| | }
|
| | }
|
| | }
|
| |
|
| | if (bDelDoubles) {
|
| |
|
| | std::sort(raulElements.begin(), raulElements.end());
|
| | raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end());
|
| | }
|
| |
|
| | return raulElements.size();
|
| | }
|
| |
|
| | unsigned long MeshGrid::Inside(
|
| | const Base::BoundBox3f& rclBB,
|
| | std::vector<ElementIndex>& raulElements,
|
| | const Base::Vector3f& rclOrg,
|
| | float fMaxDist,
|
| | bool bDelDoubles
|
| | ) const
|
| | {
|
| | unsigned long ulMinX {};
|
| | unsigned long ulMinY {};
|
| | unsigned long ulMinZ {};
|
| | unsigned long ulMaxX {};
|
| | unsigned long ulMaxY {};
|
| | unsigned long ulMaxZ {};
|
| | float fGridDiag = GetBoundBox(0, 0, 0).CalcDiagonalLength();
|
| | float fMinDistP2 = (fGridDiag * fGridDiag) + (fMaxDist * fMaxDist);
|
| |
|
| | raulElements.clear();
|
| |
|
| |
|
| | Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
|
| | Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
|
| |
|
| | for (auto i = ulMinX; i <= ulMaxX; i++) {
|
| | for (auto j = ulMinY; j <= ulMaxY; j++) {
|
| | for (auto k = ulMinZ; k <= ulMaxZ; k++) {
|
| | if (Base::DistanceP2(GetBoundBox(i, j, k).GetCenter(), rclOrg) < fMinDistP2) {
|
| | raulElements.insert(
|
| | raulElements.end(),
|
| | _aulGrid[i][j][k].begin(),
|
| | _aulGrid[i][j][k].end()
|
| | );
|
| | }
|
| | }
|
| | }
|
| | }
|
| |
|
| | if (bDelDoubles) {
|
| |
|
| | std::sort(raulElements.begin(), raulElements.end());
|
| | raulElements.erase(std::unique(raulElements.begin(), raulElements.end()), raulElements.end());
|
| | }
|
| |
|
| | return raulElements.size();
|
| | }
|
| |
|
| | unsigned long MeshGrid::Inside(const Base::BoundBox3f& rclBB, std::set<ElementIndex>& raulElements) const
|
| | {
|
| | unsigned long ulMinX {};
|
| | unsigned long ulMinY {};
|
| | unsigned long ulMinZ {};
|
| | unsigned long ulMaxX {};
|
| | unsigned long ulMaxY {};
|
| | unsigned long ulMaxZ {};
|
| |
|
| | raulElements.clear();
|
| |
|
| |
|
| | Position(Base::Vector3f(rclBB.MinX, rclBB.MinY, rclBB.MinZ), ulMinX, ulMinY, ulMinZ);
|
| | Position(Base::Vector3f(rclBB.MaxX, rclBB.MaxY, rclBB.MaxZ), ulMaxX, ulMaxY, ulMaxZ);
|
| |
|
| | for (auto i = ulMinX; i <= ulMaxX; i++) {
|
| | for (auto j = ulMinY; j <= ulMaxY; j++) {
|
| | for (auto k = ulMinZ; k <= ulMaxZ; k++) {
|
| | raulElements.insert(_aulGrid[i][j][k].begin(), _aulGrid[i][j][k].end());
|
| | }
|
| | }
|
| | }
|
| |
|
| | return raulElements.size();
|
| | }
|
| |
|
| | bool MeshGrid::CheckPosition(
|
| | const Base::Vector3f& rclPoint,
|
| | unsigned long& rulX,
|
| | unsigned long& rulY,
|
| | unsigned long& rulZ
|
| | ) const
|
| | {
|
| | rulX = static_cast<unsigned long>((rclPoint.x - _fMinX) / _fGridLenX);
|
| | rulY = static_cast<unsigned long>((rclPoint.y - _fMinY) / _fGridLenY);
|
| | rulZ = static_cast<unsigned long>((rclPoint.z - _fMinZ) / _fGridLenZ);
|
| |
|
| | return ((rulX < _ulCtGridsX) && (rulY < _ulCtGridsY) && (rulZ < _ulCtGridsZ));
|
| | }
|
| |
|
| | void MeshGrid::Position(
|
| | const Base::Vector3f& rclPoint,
|
| | unsigned long& rulX,
|
| | unsigned long& rulY,
|
| | unsigned long& rulZ
|
| | ) const
|
| | {
|
| | if (rclPoint.x <= _fMinX) {
|
| | rulX = 0;
|
| | }
|
| | else {
|
| | rulX = std::min<unsigned long>(
|
| | static_cast<unsigned long>((rclPoint.x - _fMinX) / _fGridLenX),
|
| | _ulCtGridsX - 1
|
| | );
|
| | }
|
| |
|
| | if (rclPoint.y <= _fMinY) {
|
| | rulY = 0;
|
| | }
|
| | else {
|
| | rulY = std::min<unsigned long>(
|
| | static_cast<unsigned long>((rclPoint.y - _fMinY) / _fGridLenY),
|
| | _ulCtGridsY - 1
|
| | );
|
| | }
|
| |
|
| | if (rclPoint.z <= _fMinZ) {
|
| | rulZ = 0;
|
| | }
|
| | else {
|
| | rulZ = std::min<unsigned long>(
|
| | static_cast<unsigned long>((rclPoint.z - _fMinZ) / _fGridLenZ),
|
| | _ulCtGridsZ - 1
|
| | );
|
| | }
|
| | }
|
| |
|
| | void MeshGrid::CalculateGridLength(int iCtGridPerAxis)
|
| | {
|
| |
|
| |
|
| |
|
| | Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
|
| |
|
| | float fLenghtX = clBBMesh.LengthX();
|
| | float fLenghtY = clBBMesh.LengthY();
|
| | float fLenghtZ = clBBMesh.LengthZ();
|
| |
|
| | float fLenghtD = clBBMesh.CalcDiagonalLength();
|
| |
|
| | float fLengthTol = 0.05F * fLenghtD;
|
| |
|
| | bool bLenghtXisZero = (fLenghtX <= fLengthTol);
|
| | bool bLenghtYisZero = (fLenghtY <= fLengthTol);
|
| | bool bLenghtZisZero = (fLenghtZ <= fLengthTol);
|
| |
|
| | int iFlag = 0;
|
| |
|
| | int iMaxGrids = 1;
|
| |
|
| | if (bLenghtXisZero) {
|
| | iFlag += 1;
|
| | }
|
| | else {
|
| | iMaxGrids *= iCtGridPerAxis;
|
| | }
|
| |
|
| | if (bLenghtYisZero) {
|
| | iFlag += 2;
|
| | }
|
| | else {
|
| | iMaxGrids *= iCtGridPerAxis;
|
| | }
|
| |
|
| | if (bLenghtZisZero) {
|
| | iFlag += 4;
|
| | }
|
| | else {
|
| | iMaxGrids *= iCtGridPerAxis;
|
| | }
|
| |
|
| | unsigned long ulGridsFacets = 10;
|
| |
|
| | float fFactorVolumen = 40.0;
|
| | float fFactorArea = 10.0;
|
| |
|
| | switch (iFlag) {
|
| | case 0: {
|
| | float fVolumen = fLenghtX * fLenghtY * fLenghtZ;
|
| |
|
| | float fVolumenGrid = (fVolumen * ulGridsFacets) / (fFactorVolumen * _ulCtElements);
|
| |
|
| | if ((fVolumenGrid * iMaxGrids) < fVolumen) {
|
| | fVolumenGrid = fVolumen / static_cast<float>(iMaxGrids);
|
| | }
|
| |
|
| | float fLengthGrid = std::pow(fVolumenGrid, 1.0F / 3.0F);
|
| |
|
| | _ulCtGridsX = std::max(static_cast<unsigned long>(fLenghtX / fLengthGrid), 1UL);
|
| | _ulCtGridsY = std::max(static_cast<unsigned long>(fLenghtY / fLengthGrid), 1UL);
|
| | _ulCtGridsZ = std::max(static_cast<unsigned long>(fLenghtZ / fLengthGrid), 1UL);
|
| |
|
| | } break;
|
| | case 1: {
|
| | _ulCtGridsX = 1;
|
| |
|
| | float fArea = fLenghtY * fLenghtZ;
|
| |
|
| | float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
|
| |
|
| | if ((fAreaGrid * iMaxGrids) < fArea) {
|
| | fAreaGrid = fArea / static_cast<float>(iMaxGrids);
|
| | }
|
| |
|
| | auto fLengthGrid = float(std::sqrt(fAreaGrid));
|
| |
|
| | _ulCtGridsY
|
| | = std::max<unsigned long>(static_cast<unsigned long>(fLenghtY / fLengthGrid), 1);
|
| | _ulCtGridsZ
|
| | = std::max<unsigned long>(static_cast<unsigned long>(fLenghtZ / fLengthGrid), 1);
|
| | } break;
|
| | case 2: {
|
| | _ulCtGridsY = 1;
|
| |
|
| | float fArea = fLenghtX * fLenghtZ;
|
| |
|
| | float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
|
| |
|
| | if ((fAreaGrid * iMaxGrids) < fArea) {
|
| | fAreaGrid = fArea / static_cast<float>(iMaxGrids);
|
| | }
|
| |
|
| | auto fLengthGrid = float(std::sqrt(fAreaGrid));
|
| |
|
| | _ulCtGridsX
|
| | = std::max<unsigned long>(static_cast<unsigned long>(fLenghtX / fLengthGrid), 1);
|
| | _ulCtGridsZ
|
| | = std::max<unsigned long>(static_cast<unsigned long>(fLenghtZ / fLengthGrid), 1);
|
| | } break;
|
| | case 3: {
|
| | _ulCtGridsX = 1;
|
| | _ulCtGridsY = 1;
|
| | _ulCtGridsZ = static_cast<unsigned long>(iMaxGrids);
|
| | } break;
|
| | case 4: {
|
| | _ulCtGridsZ = 1;
|
| |
|
| | float fArea = fLenghtX * fLenghtY;
|
| |
|
| | float fAreaGrid = (fArea * ulGridsFacets) / (fFactorArea * _ulCtElements);
|
| |
|
| | if ((fAreaGrid * iMaxGrids) < fArea) {
|
| | fAreaGrid = fArea / static_cast<float>(iMaxGrids);
|
| | }
|
| |
|
| | auto fLengthGrid = float(std::sqrt(fAreaGrid));
|
| |
|
| | _ulCtGridsX
|
| | = std::max<unsigned long>(static_cast<unsigned long>(fLenghtX / fLengthGrid), 1);
|
| | _ulCtGridsY
|
| | = std::max<unsigned long>(static_cast<unsigned long>(fLenghtY / fLengthGrid), 1);
|
| | } break;
|
| | case 5: {
|
| | _ulCtGridsX = 1;
|
| | _ulCtGridsZ = 1;
|
| | _ulCtGridsY = static_cast<unsigned long>(iMaxGrids);
|
| | } break;
|
| | case 6: {
|
| | _ulCtGridsY = 1;
|
| | _ulCtGridsZ = 1;
|
| | _ulCtGridsX = static_cast<unsigned long>(iMaxGrids);
|
| | } break;
|
| | case 7: {
|
| | _ulCtGridsX = static_cast<unsigned long>(iMaxGrids);
|
| | _ulCtGridsY = static_cast<unsigned long>(iMaxGrids);
|
| | _ulCtGridsZ = static_cast<unsigned long>(iMaxGrids);
|
| | } break;
|
| | }
|
| | }
|
| |
|
| | void MeshGrid::SearchNearestFromPoint(const Base::Vector3f& pnt, std::set<ElementIndex>& indices) const
|
| | {
|
| | indices.clear();
|
| | Base::BoundBox3f clBB = GetBoundBox();
|
| |
|
| | if (clBB.IsInBox(pnt)) {
|
| | unsigned long ulX {};
|
| | unsigned long ulY {};
|
| | unsigned long ulZ {};
|
| | Position(pnt, ulX, ulY, ulZ);
|
| |
|
| | unsigned long ulMaxLevel
|
| | = std::max<unsigned long>(_ulCtGridsX, std::max<unsigned long>(_ulCtGridsY, _ulCtGridsZ));
|
| | unsigned long ulLevel = 0;
|
| | while (indices.empty() && ulLevel <= ulMaxLevel) {
|
| | GetHull(ulX, ulY, ulZ, ulLevel++, indices);
|
| | }
|
| | GetHull(ulX, ulY, ulZ, ulLevel, indices);
|
| | }
|
| | else {
|
| | Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(pnt, clBB.GetCenter() - pnt);
|
| | switch (tSide) {
|
| | case Base::BoundBox3f::RIGHT: {
|
| | unsigned long nX = 0;
|
| | while (indices.empty() && nX < _ulCtGridsX) {
|
| | for (unsigned long i = 0; i < _ulCtGridsY; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | indices.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
|
| | }
|
| | }
|
| | nX++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::LEFT: {
|
| | unsigned long nX = _ulCtGridsX - 1;
|
| | while (indices.empty() && nX < _ulCtGridsX) {
|
| | for (unsigned long i = 0; i < _ulCtGridsY; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | indices.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end());
|
| | }
|
| | }
|
| | nX++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::TOP: {
|
| | unsigned long nY = 0;
|
| | while (indices.empty() && nY < _ulCtGridsY) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | indices.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
|
| | }
|
| | }
|
| | nY++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::BOTTOM: {
|
| | unsigned long nY = _ulCtGridsY - 1;
|
| | while (indices.empty() && nY < _ulCtGridsY) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | indices.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end());
|
| | }
|
| | }
|
| | nY--;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::BACK: {
|
| | unsigned long nZ = 0;
|
| | while (indices.empty() && nZ < _ulCtGridsZ) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsY; j++) {
|
| | indices.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
|
| | }
|
| | }
|
| | nZ++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::FRONT: {
|
| | unsigned long nZ = _ulCtGridsZ - 1;
|
| | while (indices.empty() && nZ < _ulCtGridsZ) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsY; j++) {
|
| | indices.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end());
|
| | }
|
| | }
|
| | nZ--;
|
| | }
|
| | break;
|
| | }
|
| |
|
| | default:
|
| | break;
|
| | }
|
| | }
|
| | }
|
| |
|
| | void MeshGrid::GetHull(
|
| | unsigned long ulX,
|
| | unsigned long ulY,
|
| | unsigned long ulZ,
|
| | unsigned long ulDistance,
|
| | std::set<ElementIndex>& raclInd
|
| | ) const
|
| | {
|
| | int nX1 = std::max<int>(0, int(ulX) - int(ulDistance));
|
| | int nY1 = std::max<int>(0, int(ulY) - int(ulDistance));
|
| | int nZ1 = std::max<int>(0, int(ulZ) - int(ulDistance));
|
| | int nX2 = std::min<int>(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance));
|
| | int nY2 = std::min<int>(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance));
|
| | int nZ2 = std::min<int>(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance));
|
| |
|
| |
|
| | for (int i = nX1; i <= nX2; i++) {
|
| | for (int j = nY1; j <= nY2; j++) {
|
| | GetElements(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | static_cast<unsigned long>(nZ1),
|
| | raclInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = nX1; i <= nX2; i++) {
|
| | for (int j = nY1; j <= nY2; j++) {
|
| | GetElements(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | static_cast<unsigned long>(nZ2),
|
| | raclInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = nY1; i <= nY2; i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | GetElements(
|
| | static_cast<unsigned long>(nX1),
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | raclInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = nY1; i <= nY2; i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | GetElements(
|
| | static_cast<unsigned long>(nX2),
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | raclInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = (nX1 + 1); i <= (nX2 - 1); i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | GetElements(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(nY1),
|
| | static_cast<unsigned long>(j),
|
| | raclInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = (nX1 + 1); i <= (nX2 - 1); i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | GetElements(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(nY2),
|
| | static_cast<unsigned long>(j),
|
| | raclInd
|
| | );
|
| | }
|
| | }
|
| | }
|
| |
|
| | unsigned long MeshGrid::GetElements(
|
| | unsigned long ulX,
|
| | unsigned long ulY,
|
| | unsigned long ulZ,
|
| | std::set<ElementIndex>& raclInd
|
| | ) const
|
| | {
|
| | const std::set<ElementIndex>& rclSet = _aulGrid[ulX][ulY][ulZ];
|
| | if (!rclSet.empty()) {
|
| | raclInd.insert(rclSet.begin(), rclSet.end());
|
| | return rclSet.size();
|
| | }
|
| |
|
| | return 0;
|
| | }
|
| |
|
| | unsigned long MeshGrid::GetElements(
|
| | const Base::Vector3f& rclPoint,
|
| | std::vector<ElementIndex>& aulFacets
|
| | ) const
|
| | {
|
| | unsigned long ulX {};
|
| | unsigned long ulY {};
|
| | unsigned long ulZ {};
|
| | if (!CheckPosition(rclPoint, ulX, ulY, ulZ)) {
|
| | return 0;
|
| | }
|
| |
|
| | aulFacets.resize(_aulGrid[ulX][ulY][ulZ].size());
|
| |
|
| | std::copy(_aulGrid[ulX][ulY][ulZ].begin(), _aulGrid[ulX][ulY][ulZ].end(), aulFacets.begin());
|
| | return aulFacets.size();
|
| | }
|
| |
|
| | unsigned long MeshGrid::GetIndexToPosition(unsigned long ulX, unsigned long ulY, unsigned long ulZ) const
|
| | {
|
| | if (!CheckPos(ulX, ulY, ulZ)) {
|
| | return std::numeric_limits<unsigned long>::max();
|
| | }
|
| | return (ulZ * _ulCtGridsY + ulY) * _ulCtGridsX + ulX;
|
| | }
|
| |
|
| | bool MeshGrid::GetPositionToIndex(
|
| | unsigned long id,
|
| | unsigned long& ulX,
|
| | unsigned long& ulY,
|
| | unsigned long& ulZ
|
| | ) const
|
| | {
|
| | ulX = id % _ulCtGridsX;
|
| | ulY = (id / _ulCtGridsX) % _ulCtGridsY;
|
| | ulZ = id / (_ulCtGridsX * _ulCtGridsY);
|
| |
|
| | if (!CheckPos(ulX, ulY, ulZ)) {
|
| | ulX = std::numeric_limits<unsigned long>::max();
|
| | ulY = std::numeric_limits<unsigned long>::max();
|
| | ulZ = std::numeric_limits<unsigned long>::max();
|
| | return false;
|
| | }
|
| |
|
| | return true;
|
| | }
|
| |
|
| |
|
| |
|
| | MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM)
|
| | : MeshGrid(rclM)
|
| | {
|
| | MeshFacetGrid::RebuildGrid();
|
| | }
|
| |
|
| | MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM, int iCtGridPerAxis)
|
| | : MeshGrid(rclM)
|
| | {
|
| | Rebuild(iCtGridPerAxis);
|
| | }
|
| |
|
| | MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ)
|
| | : MeshGrid(rclM)
|
| | {
|
| | Rebuild(ulX, ulY, ulZ);
|
| | }
|
| |
|
| | MeshFacetGrid::MeshFacetGrid(const MeshKernel& rclM, float fGridLen)
|
| | : MeshGrid(rclM)
|
| | {
|
| | Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
|
| | Rebuild(
|
| | std::max<unsigned long>(static_cast<unsigned long>(clBBMesh.LengthX() / fGridLen), 1),
|
| | std::max<unsigned long>(static_cast<unsigned long>(clBBMesh.LengthY() / fGridLen), 1),
|
| | std::max<unsigned long>(static_cast<unsigned long>(clBBMesh.LengthZ() / fGridLen), 1)
|
| | );
|
| | }
|
| |
|
| | void MeshFacetGrid::Validate(const MeshKernel& rclMesh)
|
| | {
|
| | if (_pclMesh != &rclMesh) {
|
| | Attach(rclMesh);
|
| | }
|
| | else if (rclMesh.CountFacets() != _ulCtElements) {
|
| | RebuildGrid();
|
| | }
|
| | }
|
| |
|
| | void MeshFacetGrid::Validate()
|
| | {
|
| | if (!_pclMesh) {
|
| | return;
|
| | }
|
| |
|
| | if (_pclMesh->CountFacets() != _ulCtElements) {
|
| | RebuildGrid();
|
| | }
|
| | }
|
| |
|
| | bool MeshFacetGrid::Verify() const
|
| | {
|
| | if (!_pclMesh) {
|
| | return false;
|
| | }
|
| | if (_pclMesh->CountFacets() != _ulCtElements) {
|
| | return false;
|
| | }
|
| |
|
| | MeshGridIterator it(*this);
|
| | MeshFacetIterator cF(*_pclMesh);
|
| | for (it.Init(); it.More(); it.Next()) {
|
| | std::vector<ElementIndex> aulElements;
|
| | it.GetElements(aulElements);
|
| | for (ElementIndex element : aulElements) {
|
| | cF.Set(element);
|
| | if (!cF->IntersectBoundingBox(it.GetBoundBox())) {
|
| | return false;
|
| | }
|
| | }
|
| | }
|
| |
|
| | return true;
|
| | }
|
| |
|
| | void MeshFacetGrid::RebuildGrid()
|
| | {
|
| | _ulCtElements = _pclMesh->CountFacets();
|
| |
|
| | InitGrid();
|
| |
|
| |
|
| | MeshFacetIterator clFIter(*_pclMesh);
|
| |
|
| | unsigned long i = 0;
|
| | for (clFIter.Init(); clFIter.More(); clFIter.Next()) {
|
| |
|
| | AddFacet(*clFIter, i++);
|
| | }
|
| | }
|
| |
|
| | unsigned long MeshFacetGrid::SearchNearestFromPoint(const Base::Vector3f& rclPt) const
|
| | {
|
| | ElementIndex ulFacetInd = ELEMENT_INDEX_MAX;
|
| | float fMinDist = std::numeric_limits<float>::max();
|
| | Base::BoundBox3f clBB = GetBoundBox();
|
| |
|
| | if (clBB.IsInBox(rclPt)) {
|
| | unsigned long ulX {};
|
| | unsigned long ulY {};
|
| | unsigned long ulZ {};
|
| | Position(rclPt, ulX, ulY, ulZ);
|
| | float fMinGridDist = std::min<float>(std::min<float>(_fGridLenX, _fGridLenY), _fGridLenZ);
|
| | unsigned long ulDistance = 0;
|
| | while (fMinDist > (fMinGridDist * float(ulDistance))) {
|
| | SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist);
|
| | ulDistance++;
|
| | }
|
| | SearchNearestFacetInHull(ulX, ulY, ulZ, ulDistance, rclPt, ulFacetInd, fMinDist);
|
| | }
|
| | else {
|
| | Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.GetCenter() - rclPt);
|
| | switch (tSide) {
|
| | case Base::BoundBox3f::RIGHT: {
|
| | unsigned long nX = 0;
|
| | while ((fMinDist > ((clBB.MinX - rclPt.x) + (float(nX) * _fGridLenX)))
|
| | && (nX < _ulCtGridsX)) {
|
| | for (unsigned long i = 0; i < _ulCtGridsY; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd);
|
| | }
|
| | }
|
| | nX++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::LEFT: {
|
| | unsigned long nX = _ulCtGridsX - 1;
|
| | while ((fMinDist > ((rclPt.x - clBB.MinX) + (float(nX) * _fGridLenX)))
|
| | && (nX < _ulCtGridsX)) {
|
| | for (unsigned long i = 0; i < _ulCtGridsY; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | SearchNearestFacetInGrid(nX, i, j, rclPt, fMinDist, ulFacetInd);
|
| | }
|
| | }
|
| | nX--;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::TOP: {
|
| | unsigned long nY = 0;
|
| | while ((fMinDist > ((clBB.MinY - rclPt.y) + (float(nY) * _fGridLenY)))
|
| | && (nY < _ulCtGridsY)) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd);
|
| | }
|
| | }
|
| | nY++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::BOTTOM: {
|
| | unsigned long nY = _ulCtGridsY - 1;
|
| | while ((fMinDist > ((rclPt.y - clBB.MinY) + (float(nY) * _fGridLenY)))
|
| | && (nY < _ulCtGridsY)) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsZ; j++) {
|
| | SearchNearestFacetInGrid(i, nY, j, rclPt, fMinDist, ulFacetInd);
|
| | }
|
| | }
|
| | nY--;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::BACK: {
|
| | unsigned long nZ = 0;
|
| | while ((fMinDist > ((clBB.MinZ - rclPt.z) + (float(nZ) * _fGridLenZ)))
|
| | && (nZ < _ulCtGridsZ)) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsY; j++) {
|
| | SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd);
|
| | }
|
| | }
|
| | nZ++;
|
| | }
|
| | break;
|
| | }
|
| | case Base::BoundBox3f::FRONT: {
|
| | unsigned long nZ = _ulCtGridsZ - 1;
|
| | while ((fMinDist > ((rclPt.z - clBB.MinZ) + (float(nZ) * _fGridLenZ)))
|
| | && (nZ < _ulCtGridsZ)) {
|
| | for (unsigned long i = 0; i < _ulCtGridsX; i++) {
|
| | for (unsigned long j = 0; j < _ulCtGridsY; j++) {
|
| | SearchNearestFacetInGrid(i, j, nZ, rclPt, fMinDist, ulFacetInd);
|
| | }
|
| | }
|
| | nZ--;
|
| | }
|
| | break;
|
| | }
|
| | default:
|
| | break;
|
| | }
|
| | }
|
| |
|
| | return ulFacetInd;
|
| | }
|
| |
|
| | unsigned long MeshFacetGrid::SearchNearestFromPoint(const Base::Vector3f& rclPt, float fMaxSearchArea) const
|
| | {
|
| | std::vector<ElementIndex> aulFacets;
|
| | ElementIndex ulFacetInd = ELEMENT_INDEX_MAX;
|
| | float fMinDist = fMaxSearchArea;
|
| |
|
| | MeshAlgorithm clFTool(*_pclMesh);
|
| |
|
| | Base::BoundBox3f clBB(
|
| | rclPt.x - fMaxSearchArea,
|
| | rclPt.y - fMaxSearchArea,
|
| | rclPt.z - fMaxSearchArea,
|
| | rclPt.x + fMaxSearchArea,
|
| | rclPt.y + fMaxSearchArea,
|
| | rclPt.z + fMaxSearchArea
|
| | );
|
| |
|
| | Inside(clBB, aulFacets, rclPt, fMaxSearchArea, true);
|
| |
|
| | for (ElementIndex facet : aulFacets) {
|
| | float fDist {};
|
| |
|
| | if (clFTool.Distance(rclPt, facet, fMinDist, fDist)) {
|
| | fMinDist = fDist;
|
| | ulFacetInd = facet;
|
| | }
|
| | }
|
| |
|
| | return ulFacetInd;
|
| | }
|
| |
|
| | void MeshFacetGrid::SearchNearestFacetInHull(
|
| | unsigned long ulX,
|
| | unsigned long ulY,
|
| | unsigned long ulZ,
|
| | unsigned long ulDistance,
|
| | const Base::Vector3f& rclPt,
|
| | ElementIndex& rulFacetInd,
|
| | float& rfMinDist
|
| | ) const
|
| | {
|
| | int nX1 = std::max<int>(0, int(ulX) - int(ulDistance));
|
| | int nY1 = std::max<int>(0, int(ulY) - int(ulDistance));
|
| | int nZ1 = std::max<int>(0, int(ulZ) - int(ulDistance));
|
| | int nX2 = std::min<int>(int(_ulCtGridsX) - 1, int(ulX) + int(ulDistance));
|
| | int nY2 = std::min<int>(int(_ulCtGridsY) - 1, int(ulY) + int(ulDistance));
|
| | int nZ2 = std::min<int>(int(_ulCtGridsZ) - 1, int(ulZ) + int(ulDistance));
|
| |
|
| |
|
| | for (int i = nX1; i <= nX2; i++) {
|
| | for (int j = nY1; j <= nY2; j++) {
|
| | SearchNearestFacetInGrid(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | static_cast<unsigned long>(nZ1),
|
| | rclPt,
|
| | rfMinDist,
|
| | rulFacetInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = nX1; i <= nX2; i++) {
|
| | for (int j = nY1; j <= nY2; j++) {
|
| | SearchNearestFacetInGrid(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | static_cast<unsigned long>(nZ2),
|
| | rclPt,
|
| | rfMinDist,
|
| | rulFacetInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = nY1; i <= nY2; i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | SearchNearestFacetInGrid(
|
| | static_cast<unsigned long>(nX1),
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | rclPt,
|
| | rfMinDist,
|
| | rulFacetInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = nY1; i <= nY2; i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | SearchNearestFacetInGrid(
|
| | static_cast<unsigned long>(nX2),
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(j),
|
| | rclPt,
|
| | rfMinDist,
|
| | rulFacetInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = (nX1 + 1); i <= (nX2 - 1); i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | SearchNearestFacetInGrid(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(nY1),
|
| | static_cast<unsigned long>(j),
|
| | rclPt,
|
| | rfMinDist,
|
| | rulFacetInd
|
| | );
|
| | }
|
| | }
|
| |
|
| | for (int i = (nX1 + 1); i <= (nX2 - 1); i++) {
|
| | for (int j = (nZ1 + 1); j <= (nZ2 - 1); j++) {
|
| | SearchNearestFacetInGrid(
|
| | static_cast<unsigned long>(i),
|
| | static_cast<unsigned long>(nY2),
|
| | static_cast<unsigned long>(j),
|
| | rclPt,
|
| | rfMinDist,
|
| | rulFacetInd
|
| | );
|
| | }
|
| | }
|
| | }
|
| |
|
| | void MeshFacetGrid::SearchNearestFacetInGrid(
|
| | unsigned long ulX,
|
| | unsigned long ulY,
|
| | unsigned long ulZ,
|
| | const Base::Vector3f& rclPt,
|
| | float& rfMinDist,
|
| | ElementIndex& rulFacetInd
|
| | ) const
|
| | {
|
| | const std::set<ElementIndex>& rclSet = _aulGrid[ulX][ulY][ulZ];
|
| | for (ElementIndex pI : rclSet) {
|
| | float fDist = _pclMesh->GetFacet(pI).DistanceToPoint(rclPt);
|
| | if (fDist < rfMinDist) {
|
| | rfMinDist = fDist;
|
| | rulFacetInd = pI;
|
| | }
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | MeshPointGrid::MeshPointGrid(const MeshKernel& rclM)
|
| | : MeshGrid(rclM)
|
| | {
|
| | MeshPointGrid::RebuildGrid();
|
| | }
|
| |
|
| | MeshPointGrid::MeshPointGrid() = default;
|
| |
|
| | MeshPointGrid::MeshPointGrid(const MeshKernel& rclM, unsigned long ulX, unsigned long ulY, unsigned long ulZ)
|
| | : MeshGrid(rclM)
|
| | {
|
| | Rebuild(ulX, ulY, ulZ);
|
| | }
|
| |
|
| | MeshPointGrid::MeshPointGrid(const MeshKernel& rclM, int iCtGridPerAxis)
|
| | : MeshGrid(rclM)
|
| | {
|
| | Rebuild(iCtGridPerAxis);
|
| | }
|
| |
|
| | MeshPointGrid::MeshPointGrid(const MeshKernel& rclM, float fGridLen)
|
| | : MeshGrid(rclM)
|
| | {
|
| | Base::BoundBox3f clBBMesh = _pclMesh->GetBoundBox();
|
| | Rebuild(
|
| | std::max<unsigned long>(static_cast<unsigned long>(clBBMesh.LengthX() / fGridLen), 1),
|
| | std::max<unsigned long>(static_cast<unsigned long>(clBBMesh.LengthY() / fGridLen), 1),
|
| | std::max<unsigned long>(static_cast<unsigned long>(clBBMesh.LengthZ() / fGridLen), 1)
|
| | );
|
| | }
|
| |
|
| | void MeshPointGrid::AddPoint(const MeshPoint& rclPt, ElementIndex ulPtIndex, float fEpsilon)
|
| | {
|
| | (void)fEpsilon;
|
| | unsigned long ulX {};
|
| | unsigned long ulY {};
|
| | unsigned long ulZ {};
|
| | Pos(Base::Vector3f(rclPt.x, rclPt.y, rclPt.z), ulX, ulY, ulZ);
|
| | if ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ)) {
|
| | _aulGrid[ulX][ulY][ulZ].insert(ulPtIndex);
|
| | }
|
| | }
|
| |
|
| | void MeshPointGrid::Validate(const MeshKernel& rclMesh)
|
| | {
|
| | if (_pclMesh != &rclMesh) {
|
| | Attach(rclMesh);
|
| | }
|
| | else if (rclMesh.CountPoints() != _ulCtElements) {
|
| | RebuildGrid();
|
| | }
|
| | }
|
| |
|
| | void MeshPointGrid::Validate()
|
| | {
|
| | if (!_pclMesh) {
|
| | return;
|
| | }
|
| |
|
| | if (_pclMesh->CountPoints() != _ulCtElements) {
|
| | RebuildGrid();
|
| | }
|
| | }
|
| |
|
| | bool MeshPointGrid::Verify() const
|
| | {
|
| | if (!_pclMesh) {
|
| | return false;
|
| | }
|
| | if (_pclMesh->CountFacets() != _ulCtElements) {
|
| | return false;
|
| | }
|
| |
|
| | MeshGridIterator it(*this);
|
| | MeshPointIterator cP(*_pclMesh);
|
| | for (it.Init(); it.More(); it.Next()) {
|
| | std::vector<ElementIndex> aulElements;
|
| | it.GetElements(aulElements);
|
| | for (ElementIndex element : aulElements) {
|
| | cP.Set(element);
|
| | if (!it.GetBoundBox().IsInBox(*cP)) {
|
| | return false;
|
| | }
|
| | }
|
| | }
|
| |
|
| | return true;
|
| | }
|
| |
|
| | void MeshPointGrid::RebuildGrid()
|
| | {
|
| | _ulCtElements = _pclMesh->CountPoints();
|
| |
|
| | InitGrid();
|
| |
|
| |
|
| |
|
| | MeshPointIterator cPIter(*_pclMesh);
|
| |
|
| | unsigned long i = 0;
|
| | for (cPIter.Init(); cPIter.More(); cPIter.Next()) {
|
| | AddPoint(*cPIter, i++);
|
| | }
|
| | }
|
| |
|
| | void MeshPointGrid::Pos(
|
| | const Base::Vector3f& rclPoint,
|
| | unsigned long& rulX,
|
| | unsigned long& rulY,
|
| | unsigned long& rulZ
|
| | ) const
|
| | {
|
| | rulX = static_cast<unsigned long>((rclPoint.x - _fMinX) / _fGridLenX);
|
| | rulY = static_cast<unsigned long>((rclPoint.y - _fMinY) / _fGridLenY);
|
| | rulZ = static_cast<unsigned long>((rclPoint.z - _fMinZ) / _fGridLenZ);
|
| | }
|
| |
|
| | unsigned long MeshPointGrid::FindElements(
|
| | const Base::Vector3f& rclPoint,
|
| | std::set<ElementIndex>& aulElements
|
| | ) const
|
| | {
|
| | unsigned long ulX {};
|
| | unsigned long ulY {};
|
| | unsigned long ulZ {};
|
| | Pos(rclPoint, ulX, ulY, ulZ);
|
| |
|
| |
|
| | if ((ulX < _ulCtGridsX) && (ulY < _ulCtGridsY) && (ulZ < _ulCtGridsZ)) {
|
| | return GetElements(ulX, ulY, ulZ, aulElements);
|
| | }
|
| |
|
| | return 0;
|
| | }
|
| |
|
| |
|
| |
|
| | MeshGridIterator::MeshGridIterator(const MeshGrid& rclG)
|
| | : _rclGrid(rclG)
|
| | , _clPt(0.0F, 0.0F, 0.0F)
|
| | , _clDir(0.0F, 0.0F, 0.0F)
|
| | {}
|
| |
|
| | bool MeshGridIterator::InitOnRay(
|
| | const Base::Vector3f& rclPt,
|
| | const Base::Vector3f& rclDir,
|
| | float fMaxSearchArea,
|
| | std::vector<ElementIndex>& raulElements
|
| | )
|
| | {
|
| | bool ret = InitOnRay(rclPt, rclDir, raulElements);
|
| | _fMaxSearchArea = fMaxSearchArea;
|
| | return ret;
|
| | }
|
| |
|
| | bool MeshGridIterator::InitOnRay(
|
| | const Base::Vector3f& rclPt,
|
| | const Base::Vector3f& rclDir,
|
| | std::vector<ElementIndex>& raulElements
|
| | )
|
| | {
|
| |
|
| | _cSearchPositions.clear();
|
| |
|
| | _fMaxSearchArea = std::numeric_limits<float>::max();
|
| |
|
| | raulElements.clear();
|
| |
|
| | _clPt = rclPt;
|
| | _clDir = rclDir;
|
| | _bValidRay = false;
|
| |
|
| |
|
| | if (_rclGrid.GetBoundBox().IsInBox(rclPt)) {
|
| | _rclGrid.Position(rclPt, _ulX, _ulY, _ulZ);
|
| | raulElements.insert(
|
| | raulElements.end(),
|
| | _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(),
|
| | _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()
|
| | );
|
| | _bValidRay = true;
|
| | }
|
| | else {
|
| | Base::Vector3f cP0;
|
| | Base::Vector3f cP1;
|
| |
|
| | if (_rclGrid.GetBoundBox().IntersectWithLine(rclPt, rclDir, cP0, cP1)) {
|
| | if ((cP0 - rclPt).Length() < (cP1 - rclPt).Length()) {
|
| | _rclGrid.Position(cP0, _ulX, _ulY, _ulZ);
|
| | }
|
| | else {
|
| | _rclGrid.Position(cP1, _ulX, _ulY, _ulZ);
|
| | }
|
| |
|
| | raulElements.insert(
|
| | raulElements.end(),
|
| | _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(),
|
| | _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()
|
| | );
|
| | _bValidRay = true;
|
| | }
|
| | }
|
| |
|
| | return _bValidRay;
|
| | }
|
| |
|
| | bool MeshGridIterator::NextOnRay(std::vector<ElementIndex>& raulElements)
|
| | {
|
| | if (!_bValidRay) {
|
| | return false;
|
| | }
|
| |
|
| | raulElements.clear();
|
| |
|
| | Base::Vector3f clIntersectPoint;
|
| |
|
| |
|
| | Base::BoundBox3f::SIDE tSide
|
| | = _rclGrid.GetBoundBox(_ulX, _ulY, _ulZ).GetSideFromRay(_clPt, _clDir, clIntersectPoint);
|
| |
|
| |
|
| |
|
| | if ((_clPt - clIntersectPoint).Length() > _fMaxSearchArea) {
|
| | _bValidRay = false;
|
| | }
|
| | else {
|
| | switch (tSide) {
|
| | case Base::BoundBox3f::LEFT:
|
| | _ulX--;
|
| | break;
|
| | case Base::BoundBox3f::RIGHT:
|
| | _ulX++;
|
| | break;
|
| | case Base::BoundBox3f::BOTTOM:
|
| | _ulY--;
|
| | break;
|
| | case Base::BoundBox3f::TOP:
|
| | _ulY++;
|
| | break;
|
| | case Base::BoundBox3f::FRONT:
|
| | _ulZ--;
|
| | break;
|
| | case Base::BoundBox3f::BACK:
|
| | _ulZ++;
|
| | break;
|
| |
|
| | default:
|
| | case Base::BoundBox3f::INVALID:
|
| | _bValidRay = false;
|
| | break;
|
| | }
|
| |
|
| | GridElement pos(_ulX, _ulY, _ulZ);
|
| | if (_cSearchPositions.find(pos) != _cSearchPositions.end()) {
|
| | _bValidRay = false;
|
| | }
|
| | }
|
| |
|
| | if (_bValidRay && _rclGrid.CheckPos(_ulX, _ulY, _ulZ)) {
|
| | GridElement pos(_ulX, _ulY, _ulZ);
|
| | _cSearchPositions.insert(pos);
|
| | raulElements.insert(
|
| | raulElements.end(),
|
| | _rclGrid._aulGrid[_ulX][_ulY][_ulZ].begin(),
|
| | _rclGrid._aulGrid[_ulX][_ulY][_ulZ].end()
|
| | );
|
| | }
|
| | else {
|
| | _bValidRay = false;
|
| | }
|
| |
|
| | return _bValidRay;
|
| | }
|
| |
|