From 828c64a4c93f7140cc34133cac7cf8fddd1ec01c Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 4 Aug 2022 20:47:33 +0200 Subject: [PATCH] Mesh: consider placement in MeshPy::nearestFacetOnRay --- src/Mod/Mesh/App/Mesh.cpp | 26 ++++++++++++++++ src/Mod/Mesh/App/Mesh.h | 3 ++ src/Mod/Mesh/App/MeshPyImp.cpp | 53 ++++++-------------------------- src/Mod/Mesh/App/MeshTestsApp.py | 12 ++++++++ 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index 3ae87ca40cdc..49c8aa682954 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -815,6 +815,32 @@ std::vector MeshObject::getPointsFromFacets(const std::vector(ray.first); + Base::Vector3f dir = Base::toVector(ray.second); + + Base::Placement plm = getPlacement(); + Base::Placement inv = plm.inverse(); + + // transform the ray relative to the mesh kernel + inv.multVec(pnt, pnt); + inv.getRotation().multVec(dir, dir); + + FacetIndex index = 0; + Base::Vector3f res; + MeshCore::MeshAlgorithm alg(getKernel()); + + if (alg.NearestFacetOnRay(pnt, dir, static_cast(maxAngle), res, index)) { + plm.multVec(res, res); + output.first = index; + output.second = Base::toVector(res); + return true; + } + + return false; +} + void MeshObject::updateMesh(const std::vector& facets) const { std::vector points; diff --git a/src/Mod/Mesh/App/Mesh.h b/src/Mod/Mesh/App/Mesh.h index 79ed1f030b68..87f8ada1d923 100644 --- a/src/Mod/Mesh/App/Mesh.h +++ b/src/Mod/Mesh/App/Mesh.h @@ -94,6 +94,8 @@ class MeshExport MeshObject : public Data::ComplexGeoData // typedef needed for cross-section using TPlane = std::pair; using TPolylines = std::list>; + using TRay = std::pair; + using TFaceSection = std::pair; MeshObject(); explicit MeshObject(const MeshCore::MeshKernel& Kernel); @@ -152,6 +154,7 @@ class MeshExport MeshObject : public Data::ComplexGeoData virtual void getFaces(std::vector &Points,std::vector &Topo, float Accuracy, uint16_t flags=0) const; std::vector getPointsFromFacets(const std::vector& facets) const; + bool nearestFacetOnRay(const TRay& ray, double maxAngle, TFaceSection& output) const; //@} void setKernel(const MeshCore::MeshKernel& m); diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index 35f0982247fd..7f5503fd13bc 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -1833,53 +1833,20 @@ PyObject* MeshPy::nearestFacetOnRay(PyObject *args) return nullptr; try { - Py::Tuple pnt_t(pnt_p); - Py::Tuple dir_t(dir_p); + Py::Vector pnt_t(pnt_p, false); + Py::Vector dir_t(dir_p, false); 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))); - FacetIndex 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, static_cast(maxAngle), res, index)) { -#endif + MeshObject::TRay ray = std::make_pair(pnt_t.toVector(), + dir_t.toVector()); + MeshObject::TFaceSection output; + if (getMeshObjectPtr()->nearestFacetOnRay(ray, maxAngle, output)) { 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::Long((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.GetCenter(), szBuf); + tuple.setItem(0, Py::Float(output.second.x)); + tuple.setItem(1, Py::Float(output.second.y)); + tuple.setItem(2, Py::Float(output.second.z)); + dict.setItem(Py::Long(static_cast(output.first)), tuple); } - builder.addSingleArrow(pnt-20.0f*dir, pnt+10.0f*dir); - builder.close(); - str.close(); -#endif return Py::new_reference_to(dict); } diff --git a/src/Mod/Mesh/App/MeshTestsApp.py b/src/Mod/Mesh/App/MeshTestsApp.py index c3ca04a10760..1775f587ef13 100644 --- a/src/Mod/Mesh/App/MeshTestsApp.py +++ b/src/Mod/Mesh/App/MeshTestsApp.py @@ -200,6 +200,18 @@ def testFindNearest(self): len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0,-1)))) self.assertEqual(len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0, 1), math.pi/2)), len(self.mesh.nearestFacetOnRay((0.2,0.1,0.2),(0,0,-1), math.pi/2))) + # Apply placement to mesh + plm = Base.Placement(Base.Vector(1,2,3), Base.Rotation(1,1,1,1)) + pnt = Base.Vector(0.5, 0.5, 0.5) + vec = Base.Vector(0.0, 0.0, 1.0) + + self.mesh.Placement = plm + self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt,vec)), 0) + + # Apply the placement on the ray as well + pnt = plm.multVec(pnt) + vec = plm.Rotation.multVec(vec) + self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt,vec)), 1) def testForaminate(self): class FilterAngle: