1 // Created on: 2016-02-20
2 // Created by: Kirill Gavrilov
3 // Copyright (c) 2016 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #ifndef _Select3D_SensitivePrimitiveArray_Header
17 #define _Select3D_SensitivePrimitiveArray_Header
19 #include <Graphic3d_Buffer.hxx>
20 #include <Graphic3d_IndexBuffer.hxx>
21 #include <Graphic3d_TypeOfPrimitiveArray.hxx>
22 #include <Select3D_SensitiveSet.hxx>
23 #include <Select3D_BVHIndexBuffer.hxx>
24 #include <TColStd_HPackedMapOfInteger.hxx>
26 //! Sensitive for triangulation or point set defined by Primitive Array.
27 //! The primitives can be optionally combined into patches within BVH tree
28 //! to reduce its building time in expense of extra traverse time.
29 class Select3D_SensitivePrimitiveArray : public Select3D_SensitiveSet
34 //! Constructs an empty sensitive object.
35 Standard_EXPORT Select3D_SensitivePrimitiveArray (const Handle(SelectBasics_EntityOwner)& theOwnerId);
37 //! Return patch size limit (1 by default).
38 Standard_Integer PatchSizeMax() const { return myPatchSizeMax; }
40 //! Assign patch size limit.
41 //! Should be set before initialization.
42 void SetPatchSizeMax (const Standard_Integer thePatchSizeMax) { myPatchSizeMax = thePatchSizeMax; }
44 //! Maximum allowed distance between consequential elements in patch (ShortRealLast() by default).
45 //! Has no effect on indexed triangulation.
46 float PatchDistance() const { return myPatchDistance; }
48 //! Assign patch distance limit.
49 //! Should be set before initialization.
50 void SetPatchDistance (const float thePatchDistMax) { myPatchDistance = thePatchDistMax; }
52 //! Initialize the sensitive object from triangualtion.
53 //! The sub-triangulation can be specified by arguments theIndexLower and theIndexUpper
54 //! (these are for iterating theIndices, not to restrict the actual index values!).
55 //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
56 //! @param theIndices index array defining triangulation
57 //! @param theInitLoc location
58 //! @param theIndexLower the theIndices range - first value (inclusive), starting from 0 and multiple by 3
59 //! @param theIndexUpper the theIndices range - last value (inclusive), upto theIndices->NbElements-1 and multiple by 3
60 //! @param theToEvalMinMax compute bounding box within initialization
61 //! @param theNbGroups number of groups to split the vertex array into several parts
62 Standard_EXPORT bool InitTriangulation (const Handle(Graphic3d_Buffer)& theVerts,
63 const Handle(Graphic3d_IndexBuffer)& theIndices,
64 const TopLoc_Location& theInitLoc,
65 const Standard_Integer theIndexLower,
66 const Standard_Integer theIndexUpper,
67 const bool theToEvalMinMax = true,
68 const Standard_Integer theNbGroups = 1);
70 //! Initialize the sensitive object from triangualtion.
71 //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
72 //! @param theIndices index array defining triangulation
73 //! @param theInitLoc location
74 //! @param theToEvalMinMax compute bounding box within initialization
75 //! @param theNbGroups number of groups to split the vertex array into several parts
76 bool InitTriangulation (const Handle(Graphic3d_Buffer)& theVerts,
77 const Handle(Graphic3d_IndexBuffer)& theIndices,
78 const TopLoc_Location& theInitLoc,
79 const bool theToEvalMinMax = true,
80 const Standard_Integer theNbGroups = 1)
82 const Standard_Integer anUpper = !theIndices.IsNull() ? (theIndices->NbElements - 1)
83 : (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0);
84 return InitTriangulation (theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
87 //! Initialize the sensitive object from point set.
88 //! The sub-set of points can be specified by arguments theIndexLower and theIndexUpper
89 //! (these are for iterating theIndices, not to restrict the actual index values!).
90 //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
91 //! @param theIndices index array defining points
92 //! @param theInitLoc location
93 //! @param theIndexLower the theIndices range - first value (inclusive), starting from 0
94 //! @param theIndexUpper the theIndices range - last value (inclusive), upto theIndices->NbElements-1
95 //! @param theToEvalMinMax compute bounding box within initialization
96 //! @param theNbGroups number of groups to split the vertex array into several parts
97 Standard_EXPORT bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts,
98 const Handle(Graphic3d_IndexBuffer)& theIndices,
99 const TopLoc_Location& theInitLoc,
100 const Standard_Integer theIndexLower,
101 const Standard_Integer theIndexUpper,
102 const bool theToEvalMinMax = true,
103 const Standard_Integer theNbGroups = 1);
105 //! Initialize the sensitive object from point set.
106 //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
107 //! @param theIndices index array to define subset of points
108 //! @param theInitLoc location
109 //! @param theToEvalMinMax compute bounding box within initialization
110 //! @param theNbGroups number of groups to split the vertex array into several parts
111 bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts,
112 const Handle(Graphic3d_IndexBuffer)& theIndices,
113 const TopLoc_Location& theInitLoc,
114 const bool theToEvalMinMax = true,
115 const Standard_Integer theNbGroups = 1)
117 const Standard_Integer anUpper = !theIndices.IsNull() ? (theIndices->NbElements - 1)
118 : (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0);
119 return InitPoints (theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
122 //! Initialize the sensitive object from point set.
123 //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
124 //! @param theInitLoc location
125 //! @param theToEvalMinMax compute bounding box within initialization
126 //! @param theNbGroups number of groups to split the vertex array into several parts
127 bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts,
128 const TopLoc_Location& theInitLoc,
129 const bool theToEvalMinMax = true,
130 const Standard_Integer theNbGroups = 1)
132 const Standard_Integer anUpper = !theVerts.IsNull() ? (theVerts->NbElements - 1) : 0;
133 return InitPoints (theVerts, Handle(Graphic3d_IndexBuffer)(), theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
136 //! Assign new not transformed bounding box.
137 void SetMinMax (double theMinX, double theMinY, double theMinZ,
138 double theMaxX, double theMaxY, double theMaxZ)
140 myBndBox = Select3D_BndBox3d (SelectMgr_Vec3 (theMinX, theMinY, theMinZ),
141 SelectMgr_Vec3 (theMaxX, theMaxY, theMaxZ));
142 if (!myGroups.IsNull())
144 for (Select3D_PrimArraySubGroupArray::Iterator aGroupIter (*myGroups); aGroupIter.More(); aGroupIter.Next())
146 aGroupIter.Value()->myBndBox = myBndBox;
151 //! Return flag to keep index of last topmost detected element, TRUE by default.
152 bool ToDetectElements() const { return myToDetectElem; }
154 //! Setup keeping of the index of last topmost detected element (axis picking).
155 void SetDetectElements (bool theToDetect) { myToDetectElem = theToDetect; }
157 //! Return flag to keep index map of last detected elements, FALSE by default (rectangle selection).
158 bool ToDetectElementMap() const { return !myDetectedElemMap.IsNull(); }
160 //! Setup keeping of the index map of last detected elements (rectangle selection).
161 Standard_EXPORT void SetDetectElementMap (bool theToDetect);
163 //! Return flag to keep index of last topmost detected node, FALSE by default.
164 bool ToDetectNodes() const { return myToDetectNode; }
166 //! Setup keeping of the index of last topmost detected node (for axis picking).
167 void SetDetectNodes (bool theToDetect) { myToDetectNode = theToDetect; }
169 //! Return flag to keep index map of last detected nodes, FALSE by default (rectangle selection).
170 bool ToDetectNodeMap() const { return !myDetectedNodeMap.IsNull(); }
172 //! Setup keeping of the index map of last detected nodes (rectangle selection).
173 Standard_EXPORT void SetDetectNodeMap (bool theToDetect);
175 //! Return flag to keep index of last topmost detected edge, FALSE by default.
176 bool ToDetectEdges() const { return myToDetectEdge; }
178 //! Setup keeping of the index of last topmost detected edge (axis picking).
179 void SetDetectEdges (bool theToDetect) { myToDetectEdge = theToDetect; }
181 //! Return last topmost detected element or -1 if undefined (axis picking).
182 Standard_Integer LastDetectedElement() const { return myDetectedElem; }
184 //! Return the index map of last detected elements (rectangle selection).
185 const Handle(TColStd_HPackedMapOfInteger)& LastDetectedElementMap() const { return myDetectedElemMap; }
187 //! Return last topmost detected node or -1 if undefined (axis picking).
188 Standard_Integer LastDetectedNode() const { return myDetectedNode; }
190 //! Return the index map of last detected nodes (rectangle selection).
191 const Handle(TColStd_HPackedMapOfInteger)& LastDetectedNodeMap() const { return myDetectedNodeMap; }
193 //! Return the first node of last topmost detected edge or -1 if undefined (axis picking).
194 Standard_Integer LastDetectedEdgeNode1() const { return myDetectedEdgeNode1; }
196 //! Return the second node of last topmost detected edge or -1 if undefined (axis picking).
197 Standard_Integer LastDetectedEdgeNode2() const { return myDetectedEdgeNode2; }
201 //! Checks whether the sensitive entity is overlapped by current selecting volume.
202 Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
203 SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
205 Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
207 //! Returns the length of array of triangles or edges
208 Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
210 //! Returns the amount of nodes in triangulation
211 virtual Standard_Integer NbSubElements() Standard_OVERRIDE
213 return !myGroups.IsNull() ? myGroups->Size() : myBvhIndices.NbElements;
216 //! Returns bounding box of triangle/edge with index theIdx
217 Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
219 //! Returns geometry center of triangle/edge with index theIdx
220 //! in array along the given axis theAxis
221 Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
222 const Standard_Integer theAxis) const Standard_OVERRIDE;
224 //! Swaps items with indexes theIdx1 and theIdx2 in array
225 Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
226 const Standard_Integer theIdx2) Standard_OVERRIDE;
228 //! Returns bounding box of the triangulation. If location
229 //! transformation is set, it will be applied
230 Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
232 //! Returns center of triangulation. If location transformation
233 //! is set, it will be applied
234 virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE
239 //! Returns true if the shape corresponding to the entity has init location
240 virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE
242 return !myInitLocation.IsIdentity();
245 //! Returns inversed location transformation matrix if the shape corresponding
246 //! to this entity has init location set. Otherwise, returns identity matrix.
247 virtual gp_GTrsf InvInitLocation() const Standard_OVERRIDE
249 return myInvInitLocation;
252 //! Sets the owner for all entities in group
253 Standard_EXPORT virtual void Set (const Handle(SelectBasics_EntityOwner)& theOwnerId) Standard_OVERRIDE;
255 //! Builds BVH tree for sensitive set.
256 Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
260 //! Compute bounding box.
261 Standard_EXPORT void computeBoundingBox();
263 //! Inner function for transformation application to bounding
264 //! box of the triangulation
265 Standard_EXPORT Select3D_BndBox3d applyTransformation();
267 //! Auxiliary getter.
268 const Graphic3d_Vec3& getPosVec3 (const Standard_Integer theIndex) const
270 return *reinterpret_cast<const Graphic3d_Vec3* >(myVerts->value (theIndex) + myPosOffset);
273 //! Auxiliary getter.
274 const Graphic3d_Vec2& getPosVec2 (const Standard_Integer theIndex) const
276 return *reinterpret_cast<const Graphic3d_Vec2* >(myVerts->value (theIndex) + myPosOffset);
279 //! Checks whether the element with index theIdx overlaps the current selecting volume
280 Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
281 Standard_Integer theElemIdx,
282 Standard_Real& theMatchDepth) Standard_OVERRIDE;
284 //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
285 Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
287 //! Checks whether the entity with index theIdx is inside the current selecting volume
288 Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
289 const Standard_Integer theElemIdx) Standard_OVERRIDE;
293 typedef NCollection_Shared<NCollection_Array1<Handle(Select3D_SensitivePrimitiveArray)> > Select3D_PrimArraySubGroupArray;
294 struct Select3D_SensitivePrimitiveArray_InitFunctor;
295 struct Select3D_SensitivePrimitiveArray_BVHFunctor;
299 Handle(Select3D_PrimArraySubGroupArray) myGroups; //!< sub-groups of sensitive entities
301 Handle(Graphic3d_Buffer) myVerts; //!< source data - nodes position
302 Handle(Graphic3d_IndexBuffer) myIndices; //!< source data - primitive indexes
303 Graphic3d_TypeOfPrimitiveArray myPrimType; //!< primitives type
304 Standard_Integer myIndexLower; //!< index range - first index in myIndices (inclusive)
305 Standard_Integer myIndexUpper; //!< index range - last index in myIndices (inclusive)
306 Standard_Size myPosOffset; //!< offset to the position vertex attribute
307 Standard_Integer myPatchSizeMax; //!< patch size limit (1 by default)
308 float myPatchDistance; //!< distance between elements in patch
309 bool myIs3d; //!< flag indicating that position attribute has 3 components
310 TopLoc_Location myInitLocation;
311 gp_Pnt myCDG3D; //!< Center of the whole triangulation
312 Select3D_BVHIndexBuffer myBvhIndices; //!< Indexes of edges or triangles for BVH tree
313 mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
314 gp_GTrsf myInvInitLocation;
315 Handle(TColStd_HPackedMapOfInteger) myDetectedElemMap; //!< index map of last detected elements
316 Handle(TColStd_HPackedMapOfInteger) myDetectedNodeMap; //!< index map of last detected nodes
317 Standard_Real myMinDepthElem; //!< the depth of nearest detected element
318 Standard_Real myMinDepthNode; //!< the depth of nearest detected node
319 Standard_Real myMinDepthEdge; //!< the depth of nearest detected edge
320 Standard_Integer myDetectedElem; //!< index of last detected element
321 Standard_Integer myDetectedNode; //!< index of last detected node
322 Standard_Integer myDetectedEdgeNode1; //!< index of last detected edge node 1
323 Standard_Integer myDetectedEdgeNode2; //!< index of last detected edge node 2
324 bool myToDetectElem; //!< flag to keep info about last detected element
325 bool myToDetectNode; //!< flag to keep info about last detected node
326 bool myToDetectEdge; //!< flag to keep info about last detected edge
330 DEFINE_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
334 DEFINE_STANDARD_HANDLE(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
336 #endif // _Select3D_SensitivePrimitiveArray_Header