bool MeshProjection::bboxInsideRectangle(const Base::BoundBox3f& bbox, const Base::Vector3f& p1, const Base::Vector3f& p2, const Base::Vector3f& view) const { Base::Vector3f dir(p2 - p1); Base::Vector3f base(p1), normal(view % dir); normal.Normalize(); if (bbox.IsCutPlane(base, normal)) { dir.Normalize(); Base::Vector3f cnt(bbox.CalcCenter()); return (fabs(cnt.DistanceToPlane(p1, dir)) + fabs(cnt.DistanceToPlane(p2, dir))) <= (bbox.CalcDiagonalLength() + (p2 - p1).Length()); } return false; }
PyObject* MeshPy::nearestFacetOnRay(PyObject *args) { PyObject* pnt_p; PyObject* dir_p; if (!PyArg_ParseTuple(args, "OO", &pnt_p, &dir_p)) return NULL; try { Py::Tuple pnt_t(pnt_p); Py::Tuple dir_t(dir_p); Py::Dict dict; Base::Vector3f pnt((float)Py::Float(pnt_t.getItem(0)), (float)Py::Float(pnt_t.getItem(1)), (float)Py::Float(pnt_t.getItem(2))); Base::Vector3f dir((float)Py::Float(dir_t.getItem(0)), (float)Py::Float(dir_t.getItem(1)), (float)Py::Float(dir_t.getItem(2))); unsigned long index = 0; Base::Vector3f res; MeshCore::MeshAlgorithm alg(getMeshObjectPtr()->getKernel()); #if 0 // for testing only MeshCore::MeshFacetGrid grid(getMeshObjectPtr()->getKernel(),10); // With grids we might search in the opposite direction, too if (alg.NearestFacetOnRay(pnt, dir, grid, res, index) || alg.NearestFacetOnRay(pnt, -dir, grid, res, index)) { #else if (alg.NearestFacetOnRay(pnt, dir, res, index)) { #endif Py::Tuple tuple(3); tuple.setItem(0, Py::Float(res.x)); tuple.setItem(1, Py::Float(res.y)); tuple.setItem(2, Py::Float(res.z)); dict.setItem(Py::Int((int)index), tuple); } #if 0 // for testing only char szBuf[200]; std::ofstream str("grid_test.iv"); Base::InventorBuilder builder(str); MeshCore::MeshGridIterator g_it(grid); for (g_it.Init(); g_it.More(); g_it.Next()) { Base::BoundBox3f box = g_it.GetBoundBox(); unsigned long uX,uY,uZ; g_it.GetGridPos(uX,uY,uZ); builder.addBoundingBox(Base::Vector3f(box.MinX,box.MinY, box.MinZ), Base::Vector3f(box.MaxX,box.MaxY, box.MaxZ)); sprintf(szBuf, "(%lu,%lu,%lu)", uX, uY, uZ); builder.addText(box.CalcCenter(), szBuf); } builder.addSingleArrow(pnt-20.0f*dir, pnt+10.0f*dir); builder.close(); str.close(); #endif return Py::new_reference_to(dict); } catch (const Py::Exception&) { return 0; } }
unsigned long MeshFacetGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt) const { unsigned long ulFacetInd = ULONG_MAX; float fMinDist = FLOAT_MAX; Base::BoundBox3f clBB = GetBoundBox(); if (clBB.IsInBox(rclPt) == true) { // Punkt liegt innerhalb unsigned long ulX, ulY, 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 { // Punkt ausserhalb Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.CalcCenter() - rclPt); switch (tSide) { case Base::BoundBox3f::RIGHT: { int nX = 0; while ((fMinDist > ((clBB.MinX - rclPt.x) + ((float)(nX) * _fGridLenX))) && ((unsigned long)(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: { int nX = _ulCtGridsX - 1; while ((fMinDist > ((rclPt.x - clBB.MinX) + (float(nX) * _fGridLenX))) && (nX >= 0)) { 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: { int nY = 0; while ((fMinDist > ((clBB.MinY - rclPt.y) + ((float)(nY) * _fGridLenY))) && ((unsigned long)(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: { int nY = _ulCtGridsY - 1; while ((fMinDist > ((rclPt.y - clBB.MinY) + (float(nY) * _fGridLenY))) && (nY >= 0)) { 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: { int nZ = 0; while ((fMinDist > ((clBB.MinZ - rclPt.z) + ((float)(nZ) * _fGridLenZ))) && ((unsigned long)(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: { int nZ = _ulCtGridsZ - 1; while ((fMinDist > ((rclPt.z - clBB.MinZ) + ((float)(nZ) * _fGridLenZ))) && (nZ >= 0)) { 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; }
void MeshGrid::SearchNearestFromPoint (const Base::Vector3f &rclPt, std::set<unsigned long> &raclInd) const { raclInd.clear(); Base::BoundBox3f clBB = GetBoundBox(); if (clBB.IsInBox(rclPt) == true) { // Punkt liegt innerhalb unsigned long ulX, ulY, ulZ; Position(rclPt, ulX, ulY, ulZ); //int nX = ulX, nY = ulY, nZ = ulZ; unsigned long ulLevel = 0; while (raclInd.size() == 0) GetHull(ulX, ulY, ulZ, ulLevel++, raclInd); GetHull(ulX, ulY, ulZ, ulLevel, raclInd); } else { // Punkt ausserhalb Base::BoundBox3f::SIDE tSide = clBB.GetSideFromRay(rclPt, clBB.CalcCenter() - rclPt); switch (tSide) { case Base::BoundBox3f::RIGHT: { int nX = 0; while (raclInd.size() == 0) { for (unsigned long i = 0; i < _ulCtGridsY; i++) { for (unsigned long j = 0; j < _ulCtGridsZ; j++) raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end()); } nX++; } break; } case Base::BoundBox3f::LEFT: { int nX = _ulCtGridsX - 1; while (raclInd.size() == 0) { for (unsigned long i = 0; i < _ulCtGridsY; i++) { for (unsigned long j = 0; j < _ulCtGridsZ; j++) raclInd.insert(_aulGrid[nX][i][j].begin(), _aulGrid[nX][i][j].end()); } nX++; } break; } case Base::BoundBox3f::TOP: { int nY = 0; while (raclInd.size() == 0) { for (unsigned long i = 0; i < _ulCtGridsX; i++) { for (unsigned long j = 0; j < _ulCtGridsZ; j++) raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end()); } nY++; } break; } case Base::BoundBox3f::BOTTOM: { int nY = _ulCtGridsY - 1; while (raclInd.size() == 0) { for (unsigned long i = 0; i < _ulCtGridsX; i++) { for (unsigned long j = 0; j < _ulCtGridsZ; j++) raclInd.insert(_aulGrid[i][nY][j].begin(), _aulGrid[i][nY][j].end()); } nY--; } break; } case Base::BoundBox3f::BACK: { int nZ = 0; while (raclInd.size() == 0) { for (unsigned long i = 0; i < _ulCtGridsX; i++) { for (unsigned long j = 0; j < _ulCtGridsY; j++) raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end()); } nZ++; } break; } case Base::BoundBox3f::FRONT: { int nZ = _ulCtGridsZ - 1; while (raclInd.size() == 0) { for (unsigned long i = 0; i < _ulCtGridsX; i++) { for (unsigned long j = 0; j < _ulCtGridsY; j++) raclInd.insert(_aulGrid[i][j][nZ].begin(), _aulGrid[i][j][nZ].end()); } nZ--; } break; } default: break; } } }