Mesh: consider placement in MeshPy::nearestFacetOnRay
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -94,6 +94,8 @@ public:
|
||||
// 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);
|
||||
@@ -152,6 +154,7 @@ public:
|
||||
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);
|
||||
|
||||
@@ -1833,54 +1833,21 @@ 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);
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
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&) {
|
||||
|
||||
@@ -200,6 +200,18 @@ class MeshSplitTestCases(unittest.TestCase):
|
||||
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:
|
||||
|
||||
Reference in New Issue
Block a user