Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:20:11

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 _GeomGridEval_Plane_HeaderFile
0015 #define _GeomGridEval_Plane_HeaderFile
0016 
0017 #include <Geom_Plane.hxx>
0018 #include <GeomGridEval.hxx>
0019 #include <gp_Pln.hxx>
0020 #include <gp_Pnt2d.hxx>
0021 #include <NCollection_Array1.hxx>
0022 #include <NCollection_Array2.hxx>
0023 #include <Standard_DefineAlloc.hxx>
0024 
0025 //! @brief Efficient batch evaluator for plane grid points.
0026 //!
0027 //! Uses direct analytical formula: P(u,v) = Location + u * XDir + v * YDir
0028 //! This is a header-only implementation for maximum performance.
0029 //!
0030 //! Usage:
0031 //! @code
0032 //!   GeomGridEval_Plane anEvaluator(myGeomPlane);
0033 //!   NCollection_Array2<gp_Pnt> aGrid = anEvaluator.EvaluateGrid(myUParams, myVParams);
0034 //! @endcode
0035 class GeomGridEval_Plane
0036 {
0037 public:
0038   DEFINE_STANDARD_ALLOC
0039 
0040   //! Constructor with geometry.
0041   //! @param thePlane the plane geometry to evaluate
0042   GeomGridEval_Plane(const occ::handle<Geom_Plane>& thePlane)
0043       : myGeom(thePlane)
0044   {
0045   }
0046 
0047   //! Non-copyable and non-movable.
0048   GeomGridEval_Plane(const GeomGridEval_Plane&)            = delete;
0049   GeomGridEval_Plane& operator=(const GeomGridEval_Plane&) = delete;
0050   GeomGridEval_Plane(GeomGridEval_Plane&&)                 = delete;
0051   GeomGridEval_Plane& operator=(GeomGridEval_Plane&&)      = delete;
0052 
0053   //! Returns the geometry handle.
0054   const occ::handle<Geom_Plane>& Geometry() const { return myGeom; }
0055 
0056   //! Evaluate grid points at Cartesian product of U and V parameters.
0057   //! @param theUParams array of U parameter values
0058   //! @param theVParams array of V parameter values
0059   //! @return 2D array of evaluated points (1-based indexing)
0060   NCollection_Array2<gp_Pnt> EvaluateGrid(const NCollection_Array1<double>& theUParams,
0061                                           const NCollection_Array1<double>& theVParams) const
0062   {
0063     const int aNbU = theUParams.Length();
0064     const int aNbV = theVParams.Length();
0065     if (myGeom.IsNull() || aNbU == 0 || aNbV == 0)
0066     {
0067       return NCollection_Array2<gp_Pnt>();
0068     }
0069 
0070     NCollection_Array2<gp_Pnt> aResult(1, aNbU, 1, aNbV);
0071 
0072     // Extract plane data from geometry
0073     const gp_Pln& aPln  = myGeom->Pln();
0074     const gp_Pnt& aLoc  = aPln.Location();
0075     const gp_Dir& aXDir = aPln.Position().XDirection();
0076     const gp_Dir& aYDir = aPln.Position().YDirection();
0077 
0078     // Pre-extract coordinates for performance
0079     const double aLocX = aLoc.X();
0080     const double aLocY = aLoc.Y();
0081     const double aLocZ = aLoc.Z();
0082     const double aXX   = aXDir.X();
0083     const double aXY   = aXDir.Y();
0084     const double aXZ   = aXDir.Z();
0085     const double aYX   = aYDir.X();
0086     const double aYY   = aYDir.Y();
0087     const double aYZ   = aYDir.Z();
0088 
0089     for (int iU = 1; iU <= aNbU; ++iU)
0090     {
0091       const double u  = theUParams.Value(theUParams.Lower() + iU - 1);
0092       const double uX = aLocX + u * aXX;
0093       const double uY = aLocY + u * aXY;
0094       const double uZ = aLocZ + u * aXZ;
0095 
0096       for (int iV = 1; iV <= aNbV; ++iV)
0097       {
0098         const double v = theVParams.Value(theVParams.Lower() + iV - 1);
0099         aResult.SetValue(iU, iV, gp_Pnt(uX + v * aYX, uY + v * aYY, uZ + v * aYZ));
0100       }
0101     }
0102     return aResult;
0103   }
0104 
0105   //! Evaluate grid points with first partial derivatives.
0106   //! @param theUParams array of U parameter values
0107   //! @param theVParams array of V parameter values
0108   //! @return 2D array of SurfD1 (1-based indexing)
0109   NCollection_Array2<GeomGridEval::SurfD1> EvaluateGridD1(
0110     const NCollection_Array1<double>& theUParams,
0111     const NCollection_Array1<double>& theVParams) const
0112   {
0113     const int aNbU = theUParams.Length();
0114     const int aNbV = theVParams.Length();
0115     if (myGeom.IsNull() || aNbU == 0 || aNbV == 0)
0116     {
0117       return NCollection_Array2<GeomGridEval::SurfD1>();
0118     }
0119 
0120     NCollection_Array2<GeomGridEval::SurfD1> aResult(1, aNbU, 1, aNbV);
0121 
0122     const gp_Pln& aPln  = myGeom->Pln();
0123     const gp_Pnt& aLoc  = aPln.Location();
0124     const gp_Dir& aXDir = aPln.Position().XDirection();
0125     const gp_Dir& aYDir = aPln.Position().YDirection();
0126 
0127     const double aLocX = aLoc.X();
0128     const double aLocY = aLoc.Y();
0129     const double aLocZ = aLoc.Z();
0130     const double aXX   = aXDir.X();
0131     const double aXY   = aXDir.Y();
0132     const double aXZ   = aXDir.Z();
0133     const double aYX   = aYDir.X();
0134     const double aYY   = aYDir.Y();
0135     const double aYZ   = aYDir.Z();
0136 
0137     // D1U and D1V are constant for a plane
0138     const gp_Vec aD1U(aXX, aXY, aXZ);
0139     const gp_Vec aD1V(aYX, aYY, aYZ);
0140 
0141     for (int iU = 1; iU <= aNbU; ++iU)
0142     {
0143       const double u  = theUParams.Value(theUParams.Lower() + iU - 1);
0144       const double uX = aLocX + u * aXX;
0145       const double uY = aLocY + u * aXY;
0146       const double uZ = aLocZ + u * aXZ;
0147 
0148       for (int iV = 1; iV <= aNbV; ++iV)
0149       {
0150         const double v          = theVParams.Value(theVParams.Lower() + iV - 1);
0151         aResult.ChangeValue(iU,
0152                             iV) = {gp_Pnt(uX + v * aYX, uY + v * aYY, uZ + v * aYZ), aD1U, aD1V};
0153       }
0154     }
0155     return aResult;
0156   }
0157 
0158   //! Evaluate grid points with first and second partial derivatives.
0159   //! @param theUParams array of U parameter values
0160   //! @param theVParams array of V parameter values
0161   //! @return 2D array of SurfD2 (1-based indexing)
0162   NCollection_Array2<GeomGridEval::SurfD2> EvaluateGridD2(
0163     const NCollection_Array1<double>& theUParams,
0164     const NCollection_Array1<double>& theVParams) const
0165   {
0166     const int aNbU = theUParams.Length();
0167     const int aNbV = theVParams.Length();
0168     if (myGeom.IsNull() || aNbU == 0 || aNbV == 0)
0169     {
0170       return NCollection_Array2<GeomGridEval::SurfD2>();
0171     }
0172 
0173     NCollection_Array2<GeomGridEval::SurfD2> aResult(1, aNbU, 1, aNbV);
0174 
0175     const gp_Pln& aPln  = myGeom->Pln();
0176     const gp_Pnt& aLoc  = aPln.Location();
0177     const gp_Dir& aXDir = aPln.Position().XDirection();
0178     const gp_Dir& aYDir = aPln.Position().YDirection();
0179 
0180     const double aLocX = aLoc.X();
0181     const double aLocY = aLoc.Y();
0182     const double aLocZ = aLoc.Z();
0183     const double aXX   = aXDir.X();
0184     const double aXY   = aXDir.Y();
0185     const double aXZ   = aXDir.Z();
0186     const double aYX   = aYDir.X();
0187     const double aYY   = aYDir.Y();
0188     const double aYZ   = aYDir.Z();
0189 
0190     const gp_Vec aD1U(aXX, aXY, aXZ);
0191     const gp_Vec aD1V(aYX, aYY, aYZ);
0192     const gp_Vec aZero(0, 0, 0); // All second derivatives are zero for a plane
0193 
0194     for (int iU = 1; iU <= aNbU; ++iU)
0195     {
0196       const double u  = theUParams.Value(theUParams.Lower() + iU - 1);
0197       const double uX = aLocX + u * aXX;
0198       const double uY = aLocY + u * aXY;
0199       const double uZ = aLocZ + u * aXZ;
0200 
0201       for (int iV = 1; iV <= aNbV; ++iV)
0202       {
0203         const double v = theVParams.Value(theVParams.Lower() + iV - 1);
0204         aResult.ChangeValue(
0205           iU,
0206           iV) = {gp_Pnt(uX + v * aYX, uY + v * aYY, uZ + v * aYZ), aD1U, aD1V, aZero, aZero, aZero};
0207       }
0208     }
0209     return aResult;
0210   }
0211 
0212   //! Evaluate grid points with derivatives up to third order.
0213   //! @param theUParams array of U parameter values
0214   //! @param theVParams array of V parameter values
0215   //! @return 2D array of SurfD3 (1-based indexing)
0216   NCollection_Array2<GeomGridEval::SurfD3> EvaluateGridD3(
0217     const NCollection_Array1<double>& theUParams,
0218     const NCollection_Array1<double>& theVParams) const
0219   {
0220     const int aNbU = theUParams.Length();
0221     const int aNbV = theVParams.Length();
0222     if (myGeom.IsNull() || aNbU == 0 || aNbV == 0)
0223     {
0224       return NCollection_Array2<GeomGridEval::SurfD3>();
0225     }
0226 
0227     NCollection_Array2<GeomGridEval::SurfD3> aResult(1, aNbU, 1, aNbV);
0228 
0229     const gp_Pln& aPln  = myGeom->Pln();
0230     const gp_Pnt& aLoc  = aPln.Location();
0231     const gp_Dir& aXDir = aPln.Position().XDirection();
0232     const gp_Dir& aYDir = aPln.Position().YDirection();
0233 
0234     const double aLocX = aLoc.X();
0235     const double aLocY = aLoc.Y();
0236     const double aLocZ = aLoc.Z();
0237     const double aXX   = aXDir.X();
0238     const double aXY   = aXDir.Y();
0239     const double aXZ   = aXDir.Z();
0240     const double aYX   = aYDir.X();
0241     const double aYY   = aYDir.Y();
0242     const double aYZ   = aYDir.Z();
0243 
0244     const gp_Vec aD1U(aXX, aXY, aXZ);
0245     const gp_Vec aD1V(aYX, aYY, aYZ);
0246     const gp_Vec aZero(0, 0, 0); // All derivatives of order >= 2 are zero for a plane
0247 
0248     for (int iU = 1; iU <= aNbU; ++iU)
0249     {
0250       const double u  = theUParams.Value(theUParams.Lower() + iU - 1);
0251       const double uX = aLocX + u * aXX;
0252       const double uY = aLocY + u * aXY;
0253       const double uZ = aLocZ + u * aXZ;
0254 
0255       for (int iV = 1; iV <= aNbV; ++iV)
0256       {
0257         const double v              = theVParams.Value(theVParams.Lower() + iV - 1);
0258         aResult.ChangeValue(iU, iV) = {gp_Pnt(uX + v * aYX, uY + v * aYY, uZ + v * aYZ),
0259                                        aD1U,
0260                                        aD1V,
0261                                        aZero,
0262                                        aZero,
0263                                        aZero,
0264                                        aZero,
0265                                        aZero,
0266                                        aZero,
0267                                        aZero};
0268       }
0269     }
0270     return aResult;
0271   }
0272 
0273   //! Evaluate partial derivative d^(NU+NV)S/(dU^NU dV^NV) at all grid points.
0274   //! @param theUParams array of U parameter values
0275   //! @param theVParams array of V parameter values
0276   //! @param theNU derivative order in U direction
0277   //! @param theNV derivative order in V direction
0278   //! @return 2D array of derivative vectors (1-based indexing)
0279   NCollection_Array2<gp_Vec> EvaluateGridDN(const NCollection_Array1<double>& theUParams,
0280                                             const NCollection_Array1<double>& theVParams,
0281                                             int                               theNU,
0282                                             int                               theNV) const
0283   {
0284     const int aNbU = theUParams.Length();
0285     const int aNbV = theVParams.Length();
0286     if (myGeom.IsNull() || aNbU == 0 || aNbV == 0 || theNU < 0 || theNV < 0 || (theNU + theNV) < 1)
0287     {
0288       return NCollection_Array2<gp_Vec>();
0289     }
0290 
0291     NCollection_Array2<gp_Vec> aResult(1, aNbU, 1, aNbV);
0292 
0293     // For a plane, only D1U (1,0) and D1V (0,1) are non-zero
0294     gp_Vec aDerivative(0, 0, 0);
0295 
0296     if (theNU == 1 && theNV == 0)
0297     {
0298       // D1U = XDir
0299       const gp_Dir aXDir = myGeom->Pln().Position().XDirection();
0300       aDerivative        = gp_Vec(aXDir.X(), aXDir.Y(), aXDir.Z());
0301     }
0302     else if (theNU == 0 && theNV == 1)
0303     {
0304       // D1V = YDir
0305       const gp_Dir aYDir = myGeom->Pln().Position().YDirection();
0306       aDerivative        = gp_Vec(aYDir.X(), aYDir.Y(), aYDir.Z());
0307     }
0308     // All other derivatives are zero
0309 
0310     for (int iU = 1; iU <= aNbU; ++iU)
0311     {
0312       for (int iV = 1; iV <= aNbV; ++iV)
0313       {
0314         aResult.SetValue(iU, iV, aDerivative);
0315       }
0316     }
0317     return aResult;
0318   }
0319 
0320 private:
0321   occ::handle<Geom_Plane> myGeom;
0322 };
0323 
0324 #endif // _GeomGridEval_Plane_HeaderFile