Back to home page

EIC code displayed by LXR

 
 

    


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

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 GeomBndLib_Plane_HeaderFile
0015 #define GeomBndLib_Plane_HeaderFile
0016 
0017 #include <Bnd_Box.hxx>
0018 #include <ElSLib.hxx>
0019 #include <Geom_Plane.hxx>
0020 #include <gp.hxx>
0021 #include <Precision.hxx>
0022 #include <Standard_DefineAlloc.hxx>
0023 
0024 //! Computes bounding box for a 3D plane (Geom_Plane).
0025 //! Handles infinite parameters by opening box sides based on the plane normal direction.
0026 class GeomBndLib_Plane
0027 {
0028 public:
0029   DEFINE_STANDARD_ALLOC
0030 
0031   GeomBndLib_Plane(const occ::handle<Geom_Plane>& thePlane)
0032       : myGeom(thePlane)
0033   {
0034   }
0035 
0036   GeomBndLib_Plane(const GeomBndLib_Plane&)            = delete;
0037   GeomBndLib_Plane& operator=(const GeomBndLib_Plane&) = delete;
0038   GeomBndLib_Plane(GeomBndLib_Plane&&)                 = delete;
0039   GeomBndLib_Plane& operator=(GeomBndLib_Plane&&)      = delete;
0040 
0041   const occ::handle<Geom_Plane>& Geometry() const { return myGeom; }
0042 
0043   //! Compute bounding box for full plane (infinite).
0044   [[nodiscard]] Bnd_Box Box(double theTol) const
0045   {
0046     double aU1, aU2, aV1, aV2;
0047     myGeom->Bounds(aU1, aU2, aV1, aV2);
0048     return Box(aU1, aU2, aV1, aV2, theTol);
0049   }
0050 
0051   //! Compute bounding box for plane patch [theUMin, theUMax] x [theVMin, theVMax].
0052   [[nodiscard]] Bnd_Box Box(double theUMin,
0053                             double theUMax,
0054                             double theVMin,
0055                             double theVMax,
0056                             double theTol) const
0057   {
0058     const gp_Pln& aPln = myGeom->Pln();
0059     Bnd_Box       aBox;
0060 
0061     if (Precision::IsInfinite(theVMin) || Precision::IsInfinite(theVMax)
0062         || Precision::IsInfinite(theUMin) || Precision::IsInfinite(theUMax))
0063     {
0064       TreatInfinitePlane(aPln, theUMin, theUMax, theVMin, theVMax, theTol, aBox);
0065       return aBox;
0066     }
0067 
0068     aBox.Add(ElSLib::Value(theUMin, theVMin, aPln));
0069     aBox.Add(ElSLib::Value(theUMin, theVMax, aPln));
0070     aBox.Add(ElSLib::Value(theUMax, theVMin, aPln));
0071     aBox.Add(ElSLib::Value(theUMax, theVMax, aPln));
0072     aBox.Enlarge(theTol);
0073     return aBox;
0074   }
0075 
0076   //! For analytical surfaces, BoxOptimal is same as Box.
0077   [[nodiscard]] Bnd_Box BoxOptimal(double theUMin,
0078                                    double theUMax,
0079                                    double theVMin,
0080                                    double theVMax,
0081                                    double theTol) const
0082   {
0083     return Box(theUMin, theUMax, theVMin, theVMax, theTol);
0084   }
0085 
0086   //! Compute optimal bounding box for full surface.
0087   [[nodiscard]] Bnd_Box BoxOptimal(double theTol) const { return Box(theTol); }
0088 
0089 private:
0090   //! Compute barycenter point for infinite plane.
0091   static gp_Pnt BaryCenter(const gp_Pln& thePlane,
0092                            double        theUMin,
0093                            double        theUMax,
0094                            double        theVMin,
0095                            double        theVMax)
0096   {
0097     double     aU, aV;
0098     const bool isU1Inf = Precision::IsInfinite(theUMin);
0099     const bool isU2Inf = Precision::IsInfinite(theUMax);
0100     const bool isV1Inf = Precision::IsInfinite(theVMin);
0101     const bool isV2Inf = Precision::IsInfinite(theVMax);
0102 
0103     if (isU1Inf && isU2Inf)
0104       aU = 0;
0105     else if (isU1Inf)
0106       aU = theUMax - 10.;
0107     else if (isU2Inf)
0108       aU = theUMin + 10.;
0109     else
0110       aU = (theUMin + theUMax) / 2.;
0111 
0112     if (isV1Inf && isV2Inf)
0113       aV = 0;
0114     else if (isV1Inf)
0115       aV = theVMax - 10.;
0116     else if (isV2Inf)
0117       aV = theVMin + 10.;
0118     else
0119       aV = (theVMin + theVMax) / 2.;
0120 
0121     return ElSLib::Value(aU, aV, thePlane);
0122   }
0123 
0124   //! Handle infinite plane by opening appropriate box sides.
0125   static void TreatInfinitePlane(const gp_Pln& thePlane,
0126                                  double        theUMin,
0127                                  double        theUMax,
0128                                  double        theVMin,
0129                                  double        theVMax,
0130                                  double        theTol,
0131                                  Bnd_Box&      theBox)
0132   {
0133     const gp_Dir&    aNorm        = thePlane.Axis().Direction();
0134     constexpr double anAngularTol = RealEpsilon();
0135 
0136     gp_Pnt aLocation = BaryCenter(thePlane, theUMin, theUMax, theVMin, theVMax);
0137 
0138     if (aNorm.IsParallel(gp::DX(), anAngularTol))
0139     {
0140       theBox.Add(aLocation);
0141       theBox.OpenYmin();
0142       theBox.OpenYmax();
0143       theBox.OpenZmin();
0144       theBox.OpenZmax();
0145     }
0146     else if (aNorm.IsParallel(gp::DY(), anAngularTol))
0147     {
0148       theBox.Add(aLocation);
0149       theBox.OpenXmin();
0150       theBox.OpenXmax();
0151       theBox.OpenZmin();
0152       theBox.OpenZmax();
0153     }
0154     else if (aNorm.IsParallel(gp::DZ(), anAngularTol))
0155     {
0156       theBox.Add(aLocation);
0157       theBox.OpenXmin();
0158       theBox.OpenXmax();
0159       theBox.OpenYmin();
0160       theBox.OpenYmax();
0161     }
0162     else
0163     {
0164       theBox.SetWhole();
0165       return;
0166     }
0167 
0168     theBox.Enlarge(theTol);
0169   }
0170 
0171   occ::handle<Geom_Plane> myGeom;
0172 };
0173 
0174 #endif // GeomBndLib_Plane_HeaderFile