Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-21 09:18:22

0001 // Created on: 2016-02-20
0002 // Created by: Kirill Gavrilov
0003 // Copyright (c) 2016 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 _Select3D_SensitivePrimitiveArray_Header
0017 #define _Select3D_SensitivePrimitiveArray_Header
0018 
0019 #include <Graphic3d_IndexBuffer.hxx>
0020 #include <Graphic3d_TypeOfPrimitiveArray.hxx>
0021 #include <Select3D_SensitiveSet.hxx>
0022 #include <Select3D_BVHIndexBuffer.hxx>
0023 #include <TColStd_HPackedMapOfInteger.hxx>
0024 #include <NCollection_Array1.hxx>
0025 #include <NCollection_Shared.hxx>
0026 
0027 #include <array>
0028 
0029 //! Sensitive for triangulation or point set defined by Primitive Array.
0030 //! The primitives can be optionally combined into patches within BVH tree
0031 //! to reduce its building time in expense of extra traverse time.
0032 class Select3D_SensitivePrimitiveArray : public Select3D_SensitiveSet
0033 {
0034 
0035 public:
0036   //! Constructs an empty sensitive object.
0037   Standard_EXPORT Select3D_SensitivePrimitiveArray(
0038     const occ::handle<SelectMgr_EntityOwner>& theOwnerId);
0039 
0040   //! Return patch size limit (1 by default).
0041   int PatchSizeMax() const { return myPatchSizeMax; }
0042 
0043   //! Assign patch size limit.
0044   //! Should be set before initialization.
0045   void SetPatchSizeMax(const int thePatchSizeMax) { myPatchSizeMax = thePatchSizeMax; }
0046 
0047   //! Maximum allowed distance between consequential elements in patch (ShortRealLast() by default).
0048   //! Has no effect on indexed triangulation.
0049   float PatchDistance() const { return myPatchDistance; }
0050 
0051   //! Assign patch distance limit.
0052   //! Should be set before initialization.
0053   void SetPatchDistance(const float thePatchDistMax) { myPatchDistance = thePatchDistMax; }
0054 
0055   //! Initialize the sensitive object from triangualtion.
0056   //! The sub-triangulation can be specified by arguments theIndexLower and theIndexUpper
0057   //! (these are for iterating theIndices, not to restrict the actual index values!).
0058   //! @param theVerts        attributes array containing Graphic3d_TOA_POS with type
0059   //! Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
0060   //! @param theIndices      index array defining triangulation
0061   //! @param theInitLoc      location
0062   //! @param theIndexLower   the theIndices range - first value (inclusive), starting from 0 and
0063   //! multiple by 3
0064   //! @param theIndexUpper   the theIndices range - last  value (inclusive), upto
0065   //! theIndices->NbElements-1 and multiple by 3
0066   //! @param theToEvalMinMax compute bounding box within initialization
0067   //! @param theNbGroups     number of groups to split the vertex array into several parts
0068   Standard_EXPORT bool InitTriangulation(const occ::handle<Graphic3d_Buffer>&      theVerts,
0069                                          const occ::handle<Graphic3d_IndexBuffer>& theIndices,
0070                                          const TopLoc_Location&                    theInitLoc,
0071                                          const int                                 theIndexLower,
0072                                          const int                                 theIndexUpper,
0073                                          const bool theToEvalMinMax = true,
0074                                          const int  theNbGroups     = 1);
0075 
0076   //! Initialize the sensitive object from triangualtion.
0077   //! @param theVerts        attributes array containing Graphic3d_TOA_POS with type
0078   //! Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
0079   //! @param theIndices      index array defining triangulation
0080   //! @param theInitLoc      location
0081   //! @param theToEvalMinMax compute bounding box within initialization
0082   //! @param theNbGroups     number of groups to split the vertex array into several parts
0083   bool InitTriangulation(const occ::handle<Graphic3d_Buffer>&      theVerts,
0084                          const occ::handle<Graphic3d_IndexBuffer>& theIndices,
0085                          const TopLoc_Location&                    theInitLoc,
0086                          const bool                                theToEvalMinMax = true,
0087                          const int                                 theNbGroups     = 1)
0088   {
0089     const int anUpper = !theIndices.IsNull()
0090                           ? (theIndices->NbElements - 1)
0091                           : (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0);
0092     return InitTriangulation(theVerts,
0093                              theIndices,
0094                              theInitLoc,
0095                              0,
0096                              anUpper,
0097                              theToEvalMinMax,
0098                              theNbGroups);
0099   }
0100 
0101   //! Initialize the sensitive object from point set.
0102   //! The sub-set of points can be specified by arguments theIndexLower and theIndexUpper
0103   //! (these are for iterating theIndices, not to restrict the actual index values!).
0104   //! @param theVerts        attributes array containing Graphic3d_TOA_POS with type
0105   //! Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
0106   //! @param theIndices      index array defining points
0107   //! @param theInitLoc      location
0108   //! @param theIndexLower   the theIndices range - first value (inclusive), starting from 0
0109   //! @param theIndexUpper   the theIndices range - last  value (inclusive), upto
0110   //! theIndices->NbElements-1
0111   //! @param theToEvalMinMax compute bounding box within initialization
0112   //! @param theNbGroups     number of groups to split the vertex array into several parts
0113   Standard_EXPORT bool InitPoints(const occ::handle<Graphic3d_Buffer>&      theVerts,
0114                                   const occ::handle<Graphic3d_IndexBuffer>& theIndices,
0115                                   const TopLoc_Location&                    theInitLoc,
0116                                   const int                                 theIndexLower,
0117                                   const int                                 theIndexUpper,
0118                                   const bool                                theToEvalMinMax = true,
0119                                   const int                                 theNbGroups     = 1);
0120 
0121   //! Initialize the sensitive object from point set.
0122   //! @param theVerts        attributes array containing Graphic3d_TOA_POS with type
0123   //! Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
0124   //! @param theIndices      index array to define subset of points
0125   //! @param theInitLoc      location
0126   //! @param theToEvalMinMax compute bounding box within initialization
0127   //! @param theNbGroups     number of groups to split the vertex array into several parts
0128   bool InitPoints(const occ::handle<Graphic3d_Buffer>&      theVerts,
0129                   const occ::handle<Graphic3d_IndexBuffer>& theIndices,
0130                   const TopLoc_Location&                    theInitLoc,
0131                   const bool                                theToEvalMinMax = true,
0132                   const int                                 theNbGroups     = 1)
0133   {
0134     const int anUpper = !theIndices.IsNull()
0135                           ? (theIndices->NbElements - 1)
0136                           : (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0);
0137     return InitPoints(theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
0138   }
0139 
0140   //! Initialize the sensitive object from point set.
0141   //! @param theVerts        attributes array containing Graphic3d_TOA_POS with type
0142   //! Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
0143   //! @param theInitLoc      location
0144   //! @param theToEvalMinMax compute bounding box within initialization
0145   //! @param theNbGroups     number of groups to split the vertex array into several parts
0146   bool InitPoints(const occ::handle<Graphic3d_Buffer>& theVerts,
0147                   const TopLoc_Location&               theInitLoc,
0148                   const bool                           theToEvalMinMax = true,
0149                   const int                            theNbGroups     = 1)
0150   {
0151     const int anUpper = !theVerts.IsNull() ? (theVerts->NbElements - 1) : 0;
0152     return InitPoints(theVerts,
0153                       occ::handle<Graphic3d_IndexBuffer>(),
0154                       theInitLoc,
0155                       0,
0156                       anUpper,
0157                       theToEvalMinMax,
0158                       theNbGroups);
0159   }
0160 
0161   //! Assign new not transformed bounding box.
0162   void SetMinMax(double theMinX,
0163                  double theMinY,
0164                  double theMinZ,
0165                  double theMaxX,
0166                  double theMaxY,
0167                  double theMaxZ)
0168   {
0169     myBndBox = Select3D_BndBox3d(NCollection_Vec3<double>(theMinX, theMinY, theMinZ),
0170                                  NCollection_Vec3<double>(theMaxX, theMaxY, theMaxZ));
0171     if (!myGroups.IsNull())
0172     {
0173       for (Select3D_PrimArraySubGroupArray::Iterator aGroupIter(*myGroups); aGroupIter.More();
0174            aGroupIter.Next())
0175       {
0176         aGroupIter.Value()->myBndBox = myBndBox;
0177       }
0178     }
0179   }
0180 
0181   //! Return flag to keep index of last topmost detected element, TRUE by default.
0182   bool ToDetectElements() const { return myToDetectElem; }
0183 
0184   //! Setup keeping of the index of last topmost detected element (axis picking).
0185   void SetDetectElements(bool theToDetect) { myToDetectElem = theToDetect; }
0186 
0187   //! Return flag to keep index map of last detected elements, FALSE by default (rectangle
0188   //! selection).
0189   bool ToDetectElementMap() const { return !myDetectedElemMap.IsNull(); }
0190 
0191   //! Setup keeping of the index map of last detected elements (rectangle selection).
0192   Standard_EXPORT void SetDetectElementMap(bool theToDetect);
0193 
0194   //! Return flag to keep index of last topmost detected node, FALSE by default.
0195   bool ToDetectNodes() const { return myToDetectNode; }
0196 
0197   //! Setup keeping of the index of last topmost detected node (for axis picking).
0198   void SetDetectNodes(bool theToDetect) { myToDetectNode = theToDetect; }
0199 
0200   //! Return flag to keep index map of last detected nodes, FALSE by default (rectangle selection).
0201   bool ToDetectNodeMap() const { return !myDetectedNodeMap.IsNull(); }
0202 
0203   //! Setup keeping of the index map of last detected nodes (rectangle selection).
0204   Standard_EXPORT void SetDetectNodeMap(bool theToDetect);
0205 
0206   //! Return flag to keep index of last topmost detected edge, FALSE by default.
0207   bool ToDetectEdges() const { return myToDetectEdge; }
0208 
0209   //! Setup keeping of the index of last topmost detected edge (axis picking).
0210   void SetDetectEdges(bool theToDetect) { myToDetectEdge = theToDetect; }
0211 
0212   //! Return last topmost detected element or -1 if undefined (axis picking).
0213   int LastDetectedElement() const { return myDetectedElem; }
0214 
0215   //! Return the index map of last detected elements (rectangle selection).
0216   const occ::handle<TColStd_HPackedMapOfInteger>& LastDetectedElementMap() const
0217   {
0218     return myDetectedElemMap;
0219   }
0220 
0221   //! Return last topmost detected node or -1 if undefined (axis picking).
0222   int LastDetectedNode() const { return myDetectedNode; }
0223 
0224   //! Return the index map of last detected nodes (rectangle selection).
0225   const occ::handle<TColStd_HPackedMapOfInteger>& LastDetectedNodeMap() const
0226   {
0227     return myDetectedNodeMap;
0228   }
0229 
0230   //! Return the first node of last topmost detected edge or -1 if undefined (axis picking).
0231   int LastDetectedEdgeNode1() const { return myDetectedEdgeNode1; }
0232 
0233   //! Return the second node of last topmost detected edge or -1 if undefined (axis picking).
0234   int LastDetectedEdgeNode2() const { return myDetectedEdgeNode2; }
0235 
0236   //! Return the three vertex positions of the triangle at the given triangulation index.
0237   //! Only meaningful for triangulation-based primitive arrays.
0238   //! @param[in] theIndex zero-based triangle index within [0, triangle count)
0239   Standard_EXPORT std::array<NCollection_Vec3<float>, 3> GetVertex(const int theIndex) const;
0240 
0241   //! Dumps the content of me into the stream
0242   Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const override;
0243 
0244 public:
0245   //! Checks whether the sensitive entity is overlapped by current selecting volume.
0246   Standard_EXPORT bool Matches(SelectBasics_SelectingVolumeManager& theMgr,
0247                                SelectBasics_PickResult&             thePickResult) override;
0248 
0249   Standard_EXPORT occ::handle<Select3D_SensitiveEntity> GetConnected() override;
0250 
0251   //! Returns the length of array of triangles or edges
0252   Standard_EXPORT int Size() const override;
0253 
0254   //! Returns the amount of nodes in triangulation
0255   int NbSubElements() const override
0256   {
0257     return !myGroups.IsNull() ? myGroups->Length() : myBvhIndices.NbElements;
0258   }
0259 
0260   //! Returns bounding box of triangle/edge with index theIdx
0261   Standard_EXPORT Select3D_BndBox3d Box(const int theIdx) const override;
0262 
0263   //! Returns geometry center of triangle/edge with index theIdx
0264   //! in array along the given axis theAxis
0265   Standard_EXPORT double Center(const int theIdx, const int theAxis) const override;
0266 
0267   //! Swaps items with indexes theIdx1 and theIdx2 in array
0268   Standard_EXPORT void Swap(const int theIdx1, const int theIdx2) override;
0269 
0270   //! Returns bounding box of the triangulation. If location
0271   //! transformation is set, it will be applied
0272   Standard_EXPORT Select3D_BndBox3d BoundingBox() override;
0273 
0274   //! Returns center of triangulation. If location transformation
0275   //! is set, it will be applied
0276   gp_Pnt CenterOfGeometry() const override { return myCDG3D; }
0277 
0278   //! Returns true if the shape corresponding to the entity has init location
0279   bool HasInitLocation() const override { return !myInitLocation.IsIdentity(); }
0280 
0281   //! Returns inversed location transformation matrix if the shape corresponding
0282   //! to this entity has init location set. Otherwise, returns identity matrix.
0283   gp_GTrsf InvInitLocation() const override { return myInvInitLocation; }
0284 
0285   //! Sets the owner for all entities in group
0286   Standard_EXPORT void Set(const occ::handle<SelectMgr_EntityOwner>& theOwnerId) override;
0287 
0288   //! Builds BVH tree for sensitive set.
0289   Standard_EXPORT void BVH() override;
0290 
0291 protected:
0292   //! Compute bounding box.
0293   Standard_EXPORT void computeBoundingBox();
0294 
0295   //! Inner function for transformation application to bounding
0296   //! box of the triangulation
0297   Standard_EXPORT Select3D_BndBox3d applyTransformation();
0298 
0299   //! Auxiliary getter.
0300   const NCollection_Vec3<float>& getPosVec3(const int theIndex) const
0301   {
0302     return *reinterpret_cast<const NCollection_Vec3<float>*>(myPosData + myPosStride * theIndex);
0303   }
0304 
0305   //! Auxiliary getter.
0306   const NCollection_Vec2<float>& getPosVec2(const int theIndex) const
0307   {
0308     return *reinterpret_cast<const NCollection_Vec2<float>*>(myPosData + myPosStride * theIndex);
0309   }
0310 
0311   //! Checks whether the element with index theIdx overlaps the current selecting volume
0312   Standard_EXPORT bool overlapsElement(SelectBasics_PickResult&             thePickResult,
0313                                        SelectBasics_SelectingVolumeManager& theMgr,
0314                                        int                                  theElemIdx,
0315                                        bool theIsFullInside) override;
0316 
0317   //! Calculates distance from the 3d projection of used-picked screen point to center of the
0318   //! geometry
0319   Standard_EXPORT double distanceToCOG(SelectBasics_SelectingVolumeManager& theMgr) override;
0320 
0321   //! Checks whether the entity with index theIdx is inside the current selecting volume
0322   Standard_EXPORT bool elementIsInside(SelectBasics_SelectingVolumeManager& theMgr,
0323                                        int                                  theElemIdx,
0324                                        bool theIsFullInside) override;
0325 
0326 private:
0327   typedef NCollection_Shared<NCollection_Array1<occ::handle<Select3D_SensitivePrimitiveArray>>>
0328     Select3D_PrimArraySubGroupArray;
0329   struct Select3D_SensitivePrimitiveArray_InitFunctor;
0330   struct Select3D_SensitivePrimitiveArray_BVHFunctor;
0331 
0332 private:
0333   occ::handle<Select3D_PrimArraySubGroupArray> myGroups; //!< sub-groups of sensitive entities
0334 
0335   occ::handle<Graphic3d_Buffer>      myVerts;   //!< source data - nodes position
0336   occ::handle<Graphic3d_IndexBuffer> myIndices; //!< source data - primitive indexes
0337   const uint8_t*                     myPosData; //!< position vertex attribute data
0338   // clang-format off
0339   size_t                       myPosStride;          //!< position vertex attribute stride in bytes
0340   Graphic3d_TypeOfPrimitiveArray      myPrimType;           //!< primitives type
0341   int                    myIndexLower;         //!< index range - first index in myIndices (inclusive)
0342   int                    myIndexUpper;         //!< index range - last  index in myIndices (inclusive)
0343   int                    myPatchSizeMax;       //!< patch size limit (1 by default)
0344   float                               myPatchDistance;      //!< distance between elements in patch
0345   bool                                myIs3d;               //!< flag indicating that position attribute has 3 components
0346   TopLoc_Location                     myInitLocation;
0347   gp_Pnt                              myCDG3D;              //!< Center of the whole triangulation
0348   Select3D_BVHIndexBuffer             myBvhIndices;         //!< Indexes of edges or triangles for BVH tree
0349   mutable Select3D_BndBox3d           myBndBox;             //!< Bounding box of the whole triangulation
0350   gp_GTrsf                            myInvInitLocation;
0351   occ::handle<TColStd_HPackedMapOfInteger> myDetectedElemMap;    //!< index map of last detected elements
0352   occ::handle<TColStd_HPackedMapOfInteger> myDetectedNodeMap;    //!< index map of last detected nodes
0353   double                       myMinDepthElem;       //!< the depth of nearest detected element
0354   double                       myMinDepthNode;       //!< the depth of nearest detected node
0355   double                       myMinDepthEdge;       //!< the depth of nearest detected edge
0356   int                    myDetectedElem;       //!< index of last detected element
0357   int                    myDetectedNode;       //!< index of last detected node
0358   int                    myDetectedEdgeNode1;  //!< index of last detected edge node 1
0359   int                    myDetectedEdgeNode2;  //!< index of last detected edge node 2
0360   bool                                myToDetectElem;       //!< flag to keep info about last detected element
0361   bool                                myToDetectNode;       //!< flag to keep info about last detected node
0362   bool                                myToDetectEdge;       //!< flag to keep info about last detected edge
0363   // clang-format on
0364 
0365 public:
0366   DEFINE_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
0367 };
0368 
0369 #endif // _Select3D_SensitivePrimitiveArray_Header