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_Curve_HeaderFile
0015 #define _ExtremaPC_Curve_HeaderFile
0016 
0017 #include <ExtremaPC.hxx>
0018 #include <ExtremaPC_BezierCurve.hxx>
0019 #include <ExtremaPC_BSplineCurve.hxx>
0020 #include <ExtremaPC_Circle.hxx>
0021 #include <ExtremaPC_Ellipse.hxx>
0022 #include <ExtremaPC_Hyperbola.hxx>
0023 #include <ExtremaPC_Line.hxx>
0024 #include <ExtremaPC_OffsetCurve.hxx>
0025 #include <ExtremaPC_OtherCurve.hxx>
0026 #include <ExtremaPC_Parabola.hxx>
0027 #include <Geom_Curve.hxx>
0028 #include <GeomAdaptor_Curve.hxx>
0029 #include <GeomAdaptor_TransformedCurve.hxx>
0030 #include <gp_Pnt.hxx>
0031 #include <gp_Trsf.hxx>
0032 #include <Standard_DefineAlloc.hxx>
0033 
0034 #include <variant>
0035 
0036 //! @brief Main aggregator for Point-Curve extrema computation.
0037 //!
0038 //! Provides a unified interface for computing extrema between a 3D point
0039 //! and any type of curve. Uses std::variant with std::visit for efficient
0040 //! curve type dispatch at runtime.
0041 //!
0042 //! Supports all elementary curve types (analytical solutions):
0043 //! - Line, Circle, Ellipse, Hyperbola, Parabola
0044 //!
0045 //! And numerical curves (grid-based with Newton refinement):
0046 //! - BSpline, Bezier, Offset, and general curves
0047 //!
0048 //! @note The parameter domain is fixed at construction time for optimal performance.
0049 //!       The inner curve evaluators build their grids eagerly in the constructor,
0050 //!       so multiple Perform() calls reuse the pre-built data without rebuilding.
0051 //!
0052 //! Usage example:
0053 //! @code
0054 //! ExtremaPC_Curve anExtPC(myAdaptorCurve);
0055 //! const ExtremaPC::Result& aResult = anExtPC.Perform(myPoint, 1.0e-9);
0056 //! if (aResult.IsDone())
0057 //! {
0058 //!   for (int i = 0; i < aResult.NbExt(); ++i)
0059 //!   {
0060 //!     double aDist = std::sqrt(aResult[i].SquareDistance);
0061 //!     gp_Pnt aPtOnCurve = aResult[i].Point;
0062 //!   }
0063 //! }
0064 //! @endcode
0065 class ExtremaPC_Curve
0066 {
0067 public:
0068   DEFINE_STANDARD_ALLOC
0069 
0070   //! Variant type holding all specialized evaluators.
0071   using EvaluatorVariant = std::variant<std::monostate,
0072                                         ExtremaPC_Line,
0073                                         ExtremaPC_Circle,
0074                                         ExtremaPC_Ellipse,
0075                                         ExtremaPC_Hyperbola,
0076                                         ExtremaPC_Parabola,
0077                                         ExtremaPC_BezierCurve,
0078                                         ExtremaPC_BSplineCurve,
0079                                         ExtremaPC_OffsetCurve,
0080                                         ExtremaPC_OtherCurve>;
0081 
0082   //! Constructor with curve adaptor.
0083   //! Uses the curve's natural parameter bounds as domain.
0084   //! @param[in] theCurve curve adaptor
0085   Standard_EXPORT explicit ExtremaPC_Curve(const GeomAdaptor_Curve& theCurve);
0086 
0087   //! Constructor with curve adaptor and parameter range.
0088   //! @param[in] theCurve curve adaptor
0089   //! @param[in] theUMin lower parameter bound
0090   //! @param[in] theUMax upper parameter bound
0091   Standard_EXPORT ExtremaPC_Curve(const GeomAdaptor_Curve& theCurve,
0092                                   double                   theUMin,
0093                                   double                   theUMax);
0094 
0095   //! Constructor with transformed curve adaptor.
0096   //! Uses the curve's natural parameter bounds as domain.
0097   //! For elementary curves, uses already-transformed primitives (analytical solver).
0098   //! For BSpline/Bezier, uses inverse-transform optimization with post-processing.
0099   //! For offset/other curves, delegates through Adaptor3d_Curve interface.
0100   //! @param[in] theCurve transformed curve adaptor
0101   Standard_EXPORT explicit ExtremaPC_Curve(const GeomAdaptor_TransformedCurve& theCurve);
0102 
0103   //! Constructor with transformed curve adaptor and parameter range.
0104   //! @param[in] theCurve transformed curve adaptor
0105   //! @param[in] theUMin lower parameter bound
0106   //! @param[in] theUMax upper parameter bound
0107   Standard_EXPORT ExtremaPC_Curve(const GeomAdaptor_TransformedCurve& theCurve,
0108                                   double                              theUMin,
0109                                   double                              theUMax);
0110 
0111   //! Constructor with Geom_Curve.
0112   //! For non-trimmed curves, does NOT set domain (uses natural/unbounded behavior).
0113   //! For trimmed curves, uses the trimmed bounds as domain.
0114   //! @param[in] theCurve geometric curve handle
0115   Standard_EXPORT explicit ExtremaPC_Curve(const occ::handle<Geom_Curve>& theCurve);
0116 
0117   //! Constructor with Geom_Curve and parameter range.
0118   //! For trimmed curves, intersects input bounds with trimmed bounds.
0119   //! @param[in] theCurve geometric curve handle
0120   //! @param[in] theUMin lower parameter bound
0121   //! @param[in] theUMax upper parameter bound
0122   Standard_EXPORT ExtremaPC_Curve(const occ::handle<Geom_Curve>& theCurve,
0123                                   double                         theUMin,
0124                                   double                         theUMax);
0125 
0126   ExtremaPC_Curve(const ExtremaPC_Curve&)            = delete;
0127   ExtremaPC_Curve& operator=(const ExtremaPC_Curve&) = delete;
0128   ExtremaPC_Curve(ExtremaPC_Curve&&)                 = delete;
0129   ExtremaPC_Curve& operator=(ExtremaPC_Curve&&)      = delete;
0130 
0131   //! Computes extrema between point P and the curve.
0132   //! Uses domain specified at construction time.
0133   //! @param[in] theP query point
0134   //! @param[in] theTol tolerance for extrema computation
0135   //! @param[in] theMode search mode (MinMax, Min, or Max)
0136   //! @return const reference to result containing all found extrema
0137   [[nodiscard]] Standard_EXPORT const ExtremaPC::Result& Perform(
0138     const gp_Pnt&         theP,
0139     double                theTol,
0140     ExtremaPC::SearchMode theMode = ExtremaPC::SearchMode::MinMax) const;
0141 
0142   //! Computes extrema between point P and the curve, including endpoints.
0143   //! Uses domain specified at construction time.
0144   //! @param[in] theP query point
0145   //! @param[in] theTol tolerance for extrema computation
0146   //! @param[in] theMode search mode (MinMax, Min, or Max)
0147   //! @return const reference to result containing interior + endpoint extrema
0148   [[nodiscard]] Standard_EXPORT const ExtremaPC::Result& PerformWithEndpoints(
0149     const gp_Pnt&         theP,
0150     double                theTol,
0151     ExtremaPC::SearchMode theMode = ExtremaPC::SearchMode::MinMax) const;
0152 
0153   //! Returns true if the evaluator is properly initialized.
0154   bool IsInitialized() const { return !std::holds_alternative<std::monostate>(myEvaluator); }
0155 
0156 private:
0157   //! Helper to initialize evaluator from an adaptor curve with curve-type switch.
0158   //! @param[in] theCurve the adaptor curve
0159   //! @param[in] theDomain parameter domain
0160   void initFromAdaptor(const GeomAdaptor_Curve& theCurve, const ExtremaPC::Domain1D& theDomain);
0161 
0162   //! Helper method to initialize evaluator from a Geom_Curve.
0163   //! Handles all curve type detection and evaluator creation.
0164   //! @param[in] theCurve the curve to initialize from (must not be null)
0165   //! @param[in] theDomain optional domain to use
0166   void initFromGeomCurve(const occ::handle<Geom_Curve>&            theCurve,
0167                          const std::optional<ExtremaPC::Domain1D>& theDomain);
0168 
0169   //! Helper to initialize from a TransformedCurve.
0170   //! Dispatches based on curve type and transform properties.
0171   //! @param[in] theCurve the transformed curve adaptor
0172   //! @param[in] theDomain optional domain to use
0173   void initFromTransformedCurve(const GeomAdaptor_TransformedCurve&       theCurve,
0174                                 const std::optional<ExtremaPC::Domain1D>& theDomain);
0175 
0176   //! Post-process result from untransformed-space computation.
0177   //! Forward-transforms points and scales distances.
0178   //! @param[in] theSrc result in untransformed space
0179   //! @return reference to myTransformResult with transformed data
0180   const ExtremaPC::Result& postProcessTransform(const ExtremaPC::Result& theSrc) const;
0181 
0182   EvaluatorVariant             myEvaluator;            //!< Specialized evaluator
0183   const Adaptor3d_Curve*       myAdaptorRef = nullptr; //!< Non-owning pointer to caller's adaptor
0184   occ::handle<Adaptor3d_Curve> myAdaptorOwned;         //!< Owned adaptor for lifetime management
0185   gp_Trsf                      myTrsf; //!< Forward transform (identity = no post-processing)
0186   mutable ExtremaPC::Result    myTransformResult; //!< Result buffer for transform post-processing
0187 };
0188 
0189 #endif // _ExtremaPC_Curve_HeaderFile