// SPDX-License-Identifier: LGPL-2.1-or-later /*************************************************************************** * Copyright (c) 2008 Juergen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef _CurveProjector_h_ #define _CurveProjector_h_ #include #include #include #include #include namespace MeshCore { class MeshKernel; class MeshGeomFacet; class MeshFacetGrid; } // namespace MeshCore using MeshCore::MeshGeomFacet; using MeshCore::MeshKernel; namespace MeshPart { /** The father of all projection algorithms */ class MeshPartExport CurveProjector { public: CurveProjector(const TopoDS_Shape& aShape, const MeshKernel& pMesh); virtual ~CurveProjector() = default; struct FaceSplitEdge { MeshCore::FacetIndex ulFaceIndex; Base::Vector3f p1, p2; }; template struct TopoDSLess { bool operator()(const T& x, const T& y) const { #if OCC_VERSION_HEX >= 0x070800 std::hash hasher; return hasher(x) < hasher(y); #else constexpr int max = std::numeric_limits::max(); return x.HashCode(max - 1) < y.HashCode(max - 1); #endif } }; using result_type = std::map, TopoDSLess>; result_type& result() { return mvEdgeSplitPoints; } void writeIntersectionPointsToFile(const char* name = "export_pts.asc"); protected: virtual void Do() = 0; const TopoDS_Shape& _Shape; const MeshKernel& _Mesh; result_type mvEdgeSplitPoints; }; /** Project by intersection face planes with the curve */ class MeshPartExport CurveProjectorShape: public CurveProjector { public: CurveProjectorShape(const TopoDS_Shape& aShape, const MeshKernel& pMesh); ~CurveProjectorShape() override = default; void projectCurve(const TopoDS_Edge& aEdge, std::vector& vSplitEdges); bool findStartPoint( const MeshKernel& MeshK, const Base::Vector3f& Pnt, Base::Vector3f& Rslt, MeshCore::FacetIndex& FaceIndex ); protected: void Do() override; }; /** Project by projecting a sampled curve to the mesh */ class MeshPartExport CurveProjectorSimple: public CurveProjector { public: CurveProjectorSimple(const TopoDS_Shape& aShape, const MeshKernel& pMesh); ~CurveProjectorSimple() override = default; /// helper to discredicice a Edge... void GetSampledCurves( const TopoDS_Edge& aEdge, std::vector& rclPoints, unsigned long ulNbOfPoints = 30 ); void projectCurve( const TopoDS_Edge& aEdge, const std::vector& rclPoints, std::vector& vSplitEdges ); bool findStartPoint( const MeshKernel& MeshK, const Base::Vector3f& Pnt, Base::Vector3f& Rslt, MeshCore::FacetIndex& FaceIndex ); protected: void Do() override; }; /** Project by projecting a sampled curve to the mesh */ class MeshPartExport CurveProjectorWithToolMesh: public CurveProjector { public: struct LineSeg { Base::Vector3f p; Base::Vector3f n; }; CurveProjectorWithToolMesh(const TopoDS_Shape& aShape, const MeshKernel& pMesh, MeshKernel& rToolMesh); ~CurveProjectorWithToolMesh() override = default; void makeToolMesh(const TopoDS_Edge& aEdge, std::vector& cVAry); MeshKernel& ToolMesh; protected: void Do() override; }; /** * The MeshProjection class projects a shape onto a mesh. * @author Werner Mayer */ class MeshPartExport MeshProjection { public: /// Helper class struct SplitEdge { MeshCore::PointIndex uE0, uE1; /**< start and endpoint of an edge */ Base::Vector3f cPt; /**< Point on edge (\a uE0, \a uE1) */ }; struct Edge { Base::Vector3f cPt1; Base::Vector3f cPt2; }; struct PolyLine { std::vector points; }; explicit MeshProjection(const MeshKernel& rMesh); /** * @brief findSectionParameters * Find the parameters of the edge where when projecting the corresponding point will lie * on an edge of the mesh. * @param edge * @param dir * @param parameters */ void findSectionParameters( const TopoDS_Edge& edge, const Base::Vector3f& dir, std::set& parameters ) const; void discretize( const TopoDS_Edge& aEdge, std::vector& polyline, std::size_t minPoints = 2 ) const; /** * Searches all edges that intersect with the projected curve \a aShape. Therefore \a aShape * must contain shapes of type TopoDS_Edge, other shape types are ignored. A possible solution * is 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. */ void projectParallelToMesh( const TopoDS_Shape& aShape, const Base::Vector3f& dir, std::vector& rPolyLines ) const; /** * Project all polylines onto the mesh using parallel projection. */ void projectParallelToMesh( const std::vector& aEdges, const Base::Vector3f& dir, std::vector& rPolyLines ) const; /** * Cuts the mesh at the curve defined by \a aShape. This method call @ref projectToMesh() to get * the split the facet at the found points. @see projectToMesh() for more details. */ void splitMeshByShape(const TopoDS_Shape& aShape, float fMaxDist) const; protected: void projectEdgeToEdge( const TopoDS_Edge& aCurve, float fMaxDist, const MeshCore::MeshFacetGrid& rGrid, std::vector& rSplitEdges ) const; bool findIntersection(const Edge&, const Edge&, const Base::Vector3f& dir, Base::Vector3f& res) const; private: const MeshKernel& _rcMesh; }; } // namespace MeshPart #endif