0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / Select3D / Select3D_SensitivePrimitiveArray.hxx
CommitLineData
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.
30class Select3D_SensitivePrimitiveArray : public Select3D_SensitiveSet
31{
32
33public:
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
bc73b006 200 //! Dumps the content of me into the stream
201 Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
202
8b9a309b 203public:
204
205 //! Checks whether the sensitive entity is overlapped by current selecting volume.
206 Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
207 SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
208
209 Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
210
211 //! Returns the length of array of triangles or edges
212 Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
213
214 //! Returns the amount of nodes in triangulation
fe758dbe 215 virtual Standard_Integer NbSubElements() const Standard_OVERRIDE
8b9a309b 216 {
a228288f 217 return !myGroups.IsNull() ? myGroups->Size() : myBvhIndices.NbElements;
8b9a309b 218 }
219
220 //! Returns bounding box of triangle/edge with index theIdx
221 Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
222
223 //! Returns geometry center of triangle/edge with index theIdx
224 //! in array along the given axis theAxis
225 Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
226 const Standard_Integer theAxis) const Standard_OVERRIDE;
227
228 //! Swaps items with indexes theIdx1 and theIdx2 in array
229 Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
230 const Standard_Integer theIdx2) Standard_OVERRIDE;
231
232 //! Returns bounding box of the triangulation. If location
233 //! transformation is set, it will be applied
234 Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
235
236 //! Returns center of triangulation. If location transformation
237 //! is set, it will be applied
238 virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE
239 {
240 return myCDG3D;
241 }
242
243 //! Returns true if the shape corresponding to the entity has init location
244 virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE
245 {
246 return !myInitLocation.IsIdentity();
247 }
248
249 //! Returns inversed location transformation matrix if the shape corresponding
250 //! to this entity has init location set. Otherwise, returns identity matrix.
91d96372 251 virtual gp_GTrsf InvInitLocation() const Standard_OVERRIDE
8b9a309b 252 {
253 return myInvInitLocation;
254 }
255
a228288f 256 //! Sets the owner for all entities in group
0ef04197 257 Standard_EXPORT virtual void Set (const Handle(SelectMgr_EntityOwner)& theOwnerId) Standard_OVERRIDE;
a228288f 258
259 //! Builds BVH tree for sensitive set.
260 Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
261
8b9a309b 262protected:
263
264 //! Compute bounding box.
265 Standard_EXPORT void computeBoundingBox();
266
267 //! Inner function for transformation application to bounding
268 //! box of the triangulation
269 Standard_EXPORT Select3D_BndBox3d applyTransformation();
270
271 //! Auxiliary getter.
272 const Graphic3d_Vec3& getPosVec3 (const Standard_Integer theIndex) const
273 {
da87ddc3 274 return *reinterpret_cast<const Graphic3d_Vec3* >(myPosData + myPosStride * theIndex);
8b9a309b 275 }
276
277 //! Auxiliary getter.
278 const Graphic3d_Vec2& getPosVec2 (const Standard_Integer theIndex) const
279 {
da87ddc3 280 return *reinterpret_cast<const Graphic3d_Vec2* >(myPosData + myPosStride * theIndex);
8b9a309b 281 }
282
283 //! Checks whether the element with index theIdx overlaps the current selecting volume
4a056d20 284 Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
285 SelectBasics_SelectingVolumeManager& theMgr,
8b9a309b 286 Standard_Integer theElemIdx,
4a056d20 287 Standard_Boolean theIsFullInside) Standard_OVERRIDE;
8b9a309b 288
289 //! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
290 Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
291
292 //! Checks whether the entity with index theIdx is inside the current selecting volume
293 Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
4a056d20 294 Standard_Integer theElemIdx,
295 Standard_Boolean theIsFullInside) Standard_OVERRIDE;
8b9a309b 296
297private:
298
a228288f 299 typedef NCollection_Shared<NCollection_Array1<Handle(Select3D_SensitivePrimitiveArray)> > Select3D_PrimArraySubGroupArray;
300 struct Select3D_SensitivePrimitiveArray_InitFunctor;
301 struct Select3D_SensitivePrimitiveArray_BVHFunctor;
302
303private:
304
305 Handle(Select3D_PrimArraySubGroupArray) myGroups; //!< sub-groups of sensitive entities
306
307 Handle(Graphic3d_Buffer) myVerts; //!< source data - nodes position
308 Handle(Graphic3d_IndexBuffer) myIndices; //!< source data - primitive indexes
da87ddc3 309 const Standard_Byte* myPosData; //!< position vertex attribute data
310 Standard_Size myPosStride; //!< position vertex attribute stride in bytes
a228288f 311 Graphic3d_TypeOfPrimitiveArray myPrimType; //!< primitives type
312 Standard_Integer myIndexLower; //!< index range - first index in myIndices (inclusive)
313 Standard_Integer myIndexUpper; //!< index range - last index in myIndices (inclusive)
a228288f 314 Standard_Integer myPatchSizeMax; //!< patch size limit (1 by default)
315 float myPatchDistance; //!< distance between elements in patch
316 bool myIs3d; //!< flag indicating that position attribute has 3 components
317 TopLoc_Location myInitLocation;
318 gp_Pnt myCDG3D; //!< Center of the whole triangulation
319 Select3D_BVHIndexBuffer myBvhIndices; //!< Indexes of edges or triangles for BVH tree
320 mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
321 gp_GTrsf myInvInitLocation;
322 Handle(TColStd_HPackedMapOfInteger) myDetectedElemMap; //!< index map of last detected elements
323 Handle(TColStd_HPackedMapOfInteger) myDetectedNodeMap; //!< index map of last detected nodes
324 Standard_Real myMinDepthElem; //!< the depth of nearest detected element
325 Standard_Real myMinDepthNode; //!< the depth of nearest detected node
326 Standard_Real myMinDepthEdge; //!< the depth of nearest detected edge
327 Standard_Integer myDetectedElem; //!< index of last detected element
328 Standard_Integer myDetectedNode; //!< index of last detected node
329 Standard_Integer myDetectedEdgeNode1; //!< index of last detected edge node 1
330 Standard_Integer myDetectedEdgeNode2; //!< index of last detected edge node 2
331 bool myToDetectElem; //!< flag to keep info about last detected element
332 bool myToDetectNode; //!< flag to keep info about last detected node
333 bool myToDetectEdge; //!< flag to keep info about last detected edge
8b9a309b 334
335public:
336
337 DEFINE_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
338
339};
340
341DEFINE_STANDARD_HANDLE(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
342
343#endif // _Select3D_SensitivePrimitiveArray_Header