8b9a309b |
1 | // Created on: 2016-02-20 |
2 | // Created by: Kirill Gavrilov |
3 | // Copyright (c) 2016 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
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. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | #ifndef _Select3D_SensitivePrimitiveArray_Header |
17 | #define _Select3D_SensitivePrimitiveArray_Header |
18 | |
19 | #include <Graphic3d_Buffer.hxx> |
20 | #include <Graphic3d_IndexBuffer.hxx> |
21 | #include <Graphic3d_TypeOfPrimitiveArray.hxx> |
25c35042 |
22 | #include <NCollection_Shared.hxx> |
8b9a309b |
23 | #include <Select3D_SensitiveSet.hxx> |
24 | #include <Select3D_BVHIndexBuffer.hxx> |
a228288f |
25 | #include <TColStd_HPackedMapOfInteger.hxx> |
8b9a309b |
26 | |
27 | //! Sensitive for triangulation or point set defined by Primitive Array. |
28 | //! The primitives can be optionally combined into patches within BVH tree |
29 | //! to reduce its building time in expense of extra traverse time. |
30 | class Select3D_SensitivePrimitiveArray : public Select3D_SensitiveSet |
31 | { |
32 | |
33 | public: |
34 | |
35 | //! Constructs an empty sensitive object. |
0ef04197 |
36 | Standard_EXPORT Select3D_SensitivePrimitiveArray (const Handle(SelectMgr_EntityOwner)& theOwnerId); |
8b9a309b |
37 | |
38 | //! Return patch size limit (1 by default). |
39 | Standard_Integer PatchSizeMax() const { return myPatchSizeMax; } |
40 | |
41 | //! Assign patch size limit. |
42 | //! Should be set before initialization. |
43 | void SetPatchSizeMax (const Standard_Integer thePatchSizeMax) { myPatchSizeMax = thePatchSizeMax; } |
44 | |
45 | //! Maximum allowed distance between consequential elements in patch (ShortRealLast() by default). |
46 | //! Has no effect on indexed triangulation. |
47 | float PatchDistance() const { return myPatchDistance; } |
48 | |
49 | //! Assign patch distance limit. |
50 | //! Should be set before initialization. |
51 | void SetPatchDistance (const float thePatchDistMax) { myPatchDistance = thePatchDistMax; } |
52 | |
53 | //! Initialize the sensitive object from triangualtion. |
54 | //! The sub-triangulation can be specified by arguments theIndexLower and theIndexUpper |
55 | //! (these are for iterating theIndices, not to restrict the actual index values!). |
56 | //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2 |
57 | //! @param theIndices index array defining triangulation |
58 | //! @param theInitLoc location |
59 | //! @param theIndexLower the theIndices range - first value (inclusive), starting from 0 and multiple by 3 |
60 | //! @param theIndexUpper the theIndices range - last value (inclusive), upto theIndices->NbElements-1 and multiple by 3 |
61 | //! @param theToEvalMinMax compute bounding box within initialization |
a228288f |
62 | //! @param theNbGroups number of groups to split the vertex array into several parts |
8b9a309b |
63 | Standard_EXPORT bool InitTriangulation (const Handle(Graphic3d_Buffer)& theVerts, |
64 | const Handle(Graphic3d_IndexBuffer)& theIndices, |
65 | const TopLoc_Location& theInitLoc, |
66 | const Standard_Integer theIndexLower, |
67 | const Standard_Integer theIndexUpper, |
a228288f |
68 | const bool theToEvalMinMax = true, |
69 | const Standard_Integer theNbGroups = 1); |
8b9a309b |
70 | |
71 | //! Initialize the sensitive object from triangualtion. |
72 | //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2 |
73 | //! @param theIndices index array defining triangulation |
74 | //! @param theInitLoc location |
75 | //! @param theToEvalMinMax compute bounding box within initialization |
a228288f |
76 | //! @param theNbGroups number of groups to split the vertex array into several parts |
8b9a309b |
77 | bool InitTriangulation (const Handle(Graphic3d_Buffer)& theVerts, |
78 | const Handle(Graphic3d_IndexBuffer)& theIndices, |
79 | const TopLoc_Location& theInitLoc, |
a228288f |
80 | const bool theToEvalMinMax = true, |
81 | const Standard_Integer theNbGroups = 1) |
8b9a309b |
82 | { |
83 | const Standard_Integer anUpper = !theIndices.IsNull() ? (theIndices->NbElements - 1) |
84 | : (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0); |
a228288f |
85 | return InitTriangulation (theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups); |
8b9a309b |
86 | } |
87 | |
88 | //! Initialize the sensitive object from point set. |
89 | //! The sub-set of points can be specified by arguments theIndexLower and theIndexUpper |
90 | //! (these are for iterating theIndices, not to restrict the actual index values!). |
91 | //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2 |
92 | //! @param theIndices index array defining points |
93 | //! @param theInitLoc location |
94 | //! @param theIndexLower the theIndices range - first value (inclusive), starting from 0 |
95 | //! @param theIndexUpper the theIndices range - last value (inclusive), upto theIndices->NbElements-1 |
96 | //! @param theToEvalMinMax compute bounding box within initialization |
a228288f |
97 | //! @param theNbGroups number of groups to split the vertex array into several parts |
8b9a309b |
98 | Standard_EXPORT bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts, |
99 | const Handle(Graphic3d_IndexBuffer)& theIndices, |
100 | const TopLoc_Location& theInitLoc, |
101 | const Standard_Integer theIndexLower, |
102 | const Standard_Integer theIndexUpper, |
a228288f |
103 | const bool theToEvalMinMax = true, |
104 | const Standard_Integer theNbGroups = 1); |
8b9a309b |
105 | |
106 | //! Initialize the sensitive object from point set. |
107 | //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2 |
108 | //! @param theIndices index array to define subset of points |
109 | //! @param theInitLoc location |
110 | //! @param theToEvalMinMax compute bounding box within initialization |
a228288f |
111 | //! @param theNbGroups number of groups to split the vertex array into several parts |
8b9a309b |
112 | bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts, |
113 | const Handle(Graphic3d_IndexBuffer)& theIndices, |
114 | const TopLoc_Location& theInitLoc, |
a228288f |
115 | const bool theToEvalMinMax = true, |
116 | const Standard_Integer theNbGroups = 1) |
8b9a309b |
117 | { |
118 | const Standard_Integer anUpper = !theIndices.IsNull() ? (theIndices->NbElements - 1) |
119 | : (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0); |
a228288f |
120 | return InitPoints (theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups); |
8b9a309b |
121 | } |
122 | |
123 | //! Initialize the sensitive object from point set. |
124 | //! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2 |
125 | //! @param theInitLoc location |
126 | //! @param theToEvalMinMax compute bounding box within initialization |
a228288f |
127 | //! @param theNbGroups number of groups to split the vertex array into several parts |
8b9a309b |
128 | bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts, |
129 | const TopLoc_Location& theInitLoc, |
a228288f |
130 | const bool theToEvalMinMax = true, |
131 | const Standard_Integer theNbGroups = 1) |
8b9a309b |
132 | { |
133 | const Standard_Integer anUpper = !theVerts.IsNull() ? (theVerts->NbElements - 1) : 0; |
a228288f |
134 | return InitPoints (theVerts, Handle(Graphic3d_IndexBuffer)(), theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups); |
8b9a309b |
135 | } |
136 | |
137 | //! Assign new not transformed bounding box. |
138 | void SetMinMax (double theMinX, double theMinY, double theMinZ, |
139 | double theMaxX, double theMaxY, double theMaxZ) |
140 | { |
141 | myBndBox = Select3D_BndBox3d (SelectMgr_Vec3 (theMinX, theMinY, theMinZ), |
142 | SelectMgr_Vec3 (theMaxX, theMaxY, theMaxZ)); |
a228288f |
143 | if (!myGroups.IsNull()) |
144 | { |
145 | for (Select3D_PrimArraySubGroupArray::Iterator aGroupIter (*myGroups); aGroupIter.More(); aGroupIter.Next()) |
146 | { |
147 | aGroupIter.Value()->myBndBox = myBndBox; |
148 | } |
149 | } |
8b9a309b |
150 | } |
151 | |
a228288f |
152 | //! Return flag to keep index of last topmost detected element, TRUE by default. |
8b9a309b |
153 | bool ToDetectElements() const { return myToDetectElem; } |
154 | |
a228288f |
155 | //! Setup keeping of the index of last topmost detected element (axis picking). |
8b9a309b |
156 | void SetDetectElements (bool theToDetect) { myToDetectElem = theToDetect; } |
157 | |
a228288f |
158 | //! Return flag to keep index map of last detected elements, FALSE by default (rectangle selection). |
159 | bool ToDetectElementMap() const { return !myDetectedElemMap.IsNull(); } |
160 | |
161 | //! Setup keeping of the index map of last detected elements (rectangle selection). |
162 | Standard_EXPORT void SetDetectElementMap (bool theToDetect); |
163 | |
164 | //! Return flag to keep index of last topmost detected node, FALSE by default. |
8b9a309b |
165 | bool ToDetectNodes() const { return myToDetectNode; } |
166 | |
a228288f |
167 | //! Setup keeping of the index of last topmost detected node (for axis picking). |
8b9a309b |
168 | void SetDetectNodes (bool theToDetect) { myToDetectNode = theToDetect; } |
169 | |
a228288f |
170 | //! Return flag to keep index map of last detected nodes, FALSE by default (rectangle selection). |
171 | bool ToDetectNodeMap() const { return !myDetectedNodeMap.IsNull(); } |
172 | |
173 | //! Setup keeping of the index map of last detected nodes (rectangle selection). |
174 | Standard_EXPORT void SetDetectNodeMap (bool theToDetect); |
175 | |
176 | //! Return flag to keep index of last topmost detected edge, FALSE by default. |
8b9a309b |
177 | bool ToDetectEdges() const { return myToDetectEdge; } |
178 | |
a228288f |
179 | //! Setup keeping of the index of last topmost detected edge (axis picking). |
8b9a309b |
180 | void SetDetectEdges (bool theToDetect) { myToDetectEdge = theToDetect; } |
181 | |
a228288f |
182 | //! Return last topmost detected element or -1 if undefined (axis picking). |
8b9a309b |
183 | Standard_Integer LastDetectedElement() const { return myDetectedElem; } |
184 | |
a228288f |
185 | //! Return the index map of last detected elements (rectangle selection). |
186 | const Handle(TColStd_HPackedMapOfInteger)& LastDetectedElementMap() const { return myDetectedElemMap; } |
187 | |
188 | //! Return last topmost detected node or -1 if undefined (axis picking). |
8b9a309b |
189 | Standard_Integer LastDetectedNode() const { return myDetectedNode; } |
190 | |
a228288f |
191 | //! Return the index map of last detected nodes (rectangle selection). |
192 | const Handle(TColStd_HPackedMapOfInteger)& LastDetectedNodeMap() const { return myDetectedNodeMap; } |
193 | |
194 | //! Return the first node of last topmost detected edge or -1 if undefined (axis picking). |
8b9a309b |
195 | Standard_Integer LastDetectedEdgeNode1() const { return myDetectedEdgeNode1; } |
196 | |
a228288f |
197 | //! Return the second node of last topmost detected edge or -1 if undefined (axis picking). |
8b9a309b |
198 | Standard_Integer LastDetectedEdgeNode2() const { return myDetectedEdgeNode2; } |
199 | |
200 | public: |
201 | |
202 | //! Checks whether the sensitive entity is overlapped by current selecting volume. |
203 | Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, |
204 | SelectBasics_PickResult& thePickResult) Standard_OVERRIDE; |
205 | |
206 | Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE; |
207 | |
208 | //! Returns the length of array of triangles or edges |
209 | Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; |
210 | |
211 | //! Returns the amount of nodes in triangulation |
212 | virtual Standard_Integer NbSubElements() Standard_OVERRIDE |
213 | { |
a228288f |
214 | return !myGroups.IsNull() ? myGroups->Size() : myBvhIndices.NbElements; |
8b9a309b |
215 | } |
216 | |
217 | //! Returns bounding box of triangle/edge with index theIdx |
218 | Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE; |
219 | |
220 | //! Returns geometry center of triangle/edge with index theIdx |
221 | //! in array along the given axis theAxis |
222 | Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx, |
223 | const Standard_Integer theAxis) const Standard_OVERRIDE; |
224 | |
225 | //! Swaps items with indexes theIdx1 and theIdx2 in array |
226 | Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1, |
227 | const Standard_Integer theIdx2) Standard_OVERRIDE; |
228 | |
229 | //! Returns bounding box of the triangulation. If location |
230 | //! transformation is set, it will be applied |
231 | Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE; |
232 | |
233 | //! Returns center of triangulation. If location transformation |
234 | //! is set, it will be applied |
235 | virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE |
236 | { |
237 | return myCDG3D; |
238 | } |
239 | |
240 | //! Returns true if the shape corresponding to the entity has init location |
241 | virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE |
242 | { |
243 | return !myInitLocation.IsIdentity(); |
244 | } |
245 | |
246 | //! Returns inversed location transformation matrix if the shape corresponding |
247 | //! to this entity has init location set. Otherwise, returns identity matrix. |
91d96372 |
248 | virtual gp_GTrsf InvInitLocation() const Standard_OVERRIDE |
8b9a309b |
249 | { |
250 | return myInvInitLocation; |
251 | } |
252 | |
a228288f |
253 | //! Sets the owner for all entities in group |
0ef04197 |
254 | Standard_EXPORT virtual void Set (const Handle(SelectMgr_EntityOwner)& theOwnerId) Standard_OVERRIDE; |
a228288f |
255 | |
256 | //! Builds BVH tree for sensitive set. |
257 | Standard_EXPORT virtual void BVH() Standard_OVERRIDE; |
258 | |
8b9a309b |
259 | protected: |
260 | |
261 | //! Compute bounding box. |
262 | Standard_EXPORT void computeBoundingBox(); |
263 | |
264 | //! Inner function for transformation application to bounding |
265 | //! box of the triangulation |
266 | Standard_EXPORT Select3D_BndBox3d applyTransformation(); |
267 | |
268 | //! Auxiliary getter. |
269 | const Graphic3d_Vec3& getPosVec3 (const Standard_Integer theIndex) const |
270 | { |
da87ddc3 |
271 | return *reinterpret_cast<const Graphic3d_Vec3* >(myPosData + myPosStride * theIndex); |
8b9a309b |
272 | } |
273 | |
274 | //! Auxiliary getter. |
275 | const Graphic3d_Vec2& getPosVec2 (const Standard_Integer theIndex) const |
276 | { |
da87ddc3 |
277 | return *reinterpret_cast<const Graphic3d_Vec2* >(myPosData + myPosStride * theIndex); |
8b9a309b |
278 | } |
279 | |
280 | //! Checks whether the element with index theIdx overlaps the current selecting volume |
4a056d20 |
281 | Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult, |
282 | SelectBasics_SelectingVolumeManager& theMgr, |
8b9a309b |
283 | Standard_Integer theElemIdx, |
4a056d20 |
284 | Standard_Boolean theIsFullInside) Standard_OVERRIDE; |
8b9a309b |
285 | |
286 | //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry |
287 | Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE; |
288 | |
289 | //! Checks whether the entity with index theIdx is inside the current selecting volume |
290 | Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr, |
4a056d20 |
291 | Standard_Integer theElemIdx, |
292 | Standard_Boolean theIsFullInside) Standard_OVERRIDE; |
8b9a309b |
293 | |
294 | private: |
295 | |
a228288f |
296 | typedef NCollection_Shared<NCollection_Array1<Handle(Select3D_SensitivePrimitiveArray)> > Select3D_PrimArraySubGroupArray; |
297 | struct Select3D_SensitivePrimitiveArray_InitFunctor; |
298 | struct Select3D_SensitivePrimitiveArray_BVHFunctor; |
299 | |
300 | private: |
301 | |
302 | Handle(Select3D_PrimArraySubGroupArray) myGroups; //!< sub-groups of sensitive entities |
303 | |
304 | Handle(Graphic3d_Buffer) myVerts; //!< source data - nodes position |
305 | Handle(Graphic3d_IndexBuffer) myIndices; //!< source data - primitive indexes |
da87ddc3 |
306 | const Standard_Byte* myPosData; //!< position vertex attribute data |
307 | Standard_Size myPosStride; //!< position vertex attribute stride in bytes |
a228288f |
308 | Graphic3d_TypeOfPrimitiveArray myPrimType; //!< primitives type |
309 | Standard_Integer myIndexLower; //!< index range - first index in myIndices (inclusive) |
310 | Standard_Integer myIndexUpper; //!< index range - last index in myIndices (inclusive) |
a228288f |
311 | Standard_Integer myPatchSizeMax; //!< patch size limit (1 by default) |
312 | float myPatchDistance; //!< distance between elements in patch |
313 | bool myIs3d; //!< flag indicating that position attribute has 3 components |
314 | TopLoc_Location myInitLocation; |
315 | gp_Pnt myCDG3D; //!< Center of the whole triangulation |
316 | Select3D_BVHIndexBuffer myBvhIndices; //!< Indexes of edges or triangles for BVH tree |
317 | mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation |
318 | gp_GTrsf myInvInitLocation; |
319 | Handle(TColStd_HPackedMapOfInteger) myDetectedElemMap; //!< index map of last detected elements |
320 | Handle(TColStd_HPackedMapOfInteger) myDetectedNodeMap; //!< index map of last detected nodes |
321 | Standard_Real myMinDepthElem; //!< the depth of nearest detected element |
322 | Standard_Real myMinDepthNode; //!< the depth of nearest detected node |
323 | Standard_Real myMinDepthEdge; //!< the depth of nearest detected edge |
324 | Standard_Integer myDetectedElem; //!< index of last detected element |
325 | Standard_Integer myDetectedNode; //!< index of last detected node |
326 | Standard_Integer myDetectedEdgeNode1; //!< index of last detected edge node 1 |
327 | Standard_Integer myDetectedEdgeNode2; //!< index of last detected edge node 2 |
328 | bool myToDetectElem; //!< flag to keep info about last detected element |
329 | bool myToDetectNode; //!< flag to keep info about last detected node |
330 | bool myToDetectEdge; //!< flag to keep info about last detected edge |
8b9a309b |
331 | |
332 | public: |
333 | |
334 | DEFINE_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet) |
335 | |
336 | }; |
337 | |
338 | DEFINE_STANDARD_HANDLE(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet) |
339 | |
340 | #endif // _Select3D_SensitivePrimitiveArray_Header |