0027202: Visualization - add sensitivity Select3D_SensitivePrimitiveArray for Graphic...
[occt.git] / src / Select3D / Select3D_SensitiveSet.cxx
CommitLineData
f751596e 1// Created on: 2014-05-29
2// Created by: Varvara POSKONINA
3// Copyright (c) 2005-2014 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#include <Select3D_SensitiveSet.hxx>
17#include <Select3D_BVHPrimitiveContent.hxx>
18
f751596e 19
92efcf78 20IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveSet,Select3D_SensitiveEntity)
21
f751596e 22//=======================================================================
23// function : Select3D_SensitiveSet
24// purpose : Creates new empty sensitive set and its content
25//=======================================================================
26Select3D_SensitiveSet::Select3D_SensitiveSet (const Handle(SelectBasics_EntityOwner)& theOwnerId)
27: Select3D_SensitiveEntity (theOwnerId)
28{
29 myDetectedIdx = -1;
30 myIsLeftChildQueuedFirst = Standard_False;
31 myContent = new Select3D_BVHPrimitiveContent (this);
32}
33
34//=======================================================================
35// function : BVH
36// purpose : Builds BVH tree for sensitive set
37//=======================================================================
38void Select3D_SensitiveSet::BVH()
39{
40 myContent->GetBVH();
41}
42
43//=======================================================================
44// function : Matches
45// purpose : Checks whether one or more entities of the set overlap
46// current selecting volume. Implements the traverse of BVH
47// tree built for the set
48//=======================================================================
49Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
50 SelectBasics_PickResult& thePickResult)
51{
2157d6ac 52 const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVH = myContent->GetBVH();
f751596e 53
2157d6ac 54 thePickResult = SelectBasics_PickResult (RealLast(), RealLast());
55
72080ae1 56 if (myContent->Size() < 1 || !theMgr.Overlaps (aBVH->MinPoint (0),
57 aBVH->MaxPoint (0)))
f751596e 58 {
59 return Standard_False;
60 }
61
62 Standard_Integer aStack[32];
2157d6ac 63 Standard_Integer aNode = 0;
f751596e 64 Standard_Integer aHead = -1;
2157d6ac 65
f751596e 66 Standard_Integer aMatchesNb = -1;
2157d6ac 67 Standard_Real aMinDepth = RealLast();
68
f751596e 69 for (;;)
70 {
2157d6ac 71 const BVH_Vec4i& aData = aBVH->NodeInfoBuffer()[aNode];
72
73 if (aData.x() == 0) // is inner node
f751596e 74 {
2157d6ac 75 const Standard_Integer aLftIdx = aData.y();
76 const Standard_Integer aRghIdx = aData.z();
77
78 Standard_Boolean isLftInside = Standard_True;
79 Standard_Boolean isRghInside = Standard_True;
80
81 Standard_Boolean toCheckLft = theMgr.Overlaps (aBVH->MinPoint (aLftIdx),
82 aBVH->MaxPoint (aLftIdx),
83 theMgr.IsOverlapAllowed() ? NULL : &isLftInside);
84
85 Standard_Boolean toCheckRgh = theMgr.Overlaps (aBVH->MinPoint (aRghIdx),
86 aBVH->MaxPoint (aRghIdx),
87 theMgr.IsOverlapAllowed() ? NULL : &isRghInside);
88
89 if (!theMgr.IsOverlapAllowed()) // inclusion test
f751596e 90 {
2157d6ac 91 if (!toCheckLft || !toCheckRgh)
92 {
93 return Standard_False; // no inclusion
94 }
95
96 toCheckLft &= !isLftInside;
97 toCheckRgh &= !isRghInside;
f751596e 98 }
2157d6ac 99
100 if (toCheckLft || toCheckRgh)
f751596e 101 {
2157d6ac 102 aNode = toCheckLft ? aLftIdx : aRghIdx;
103
104 if (toCheckLft && toCheckRgh)
105 {
106 aStack[++aHead] = aRghIdx;
107 }
f751596e 108 }
109 else
110 {
111 if (aHead < 0)
f751596e 112 break;
f751596e 113
2157d6ac 114 aNode = aStack[aHead--];
f751596e 115 }
116 }
117 else
118 {
2157d6ac 119 for (Standard_Integer anElemIdx = aData.y(); anElemIdx <= aData.z(); ++anElemIdx)
f751596e 120 {
2157d6ac 121 if (!theMgr.IsOverlapAllowed()) // inclusion test
f751596e 122 {
2157d6ac 123 if (!elementIsInside (theMgr, anElemIdx))
f751596e 124 {
2157d6ac 125 return Standard_False;
f751596e 126 }
2157d6ac 127 }
128 else // overlap test
129 {
8b9a309b 130 Standard_Real aCurrentDepth = aMinDepth;
2157d6ac 131
132 if (!overlapsElement (theMgr, anElemIdx, aCurrentDepth))
133 {
134 continue;
135 }
136
137 if (aMinDepth > aCurrentDepth)
138 {
139 aMinDepth = aCurrentDepth;
140 myDetectedIdx = anElemIdx;
141 }
142
143 ++aMatchesNb;
f751596e 144 }
145 }
2157d6ac 146
f751596e 147 if (aHead < 0)
f751596e 148 break;
f751596e 149
2157d6ac 150 aNode = aStack[aHead--];
f751596e 151 }
152 }
153
154 if (aMatchesNb != -1)
155 {
2157d6ac 156 thePickResult = SelectBasics_PickResult (aMinDepth, distanceToCOG (theMgr));
f751596e 157 }
158
2157d6ac 159 return !theMgr.IsOverlapAllowed() || aMatchesNb != -1;
f751596e 160}
161
162//=======================================================================
163// function : BoundingBox
164// purpose : This method should be redefined in Select3D_SensitiveSet
165// descendants
166//=======================================================================
167Select3D_BndBox3d Select3D_SensitiveSet::BoundingBox()
168{
169 return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast()),
170 SelectMgr_Vec3 (RealFirst()));
171}
172
173//=======================================================================
174// function : CenterOfGeometry
175// purpose : This method should be redefined in Select3D_SensitiveSet
176// descendants
177//=======================================================================
178gp_Pnt Select3D_SensitiveSet::CenterOfGeometry() const
179{
180 return gp_Pnt (RealLast(), RealLast(), RealLast());
181}
182
183//=======================================================================
184// function : MarkDirty
185// purpose : Marks BVH tree of the set as outdated. It will be rebuild
186// at the next call of BVH()
187//=======================================================================
188void Select3D_SensitiveSet::MarkDirty()
189{
190 myContent->MarkDirty();
191}
192
193//=======================================================================
194// function : Clear
195// purpose : Destroys cross-reference to avoid memory leak
196//=======================================================================
197void Select3D_SensitiveSet::Clear()
198{
199 myContent.Nullify();
200}
2157d6ac 201
202//=======================================================================
203// function : GetLeafNodeSize
204// purpose : Returns a number of nodes in 1 BVH leaf
205//=======================================================================
206Standard_Integer Select3D_SensitiveSet::GetLeafNodeSize() const
207{
208 return myContent->GetLeafNodeSize();
209}