// Created on: 1998-07-14 // Created by: data exchange team // Copyright (c) 1998-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _ShapeConstruct_ProjectCurveOnSurface_HeaderFile #define _ShapeConstruct_ProjectCurveOnSurface_HeaderFile #include "Standard.hxx" #include "Standard_Type.hxx" #include "gp_Pnt.hxx" #include "gp_Pnt2d.hxx" #include "NCollection_Array1.hxx" #include "Precision.hxx" #include "ShapeExtend_Status.hxx" #include "Standard_Transient.hxx" #include class Geom2d_Curve; class Geom_Curve; class Geom_Surface; class ShapeAnalysis_Surface; // Resolve name collisions with X11 headers #ifdef Status #undef Status #endif //! This tool provides a method for computing pcurve by projecting //! 3d curve onto a surface. //! Projection is done by 23 or more points (this number is changed //! for B-Splines according to the following rule: //! the total number of the points is not less than number of spans * //! (degree + 1); //! it is increased recursively starting with 23 and is added with 22 //! until the condition is fulfilled). //! Isoparametric cases (if curve corresponds to U=const or V=const on //! the surface) are recognized with the given precision. class ShapeConstruct_ProjectCurveOnSurface : public Standard_Transient { public: // Type aliases for internal containers (1-based indexing for geometry arrays) using ArrayOfPnt = NCollection_Array1; using ArrayOfPnt2d = NCollection_Array1; using ArrayOfReal = NCollection_Array1; // Cache uses 0-based indexing (simple 2-element array) using CachePoint = std::pair; using CacheArray = NCollection_Array1; public: //! Empty constructor. Standard_EXPORT ShapeConstruct_ProjectCurveOnSurface(); //! Initializes the object with all necessary parameters, //! i.e. surface and precision //! @param[in] theSurf the surface to project on //! @param[in] thePreci the precision for projection Standard_EXPORT virtual void Init(const occ::handle& theSurf, const double thePreci); //! Initializes the object with all necessary parameters, //! i.e. surface and precision //! @param[in] theSurf the surface to project on (ShapeAnalysis_Surface) //! @param[in] thePreci the precision for projection Standard_EXPORT virtual void Init(const occ::handle& theSurf, const double thePreci); //! Loads a surface (in the form of Geom_Surface) to project on //! @param[in] theSurf the surface to project on Standard_EXPORT void SetSurface(const occ::handle& theSurf); //! Loads a surface (in the form of ShapeAnalysis_Surface) to project on //! @param[in] theSurf the surface to project on Standard_EXPORT void SetSurface(const occ::handle& theSurf); //! Sets value for current precision //! @param[in] thePreci the precision value Standard_EXPORT void SetPrecision(const double thePreci); //! Returns (modifiable) the flag specifying to which side of //! parametrical space adjust part of pcurve which lies on seam. //! This is required in very rare case when 3d curve which is //! to be projected goes partly along the seam on the closed //! surface with singularity (e.g. sphere), goes through the //! degenerated point and partly lies on internal area of surface. //! //! If this flag is True, the seam part of such curve will be //! adjusted to the left side of parametric space (on sphere U=0), //! else to the right side (on sphere U=2*PI) //! Default value is True //! @return modifiable reference to the adjustment flag Standard_EXPORT int& AdjustOverDegenMode(); //! Returns the status of last Perform //! @param[in] theStatus the status to query //! @return true if the specified status is set Standard_EXPORT bool Status(const ShapeExtend_Status theStatus) const; //! Computes the projection of 3d curve onto a surface using the //! specialized algorithm. Returns False if projector fails, //! otherwise, if pcurve computed successfully, returns True. //! The output curve 2D is guaranteed to be same-parameter //! with input curve 3D on the interval [theFirst, theLast]. If the output curve //! lies on a direct line the infinite line is returned, in the case //! same-parameter condition is satisfied. //! @param[in] theC3D the 3D curve to project //! @param[in] theFirst the first parameter of the curve //! @param[in] theLast the last parameter of the curve //! @param[out] theC2D the resulting 2D curve //! @param[in] theTolFirst the tolerance at the first point (default: Precision::Confusion()) //! @param[in] theTolLast the tolerance at the last point (default: Precision::Confusion()) //! @return true if projection succeeded Standard_EXPORT virtual bool Perform(const occ::handle& theC3D, const double theFirst, const double theLast, occ::handle& theC2D, const double theTolFirst = Precision::Confusion(), const double theTolLast = Precision::Confusion()); DEFINE_STANDARD_RTTIEXT(ShapeConstruct_ProjectCurveOnSurface, Standard_Transient) protected: //! Try to approximate 3D curve by Geom2d_Line //! or Geom2d_BSplineCurve with degree 1 with specified tolerance. //! @param[in] thePoints points obtained from 3d curve //! @param[in] theParams parameters corresponding points on 3d curve //! @param[out] thePoints2d 2d points lies on line in parametric space //! @param[in] theTol tolerance used for compare initial points 3d and //! 3d points obtained from line lying in parametric space of surface //! @param[out] theIsRecompute flag indicating if recomputation is needed //! @param[out] theIsFromCache flag indicating if result is from cache //! @return the resulting 2D curve or null if line fitting failed Standard_EXPORT occ::handle getLine(const ArrayOfPnt& thePoints, const ArrayOfReal& theParams, ArrayOfPnt2d& thePoints2d, const double theTol, bool& theIsRecompute, bool& theIsFromCache) const; //! Computes the projection of 3d curve onto a surface using the //! standard algorithm from ProjLib. Returns False if standard //! projector fails or raises an exception or cuts the curve by //! parametrical bounds of the surface. Else, if pcurve computed //! successfully, returns True. //! @param[in] theC3D the 3D curve to project //! @param[in] theFirst the first parameter of the curve //! @param[in] theLast the last parameter of the curve //! @param[out] theC2D the resulting 2D curve //! @return true if projection succeeded Standard_EXPORT bool PerformByProjLib(const occ::handle& theC3D, const double theFirst, const double theLast, occ::handle& theC2D); //! Performs analytical projection for special cases (plane surfaces) //! @param[in] theC3D the 3D curve to project //! @return the resulting 2D curve or null if analytical projection not applicable Standard_EXPORT occ::handle projectAnalytic( const occ::handle& theC3D) const; //! Main approximation routine for pcurve computation //! @param[in] theNbPnt number of points //! @param[in] theC3D the 3D curve //! @param[in] theTolFirst tolerance at first point //! @param[in] theTolLast tolerance at last point //! @param[in,out] thePoints array of 3D points //! @param[in,out] theParams array of parameters //! @param[out] thePoints2d array of 2D points //! @param[out] theC2D resulting 2D curve //! @return true if approximation succeeded Standard_EXPORT bool approxPCurve(const int theNbPnt, const occ::handle& theC3D, const double theTolFirst, const double theTolLast, ArrayOfPnt& thePoints, ArrayOfReal& theParams, ArrayOfPnt2d& thePoints2d, occ::handle& theC2D); //! Corrects extremity point near singularity //! @param[in] theC3D the 3D curve //! @param[in] theParams array of parameters //! @param[in,out] thePoints2d array of 2D points //! @param[in] theIsFirstPoint true if correcting first point, false for last //! @param[in] thePointOnIsoLine point on isoline //! @param[in] theIsUIso true if U-isoline, false if V-isoline Standard_EXPORT void correctExtremity(const occ::handle& theC3D, const ArrayOfReal& theParams, ArrayOfPnt2d& thePoints2d, const bool theIsFirstPoint, const gp_Pnt2d& thePointOnIsoLine, const bool theIsUIso); //! Inserts additional point or adjusts coordinate to handle period jumps //! @param[in,out] theToAdjust flag indicating if adjustment should be done //! @param[in] theIndCoord coordinate index (1=U, 2=V) //! @param[in] thePeriod the period value //! @param[in] theTolOnPeriod tolerance on period //! @param[in,out] theCurCoord current coordinate value //! @param[in] thePrevCoord previous coordinate value //! @param[in] theC3D the 3D curve //! @param[in,out] theIndex current point index //! @param[in,out] thePoints array of 3D points //! @param[in,out] theParams array of parameters //! @param[in,out] thePoints2d array of 2D points Standard_EXPORT void insertAdditionalPointOrAdjust(bool& theToAdjust, const int theIndCoord, const double thePeriod, const double theTolOnPeriod, double& theCurCoord, const double thePrevCoord, const occ::handle& theC3D, int& theIndex, ArrayOfPnt& thePoints, ArrayOfReal& theParams, ArrayOfPnt2d& thePoints2d); //! Interpolates 2D curve from points //! @param[in] theNbPnt number of points //! @param[in] thePoints2d array of 2D points //! @param[in] theParams array of parameters //! @return the interpolated 2D curve or null on failure Standard_EXPORT occ::handle interpolatePCurve(const int theNbPnt, const ArrayOfPnt2d& thePoints2d, const ArrayOfReal& theParams) const; //! Approximates 2D curve from points //! @param[in] thePoints2d array of 2D points //! @param[in] theParams array of parameters //! @return the approximated 2D curve or null on failure Standard_EXPORT occ::handle approximatePCurve(const ArrayOfPnt2d& thePoints2d, const ArrayOfReal& theParams) const; //! Checks and removes coincident 3D points //! @param[in,out] thePoints array of 3D points //! @param[in,out] theParams array of parameters //! @param[in,out] thePreci precision (may be adjusted) Standard_EXPORT void checkPoints(ArrayOfPnt& thePoints, ArrayOfReal& theParams, double& thePreci) const; //! Checks and removes coincident 2D points //! @param[in,out] thePoints2d array of 2D points //! @param[in,out] theParams array of parameters //! @param[in,out] thePreci precision (may be adjusted) Standard_EXPORT void checkPoints2d(ArrayOfPnt2d& thePoints2d, ArrayOfReal& theParams, double& thePreci) const; //! Detects if curve is isoparametric (U=const or V=const) //! @param[in] theNbPnt number of points //! @param[in] thePoints array of 3D points //! @param[in] theParams array of parameters //! @param[out] theIsTypeU true if U-iso, false if V-iso //! @param[out] theP1OnIso true if first point is on iso //! @param[out] theValueP1 2D value of first point on iso //! @param[out] theP2OnIso true if last point is on iso //! @param[out] theValueP2 2D value of last point on iso //! @param[out] theIsoPar2d3d true if parametrization matches //! @param[out] theCIso the isoline curve //! @param[out] theT1 first iso parameter //! @param[out] theT2 last iso parameter //! @param[out] theParamsOut output parameters on isoline //! @return true if curve is isoparametric Standard_EXPORT bool isAnIsoparametric(const int theNbPnt, const ArrayOfPnt& thePoints, const ArrayOfReal& theParams, bool& theIsTypeU, bool& theP1OnIso, gp_Pnt2d& theValueP1, bool& theP2OnIso, gp_Pnt2d& theValueP2, bool& theIsoPar2d3d, occ::handle& theCIso, double& theT1, double& theT2, ArrayOfReal& theParamsOut) const; private: occ::handle mySurf; //!< Surface to project on double myPreci; //!< Current precision int myStatus; //!< Operation status int myAdjustOverDegen; //!< Seam adjustment flag CacheArray myCache; //!< Cached 3D/2D point pairs for projection optimization }; #endif // _ShapeConstruct_ProjectCurveOnSurface_HeaderFile