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