From c1d9087d090107c6762e703ada2e7ce6f423887f Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 26 Jun 2019 16:57:14 +0200 Subject: [PATCH] add method to project points on mesh --- src/Mod/MeshPart/App/AppMeshPartPy.cpp | 46 +++++++++++++++++++++++++ src/Mod/MeshPart/App/CurveProjector.cpp | 30 ++++++++++++++++ src/Mod/MeshPart/App/CurveProjector.h | 12 +++++++ 3 files changed, 88 insertions(+) diff --git a/src/Mod/MeshPart/App/AppMeshPartPy.cpp b/src/Mod/MeshPart/App/AppMeshPartPy.cpp index 70cb47eaf424..47d8ed757975 100644 --- a/src/Mod/MeshPart/App/AppMeshPartPy.cpp +++ b/src/Mod/MeshPart/App/AppMeshPartPy.cpp @@ -79,6 +79,11 @@ class Module : public Py::ExtensionModule "projectShapeOnMesh(Shape, Mesh, Vector) -> list of polygons\n" "projectShapeOnMesh(list of polygons, Mesh, Vector) -> list of polygons\n" ); + add_varargs_method("projectPointsOnMesh",&Module::projectPointsOnMesh, + "Projects points onto a mesh with a given direction\n" + "and tolerance." + "projectPointsOnMesh(list of points, Mesh, Vector, [float]) -> list of points\n" + ); add_varargs_method("wireFromSegment",&Module::wireFromSegment, "Create wire(s) from boundary of segment\n" ); @@ -361,6 +366,47 @@ class Module : public Py::ExtensionModule "Shape, Mesh, Vector or\n" "Polygons, Mesh, Vector\n"); } + Py::Object projectPointsOnMesh(const Py::Tuple& args) + { + PyObject *seq, *m, *v; + double precision = -1; + if (PyArg_ParseTuple(args.ptr(), "OO!O!|d", + &seq, + &Mesh::MeshPy::Type, &m, + &Base::VectorPy::Type, &v, + &precision)) { + std::vector pointsIn; + Py::Sequence points(seq); + pointsIn.reserve(points.size()); + + // collect list of input points + for (Py::Sequence::iterator it = points.begin(); it != points.end(); ++it) { + Py::Vector pnt(*it); + pointsIn.push_back(Base::convertTo(pnt.toVector())); + } + + const Mesh::MeshObject* mesh = static_cast(m)->getMeshObjectPtr(); + Base::Vector3d* vec = static_cast(v)->getVectorPtr(); + Base::Vector3f dir = Base::convertTo(*vec); + + MeshCore::MeshKernel kernel(mesh->getKernel()); + kernel.Transform(mesh->getTransform()); + + MeshProjection proj(kernel); + std::vector pointsOut; + proj.projectOnMesh(pointsIn, dir, static_cast(precision), pointsOut); + + Py::List list; + for (auto it : pointsOut) { + Py::Vector v(it); + list.append(v); + } + + return list; + } + + throw Py::Exception(); + } Py::Object wireFromSegment(const Py::Tuple& args) { PyObject *o, *m; diff --git a/src/Mod/MeshPart/App/CurveProjector.cpp b/src/Mod/MeshPart/App/CurveProjector.cpp index 9059d08c9aa1..354868aa5f89 100644 --- a/src/Mod/MeshPart/App/CurveProjector.cpp +++ b/src/Mod/MeshPart/App/CurveProjector.cpp @@ -844,6 +844,36 @@ void MeshProjection::projectToMesh (const TopoDS_Shape &aShape, float fMaxDist, } } +void MeshProjection::projectOnMesh(const std::vector& pointsIn, + const Base::Vector3f& dir, + float tolerance, + std::vector& pointsOut) const +{ + // calculate the average edge length and create a grid + MeshAlgorithm clAlg(_rcMesh); + float fAvgLen = clAlg.GetAverageEdgeLength(); + MeshFacetGrid cGrid(_rcMesh, 5.0f*fAvgLen); + + Base::SequencerLauncher seq( "Project points on mesh", pointsIn.size() ); + + for (auto it : pointsIn) { + Base::Vector3f result; + unsigned long index; + if (clAlg.NearestFacetOnRay(it, dir, cGrid, result, index)) { + MeshCore::MeshGeomFacet geomFacet = _rcMesh.GetFacet(index); + if (tolerance > 0 && geomFacet.IntersectPlaneWithLine(it, dir, result)) { + if (geomFacet.IsPointOfFace(result, tolerance)) + pointsOut.push_back(result); + } + else { + pointsOut.push_back(result); + } + } + + seq.next(); + } +} + void MeshProjection::projectParallelToMesh (const TopoDS_Shape &aShape, const Base::Vector3f& dir, std::vector& rPolyLines) const { // calculate the average edge length and create a grid diff --git a/src/Mod/MeshPart/App/CurveProjector.h b/src/Mod/MeshPart/App/CurveProjector.h index e824ec04e602..6e0a73df98c3 100644 --- a/src/Mod/MeshPart/App/CurveProjector.h +++ b/src/Mod/MeshPart/App/CurveProjector.h @@ -196,6 +196,18 @@ class MeshPartExport MeshProjection * taken if the distance between the curve point and the projected point is <= \a fMaxDist. */ void projectToMesh (const TopoDS_Shape &aShape, float fMaxDist, std::vector& rPolyLines) const; + /** + * @brief projectOnMesh + * Projects the given points onto the mesh along a given direction. The points can can be projected + * will be saved to \a pointsOut + * @brief projectOnMesh + * @param pointsIn + * @param dir + * @param tolerance + * @param pointsOut + */ + void projectOnMesh(const std::vector& pointsIn, const Base::Vector3f& dir, + float tolerance, std::vector& pointsOut) const; /** * Project all edges of the shape onto the mesh using parallel projection. */