Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-12 09:18:32

0001 // Created on: 2014-05-22
0002 // Created by: Varvara POSKONINA
0003 // Copyright (c) 2005-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _SelectMgr_RectangularFrustum_HeaderFile
0017 #define _SelectMgr_RectangularFrustum_HeaderFile
0018 
0019 #include <SelectMgr_Frustum.hxx>
0020 
0021 //! This class contains representation of rectangular selecting frustum, created in case
0022 //! of point and box selection, and algorithms for overlap detection between selecting
0023 //! frustum and sensitive entities. The principle of frustum calculation:
0024 //! - for point selection: on a near view frustum plane rectangular neighborhood of
0025 //!                        user-picked point is created according to the pixel tolerance
0026 //!                        given and then this rectangle is projected onto far view frustum
0027 //!                        plane. This rectangles define the parallel bases of selecting frustum;
0028 //! - for box selection: box points are projected onto near and far view frustum planes.
0029 //!                      These 2 projected rectangles define parallel bases of selecting frustum.
0030 //! Overlap detection tests are implemented according to the terms of separating axis
0031 //! theorem (SAT).
0032 class SelectMgr_RectangularFrustum : public SelectMgr_Frustum<4>
0033 {
0034 public:
0035   //! Auxiliary structure to define selection primitive (point or box)
0036   //! In case of point selection min and max points are identical.
0037   struct SelectionRectangle
0038   {
0039     SelectionRectangle()
0040         : myMinPnt(gp_Pnt2d(RealLast(), RealLast())),
0041           myMaxPnt(gp_Pnt2d(RealLast(), RealLast()))
0042     {
0043     }
0044 
0045     const gp_Pnt2d& MousePos() const { return myMinPnt; }
0046 
0047     void SetMousePos(const gp_Pnt2d& thePos)
0048     {
0049       myMinPnt = thePos;
0050       myMaxPnt = thePos;
0051     }
0052 
0053     const gp_Pnt2d& MinPnt() const { return myMinPnt; }
0054 
0055     void SetMinPnt(const gp_Pnt2d& theMinPnt) { myMinPnt = theMinPnt; }
0056 
0057     const gp_Pnt2d& MaxPnt() const { return myMaxPnt; }
0058 
0059     void SetMaxPnt(const gp_Pnt2d& theMaxPnt) { myMaxPnt = theMaxPnt; }
0060 
0061   private:
0062     gp_Pnt2d myMinPnt;
0063     gp_Pnt2d myMaxPnt;
0064   };
0065 
0066   //! Creates rectangular selecting frustum.
0067   Standard_EXPORT SelectMgr_RectangularFrustum();
0068 
0069   //! Initializes volume according to the point and given pixel tolerance
0070   Standard_EXPORT void Init(const gp_Pnt2d& thePoint);
0071 
0072   //! Initializes volume according to the selected rectangle
0073   Standard_EXPORT void Init(const gp_Pnt2d& theMinPnt, const gp_Pnt2d& theMaxPnt);
0074 
0075   //! Returns True if Frustum (theVertices) intersects the circle.
0076   Standard_EXPORT bool isIntersectCircle(const double                      theRadius,
0077                                          const gp_Pnt&                     theCenter,
0078                                          const gp_Trsf&                    theTrsf,
0079                                          const NCollection_Array1<gp_Pnt>& theVertices) const;
0080 
0081   //! Returns True if Seg1 (thePnt1Seg1, thePnt2Seg1) and Seg2 (thePnt1Seg2, thePnt2Seg2) intersect.
0082   Standard_EXPORT bool isSegmentsIntersect(const gp_Pnt& thePnt1Seg1,
0083                                            const gp_Pnt& thePnt2Seg1,
0084                                            const gp_Pnt& thePnt1Seg2,
0085                                            const gp_Pnt& thePnt2Seg2) const;
0086 
0087   //! Builds volume according to internal parameters.
0088   //! NOTE: it should be called after Init() method
0089   Standard_EXPORT void Build() override;
0090 
0091   //! Checks if it is possible to scale this frustum.
0092   //! It is true for frustum built on a single point.
0093   Standard_EXPORT bool IsScalable() const override;
0094 
0095   //! IMPORTANT: Scaling makes sense only for frustum built on a single point!
0096   //!            Note that this method does not perform any checks on type of the frustum.
0097   //! Returns a copy of the frustum resized according to the scale factor given
0098   //! and transforms it using the matrix given.
0099   //! There are no default parameters, but in case if:
0100   //!    - transformation only is needed: @theScaleFactor must be initialized as any negative value;
0101   //!    - scale only is needed: @theTrsf must be set to gp_Identity.
0102   //! Builder is an optional argument that represents corresponding settings for re-constructing
0103   //! transformed frustum from scratch. Can be null if reconstruction is not expected furthermore.
0104   Standard_EXPORT occ::handle<SelectMgr_BaseIntersector> ScaleAndTransform(
0105     const int                                    theScaleFactor,
0106     const gp_GTrsf&                              theTrsf,
0107     const occ::handle<SelectMgr_FrustumBuilder>& theBuilder) const override;
0108 
0109   //! Returns a copy of the frustum using the given frustum builder configuration.
0110   //! Returned frustum should be re-constructed before being used.
0111   //! @param[in] theBuilder  argument that represents corresponding settings for re-constructing
0112   //! transformed frustum from scratch;
0113   //!                        should NOT be NULL.
0114   //! @return a copy of the frustum with the input builder assigned
0115   Standard_EXPORT occ::handle<SelectMgr_BaseIntersector> CopyWithBuilder(
0116     const occ::handle<SelectMgr_FrustumBuilder>& theBuilder) const override;
0117 
0118   // SAT Tests for different objects
0119 
0120   //! SAT intersection test between defined volume and given axis-aligned box
0121   Standard_EXPORT bool OverlapsBox(const NCollection_Vec3<double>& theBoxMin,
0122                                    const NCollection_Vec3<double>& theBoxMax,
0123                                    const SelectMgr_ViewClipRange&  theClipRange,
0124                                    SelectBasics_PickResult&        thePickResult) const override;
0125 
0126   //! Returns true if selecting volume is overlapped by axis-aligned bounding box
0127   //! with minimum corner at point theMinPt and maximum at point theMaxPt
0128   Standard_EXPORT bool OverlapsBox(const NCollection_Vec3<double>& theBoxMin,
0129                                    const NCollection_Vec3<double>& theBoxMax,
0130                                    bool*                           theInside) const override;
0131 
0132   //! Intersection test between defined volume and given point
0133   Standard_EXPORT bool OverlapsPoint(const gp_Pnt&                  thePnt,
0134                                      const SelectMgr_ViewClipRange& theClipRange,
0135                                      SelectBasics_PickResult&       thePickResult) const override;
0136 
0137   //! Intersection test between defined volume and given point
0138   Standard_EXPORT bool OverlapsPoint(const gp_Pnt& thePnt) const override;
0139 
0140   //! SAT intersection test between defined volume and given ordered set of points,
0141   //! representing line segments. The test may be considered of interior part or
0142   //! boundary line defined by segments depending on given sensitivity type
0143   Standard_EXPORT bool OverlapsPolygon(const NCollection_Array1<gp_Pnt>& theArrayOfPnts,
0144                                        Select3D_TypeOfSensitivity        theSensType,
0145                                        const SelectMgr_ViewClipRange&    theClipRange,
0146                                        SelectBasics_PickResult& thePickResult) const override;
0147 
0148   //! Checks if line segment overlaps selecting frustum
0149   Standard_EXPORT bool OverlapsSegment(const gp_Pnt&                  thePnt1,
0150                                        const gp_Pnt&                  thePnt2,
0151                                        const SelectMgr_ViewClipRange& theClipRange,
0152                                        SelectBasics_PickResult&       thePickResult) const override;
0153 
0154   //! SAT intersection test between defined volume and given triangle. The test may
0155   //! be considered of interior part or boundary line defined by triangle vertices
0156   //! depending on given sensitivity type
0157   Standard_EXPORT bool OverlapsTriangle(const gp_Pnt&                  thePnt1,
0158                                         const gp_Pnt&                  thePnt2,
0159                                         const gp_Pnt&                  thePnt3,
0160                                         Select3D_TypeOfSensitivity     theSensType,
0161                                         const SelectMgr_ViewClipRange& theClipRange,
0162                                         SelectBasics_PickResult& thePickResult) const override;
0163 
0164   //! Intersection test between defined volume and given sphere
0165   Standard_EXPORT bool OverlapsSphere(const gp_Pnt&                  theCenter,
0166                                       const double                   theRadius,
0167                                       const SelectMgr_ViewClipRange& theClipRange,
0168                                       SelectBasics_PickResult&       thePickResult) const override;
0169 
0170   //! Intersection test between defined volume and given sphere
0171   Standard_EXPORT bool OverlapsSphere(const gp_Pnt& theCenter,
0172                                       const double  theRadius,
0173                                       bool*         theInside) const override;
0174 
0175   //! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses
0176   //! theBottomRad and theTopRad, height theHeight and transformation to apply theTrsf.
0177   Standard_EXPORT bool OverlapsCylinder(const double                   theBottomRad,
0178                                         const double                   theTopRad,
0179                                         const double                   theHeight,
0180                                         const gp_Trsf&                 theTrsf,
0181                                         const bool                     theIsHollow,
0182                                         const SelectMgr_ViewClipRange& theClipRange,
0183                                         SelectBasics_PickResult& thePickResult) const override;
0184 
0185   //! Returns true if selecting volume is overlapped by cylinder (or cone) with radiuses
0186   //! theBottomRad and theTopRad, height theHeight and transformation to apply theTrsf.
0187   Standard_EXPORT bool OverlapsCylinder(const double   theBottomRad,
0188                                         const double   theTopRad,
0189                                         const double   theHeight,
0190                                         const gp_Trsf& theTrsf,
0191                                         const bool     theIsHollow,
0192                                         bool*          theInside = nullptr) const override;
0193 
0194   //! Returns true if selecting volume is overlapped by circle with radius theRadius,
0195   //! boolean theIsFilled and transformation to apply theTrsf.
0196   //! The position and orientation of the circle are specified
0197   //! via theTrsf transformation for gp::XOY() with center in gp::Origin().
0198   Standard_EXPORT bool OverlapsCircle(const double                   theBottomRad,
0199                                       const gp_Trsf&                 theTrsf,
0200                                       const bool                     theIsFilled,
0201                                       const SelectMgr_ViewClipRange& theClipRange,
0202                                       SelectBasics_PickResult&       thePickResult) const override;
0203 
0204   //! Returns true if selecting volume is overlapped by circle with radius theRadius,
0205   //! boolean theIsFilled and transformation to apply theTrsf.
0206   //! The position and orientation of the circle are specified
0207   //! via theTrsf transformation for gp::XOY() with center in gp::Origin().
0208   Standard_EXPORT bool OverlapsCircle(const double   theBottomRad,
0209                                       const gp_Trsf& theTrsf,
0210                                       const bool     theIsFilled,
0211                                       bool*          theInside = nullptr) const override;
0212 
0213   //! Measures distance between 3d projection of user-picked
0214   //! screen point and given point theCOG.
0215   //! It makes sense only for frustums built on a single point.
0216   Standard_EXPORT double DistToGeometryCenter(const gp_Pnt& theCOG) const override;
0217 
0218   //! Calculates the point on a view ray that was detected during the run of selection algo by given
0219   //! depth
0220   Standard_EXPORT gp_Pnt DetectedPoint(const double theDepth) const override;
0221 
0222   //! A set of helper functions that return rectangular selecting frustum data
0223   const gp_Pnt* GetVertices() const { return myVertices; }
0224 
0225   //! Returns projection of 2d mouse picked point or projection
0226   //! of center of 2d rectangle (for point and rectangular selection
0227   //! correspondingly) onto near view frustum plane
0228   const gp_Pnt& GetNearPnt() const override { return myNearPickedPnt; }
0229 
0230   //! Returns projection of 2d mouse picked point or projection
0231   //! of center of 2d rectangle (for point and rectangular selection
0232   //! correspondingly) onto far view frustum plane
0233   const gp_Pnt& GetFarPnt() const override { return myFarPickedPnt; }
0234 
0235   //! Returns view ray direction.
0236   const gp_Dir& GetViewRayDirection() const override { return myViewRayDir; }
0237 
0238   //! Returns current mouse coordinates.
0239   Standard_EXPORT const gp_Pnt2d& GetMousePosition() const override;
0240 
0241   //! Stores plane equation coefficients (in the following form:
0242   //! Ax + By + Cz + D = 0) to the given vector
0243   Standard_EXPORT void GetPlanes(
0244     NCollection_DynamicArray<NCollection_Vec4<double>>& thePlaneEquations) const override;
0245 
0246   //! Dumps the content of me into the stream
0247   Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const override;
0248 
0249 protected:
0250   Standard_EXPORT void segmentSegmentDistance(const gp_Pnt&            theSegPnt1,
0251                                               const gp_Pnt&            theSegPnt2,
0252                                               SelectBasics_PickResult& thePickResult) const;
0253 
0254   Standard_EXPORT bool segmentPlaneIntersection(const gp_Vec&            thePlane,
0255                                                 const gp_Pnt&            thePntOnPlane,
0256                                                 SelectBasics_PickResult& thePickResult) const;
0257 
0258 private:
0259   void cacheVertexProjections(SelectMgr_RectangularFrustum* theFrustum) const;
0260 
0261 private:
0262   enum
0263   {
0264     LeftTopNear,
0265     LeftTopFar,
0266     LeftBottomNear,
0267     LeftBottomFar,
0268     RightTopNear,
0269     RightTopFar,
0270     RightBottomNear,
0271     RightBottomFar
0272   };
0273 
0274 private:
0275   // clang-format off
0276   SelectionRectangle      mySelRectangle;              //!< parameters for selection by point or box (it is used to build frustum)
0277   gp_Pnt                  myNearPickedPnt;             //!< 3d projection of user-picked selection point onto near view plane
0278   gp_Pnt                  myFarPickedPnt;              //!< 3d projection of user-picked selection point onto far view plane
0279   gp_Dir                  myViewRayDir;                //!< view ray direction
0280   double           myScale;                     //!< Scale factor of applied transformation, if there was any
0281   // clang-format on
0282 };
0283 
0284 #endif // _SelectMgr_RectangularFrustum_HeaderFile