Skip to content

Commit

Permalink
Mesh: consider placement in MeshPy::nearestFacetOnRay
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Aug 4, 2022
1 parent 14451f7 commit 828c64a
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 43 deletions.
26 changes: 26 additions & 0 deletions src/Mod/Mesh/App/Mesh.cpp
Expand Up @@ -815,6 +815,32 @@ std::vector<PointIndex> MeshObject::getPointsFromFacets(const std::vector<FacetI
return _kernel.GetFacetPoints(facets);
}

bool MeshObject::nearestFacetOnRay(const MeshObject::TRay& ray, double maxAngle, MeshObject::TFaceSection& output) const
{
Base::Vector3f pnt = Base::toVector<float>(ray.first);
Base::Vector3f dir = Base::toVector<float>(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<float>(maxAngle), res, index)) {
plm.multVec(res, res);
output.first = index;
output.second = Base::toVector<double>(res);
return true;
}

return false;
}

void MeshObject::updateMesh(const std::vector<FacetIndex>& facets) const
{
std::vector<PointIndex> points;
Expand Down
3 changes: 3 additions & 0 deletions src/Mod/Mesh/App/Mesh.h
Expand Up @@ -94,6 +94,8 @@ class MeshExport MeshObject : public Data::ComplexGeoData
// typedef needed for cross-section
using TPlane = std::pair<Base::Vector3f, Base::Vector3f>;
using TPolylines = std::list<std::vector<Base::Vector3f>>;
using TRay = std::pair<Base::Vector3d, Base::Vector3d>;
using TFaceSection = std::pair<FacetIndex, Base::Vector3d>;

MeshObject();
explicit MeshObject(const MeshCore::MeshKernel& Kernel);
Expand Down Expand Up @@ -152,6 +154,7 @@ class MeshExport MeshObject : public Data::ComplexGeoData
virtual void getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &Topo,
float Accuracy, uint16_t flags=0) const;
std::vector<PointIndex> getPointsFromFacets(const std::vector<FacetIndex>& facets) const;
bool nearestFacetOnRay(const TRay& ray, double maxAngle, TFaceSection& output) const;
//@}

void setKernel(const MeshCore::MeshKernel& m);
Expand Down
53 changes: 10 additions & 43 deletions src/Mod/Mesh/App/MeshPyImp.cpp
Expand Up @@ -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<float>(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<int>(output.first)), tuple);
}
builder.addSingleArrow(pnt-20.0f*dir, pnt+10.0f*dir);
builder.close();
str.close();
#endif

return Py::new_reference_to(dict);
}
Expand Down
12 changes: 12 additions & 0 deletions src/Mod/Mesh/App/MeshTestsApp.py
Expand Up @@ -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:
Expand Down

0 comments on commit 828c64a

Please sign in to comment.