Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:19:57

0001 // Copyright (c) 2025 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _ExtremaPC_BSplineCurve_HeaderFile
0015 #define _ExtremaPC_BSplineCurve_HeaderFile
0016 
0017 #include <ExtremaPC.hxx>
0018 #include <ExtremaPC_GridEvaluator.hxx>
0019 #include <GeomAdaptor_Curve.hxx>
0020 #include <Geom_BSplineCurve.hxx>
0021 #include <gp_Pnt.hxx>
0022 #include <NCollection_Array1.hxx>
0023 #include <Standard_DefineAlloc.hxx>
0024 #include <Standard_Handle.hxx>
0025 #include <math_Vector.hxx>
0026 
0027 //! @brief Point-BSplineCurve extrema computation using grid-based approach.
0028 //!
0029 //! Computes the extrema between a 3D point and a BSpline curve using
0030 //! a grid-based approach with Newton refinement.
0031 //!
0032 //! The grid is cached for efficiency when performing multiple queries
0033 //! with the same parameter domain.
0034 //!
0035 //! The algorithm:
0036 //! 1. Build knot-aware grid with 2*(degree + 1) samples per knot span using GeomGridEval
0037 //! 2. Linear scan of grid to find candidate intervals (sign changes in F(u))
0038 //! 3. Newton refinement on each candidate interval
0039 //!
0040 //! This approach is simpler and more stable than BVH-based methods,
0041 //! with comparable accuracy for typical BSpline curves.
0042 //!
0043 //! The domain is fixed at construction time and the grid is built eagerly
0044 //! for optimal performance with multiple queries.
0045 class ExtremaPC_BSplineCurve
0046 {
0047 public:
0048   DEFINE_STANDARD_ALLOC
0049 
0050   //! Constructor with BSpline curve (uses full curve domain).
0051   //! Grid is built eagerly at construction time.
0052   //! @param[in] theCurve BSpline curve handle
0053   Standard_EXPORT explicit ExtremaPC_BSplineCurve(const occ::handle<Geom_BSplineCurve>& theCurve);
0054 
0055   //! Constructor with BSpline curve and parameter domain.
0056   //! Grid is built eagerly at construction time for the specified domain.
0057   //! @param[in] theCurve BSpline curve handle
0058   //! @param[in] theDomain parameter domain (fixed for all queries)
0059   Standard_EXPORT ExtremaPC_BSplineCurve(const occ::handle<Geom_BSplineCurve>& theCurve,
0060                                          const ExtremaPC::Domain1D&            theDomain);
0061 
0062   //! Copy constructor is deleted.
0063   ExtremaPC_BSplineCurve(const ExtremaPC_BSplineCurve&) = delete;
0064 
0065   //! Copy assignment operator is deleted.
0066   ExtremaPC_BSplineCurve& operator=(const ExtremaPC_BSplineCurve&) = delete;
0067 
0068   //! Move constructor.
0069   ExtremaPC_BSplineCurve(ExtremaPC_BSplineCurve&&) = default;
0070 
0071   //! Move assignment operator.
0072   ExtremaPC_BSplineCurve& operator=(ExtremaPC_BSplineCurve&&) = default;
0073 
0074   //! Evaluates point on curve at parameter.
0075   //! @param theU parameter
0076   //! @return point on curve
0077   Standard_EXPORT gp_Pnt Value(double theU) const;
0078 
0079   //! Returns true if domain is bounded (subset of curve domain).
0080   bool IsBounded() const { return true; } // BSpline curves are always bounded
0081 
0082   //! Returns the domain.
0083   const ExtremaPC::Domain1D& Domain() const { return myDomain; }
0084 
0085   //! Compute extrema between point P and the curve.
0086   //! Uses domain specified at construction time.
0087   //! @param theP query point
0088   //! @param theTol tolerance for root finding
0089   //! @param theMode search mode (MinMax, Min, or Max)
0090   //! @return const reference to result containing extrema
0091   [[nodiscard]] Standard_EXPORT const ExtremaPC::Result& Perform(
0092     const gp_Pnt&         theP,
0093     double                theTol,
0094     ExtremaPC::SearchMode theMode = ExtremaPC::SearchMode::MinMax) const;
0095 
0096   //! Compute extrema between point P and the curve including endpoints.
0097   //! Uses domain specified at construction time.
0098   //! @param theP query point
0099   //! @param theTol tolerance for root finding
0100   //! @param theMode search mode (MinMax, Min, or Max)
0101   //! @return const reference to result containing interior + endpoint extrema
0102   [[nodiscard]] Standard_EXPORT const ExtremaPC::Result& PerformWithEndpoints(
0103     const gp_Pnt&         theP,
0104     double                theTol,
0105     ExtremaPC::SearchMode theMode = ExtremaPC::SearchMode::MinMax) const;
0106 
0107   //! Returns the BSpline curve.
0108   const occ::handle<Geom_BSplineCurve>& Curve() const { return myCurve; }
0109 
0110 private:
0111   //! Build knot-aware parameter array for grid sampling.
0112   //! Places samples at knots and (degree + 1) intermediate points per span.
0113   //! @return array of parameter values for grid sampling
0114   math_Vector buildKnotAwareParams() const;
0115 
0116   //! Build grid for the curve.
0117   void buildGrid();
0118 
0119   occ::handle<Geom_BSplineCurve> myCurve;   //!< BSpline curve
0120   GeomAdaptor_Curve              myAdaptor; //!< Curve adaptor
0121   ExtremaPC::Domain1D            myDomain;  //!< Parameter domain (fixed)
0122 
0123   // Grid evaluator with cached state (grid, result, temporary vectors)
0124   mutable ExtremaPC_GridEvaluator myEvaluator;
0125 };
0126 
0127 #endif // _ExtremaPC_BSplineCurve_HeaderFile