b311480e |
1 | // Created on: 1995-02-15 |
2 | // Created by: Roberc Coublanc |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
aa75c0cf |
17 | #include <SelectMgr_ViewerSelector.hxx> |
7fd59977 |
18 | |
f751596e |
19 | #include <BVH_Tree.hxx> |
91d96372 |
20 | #include <gp_GTrsf.hxx> |
7fd59977 |
21 | #include <gp_Pnt.hxx> |
f751596e |
22 | #include <OSD_Environment.hxx> |
7fd59977 |
23 | #include <Precision.hxx> |
4269bd1b |
24 | #include <SelectBasics_EntityOwner.hxx> |
7fd59977 |
25 | #include <SelectBasics_SensitiveEntity.hxx> |
f751596e |
26 | #include <SelectBasics_PickResult.hxx> |
27 | #include <SelectMgr_EntityOwner.hxx> |
7fd59977 |
28 | #include <SelectMgr_SortCriterion.hxx> |
f751596e |
29 | #include <SelectMgr_SensitiveEntitySet.hxx> |
f751596e |
30 | #include <TColStd_Array1OfInteger.hxx> |
31 | #include <TCollection_AsciiString.hxx> |
32 | #include <TColStd_HArray1OfInteger.hxx> |
33 | #include <TColStd_ListOfInteger.hxx> |
34 | |
e35db416 |
35 | #include <algorithm> |
36 | |
f5b72419 |
37 | IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient) |
92efcf78 |
38 | |
e35db416 |
39 | namespace { |
40 | // Comparison operator for sorting selection results |
41 | class CompareResults |
42 | { |
43 | public: |
44 | |
45 | CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion) |
46 | : myMapOfCriterion (aMapOfCriterion) |
47 | { |
48 | } |
49 | |
50 | Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const |
51 | { |
52 | return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight); |
53 | } |
54 | |
55 | private: |
56 | void operator = (const CompareResults&); |
57 | |
58 | private: |
59 | const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion; |
60 | }; |
f751596e |
61 | |
aa75c0cf |
62 | //! Compute 3d position for detected entity. |
63 | inline void updatePoint3d (SelectMgr_SortCriterion& theCriterion, |
64 | const gp_GTrsf& theInversedTrsf, |
65 | SelectMgr_SelectingVolumeManager& theMgr) |
4269bd1b |
66 | { |
949c9b7f |
67 | if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point) |
68 | { |
69 | return; |
70 | } |
71 | |
aa75c0cf |
72 | theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth); |
73 | gp_GTrsf anInvTrsf = theInversedTrsf; |
74 | if (theCriterion.Entity->HasInitLocation()) |
f751596e |
75 | { |
aa75c0cf |
76 | anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf; |
f751596e |
77 | } |
aa75c0cf |
78 | if (anInvTrsf.Form() != gp_Identity) |
f751596e |
79 | { |
aa75c0cf |
80 | anInvTrsf.Inverted().Transforms (theCriterion.Point.ChangeCoord()); |
4269bd1b |
81 | } |
f751596e |
82 | } |
aa75c0cf |
83 | |
896faa72 |
84 | static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT; |
f751596e |
85 | } |
86 | |
7fd59977 |
87 | //================================================== |
88 | // Function: Initialize |
89 | // Purpose : |
90 | //================================================== |
91 | SelectMgr_ViewerSelector::SelectMgr_ViewerSelector(): |
7fd59977 |
92 | preferclosest(Standard_True), |
f751596e |
93 | myToUpdateTolerance (Standard_True), |
94 | myCurRank (0), |
95 | myIsLeftChildQueuedFirst (Standard_False), |
96 | myEntityIdx (0) |
7fd59977 |
97 | { |
f5b72419 |
98 | myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True); |
7fd59977 |
99 | } |
100 | |
7fd59977 |
101 | //================================================== |
102 | // Function: Activate |
103 | // Purpose : |
104 | //================================================== |
f751596e |
105 | void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection) |
7fd59977 |
106 | { |
f751596e |
107 | for (theSelection->Init(); theSelection->More(); theSelection->Next()) |
7fd59977 |
108 | { |
f751596e |
109 | theSelection->Sensitive()->SetActiveForSelection(); |
4269bd1b |
110 | } |
7fd59977 |
111 | |
f751596e |
112 | theSelection->SetSelectionState (SelectMgr_SOS_Activated); |
7fd59977 |
113 | |
f751596e |
114 | myTolerances.Add (theSelection->Sensitivity()); |
f751596e |
115 | myToUpdateTolerance = Standard_True; |
7fd59977 |
116 | } |
117 | |
7fd59977 |
118 | //================================================== |
f751596e |
119 | // Function: Deactivate |
7fd59977 |
120 | // Purpose : |
121 | //================================================== |
f751596e |
122 | void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection) |
4269bd1b |
123 | { |
f751596e |
124 | for (theSelection->Init(); theSelection->More(); theSelection->Next()) |
125 | { |
126 | theSelection->Sensitive()->ResetSelectionActiveStatus(); |
7fd59977 |
127 | } |
7fd59977 |
128 | |
f751596e |
129 | theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); |
7fd59977 |
130 | |
f751596e |
131 | myTolerances.Decrement (theSelection->Sensitivity()); |
f751596e |
132 | myToUpdateTolerance = Standard_True; |
7fd59977 |
133 | } |
134 | |
7fd59977 |
135 | //================================================== |
136 | // Function: Clear |
137 | // Purpose : |
138 | //================================================== |
139 | void SelectMgr_ViewerSelector::Clear() |
140 | { |
7fd59977 |
141 | mystored.Clear(); |
7fd59977 |
142 | } |
143 | |
28ee613b |
144 | //======================================================================= |
145 | // function: isToScaleFrustum |
146 | // purpose : Checks if the entity given requires to scale current selecting frustum |
147 | //======================================================================= |
148 | Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity) |
149 | { |
150 | return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point |
29a4908e |
151 | && sensitivity (theEntity) < myTolerances.Tolerance(); |
28ee613b |
152 | } |
153 | |
29a4908e |
154 | //======================================================================= |
155 | // function: sensitivity |
156 | // purpose : In case if custom tolerance is set, this method will return sum of entity |
157 | // sensitivity and custom tolerance. |
158 | //======================================================================= |
3bf9a45f |
159 | Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const |
29a4908e |
160 | { |
161 | return myTolerances.IsCustomTolSet() ? |
162 | theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor(); |
163 | } |
164 | |
f751596e |
165 | //======================================================================= |
166 | // function: checkOverlap |
167 | // purpose : Internal function that checks if a particular sensitive |
168 | // entity theEntity overlaps current selecting volume precisely |
169 | //======================================================================= |
170 | void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity, |
aa75c0cf |
171 | const gp_GTrsf& theInversedTrsf, |
f751596e |
172 | SelectMgr_SelectingVolumeManager& theMgr) |
7fd59977 |
173 | { |
c5f3a425 |
174 | Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId())); |
3202bf1e |
175 | Handle(SelectMgr_SelectableObject) aSelectable; |
176 | Standard_Boolean toRestoresViewClipEnabled = Standard_False; |
177 | if (!anOwner.IsNull()) |
178 | { |
179 | aSelectable = anOwner->Selectable(); |
8b1441e3 |
180 | if (!aSelectable->ClipPlanes().IsNull() |
181 | && aSelectable->ClipPlanes()->ToOverrideGlobal()) |
3202bf1e |
182 | { |
183 | theMgr.SetViewClippingEnabled (Standard_False); |
184 | toRestoresViewClipEnabled = Standard_True; |
185 | } |
8b1441e3 |
186 | else if (!aSelectable->TransformPersistence().IsNull()) |
187 | { |
188 | if (aSelectable->TransformPersistence()->IsZoomOrRotate() |
189 | && !theMgr.ViewClipping().IsNull()) |
190 | { |
191 | // Zoom/rotate persistence object lives in two worlds at the same time. |
192 | // Global clipping planes can not be trivially applied without being converted |
193 | // into local space of transformation persistence object. |
194 | // As more simple alternative - just clip entire object by its anchor point defined in the world space. |
195 | const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping(); |
196 | |
197 | const gp_Pnt anAnchor = aSelectable->TransformPersistence()->AnchorPoint(); |
198 | for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next()) |
199 | { |
200 | const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); |
201 | if (!aPlane->IsOn()) |
202 | { |
203 | continue; |
204 | } |
205 | |
206 | const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation(); |
207 | const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0); |
208 | if (aPlaneEquation.Dot (aCheckPnt) < 0.0) // vertex is outside the half-space |
209 | { |
210 | return; |
211 | } |
212 | } |
213 | } |
214 | |
215 | theMgr.SetViewClippingEnabled (Standard_False); |
216 | toRestoresViewClipEnabled = Standard_True; |
217 | } |
3202bf1e |
218 | } |
7fd59977 |
219 | |
f751596e |
220 | SelectBasics_PickResult aPickResult; |
3202bf1e |
221 | const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult); |
222 | if (toRestoresViewClipEnabled) |
f751596e |
223 | { |
3202bf1e |
224 | theMgr.SetViewClippingEnabled (Standard_True); |
225 | } |
7fd59977 |
226 | |
3202bf1e |
227 | if (!isMatched |
228 | || anOwner.IsNull()) |
229 | { |
230 | return; |
231 | } |
232 | |
233 | if (HasDepthClipping (anOwner) |
234 | && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point) |
235 | { |
236 | Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(), |
237 | aPickResult.Depth()); |
238 | if (isClipped) |
239 | return; |
240 | } |
241 | |
242 | SelectMgr_SortCriterion aCriterion; |
243 | myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition); |
244 | aCriterion.Entity = theEntity; |
245 | aCriterion.Priority = anOwner->Priority(); |
246 | aCriterion.Depth = aPickResult.Depth(); |
247 | aCriterion.MinDist = aPickResult.DistToGeomCenter(); |
248 | aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0; |
249 | aCriterion.ToPreferClosest = preferclosest; |
250 | |
251 | const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner); |
252 | if (aPrevStoredIndex != 0) |
253 | { |
254 | if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box) |
255 | { |
256 | SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex); |
257 | if (aCriterion > aPrevCriterion) |
f751596e |
258 | { |
aa75c0cf |
259 | updatePoint3d (aCriterion, theInversedTrsf, theMgr); |
3202bf1e |
260 | aPrevCriterion = aCriterion; |
7fd59977 |
261 | } |
262 | } |
7fd59977 |
263 | } |
3202bf1e |
264 | else |
265 | { |
266 | updatePoint3d (aCriterion, theInversedTrsf, theMgr); |
267 | mystored.Add (anOwner, aCriterion); |
268 | } |
7fd59977 |
269 | } |
270 | |
3bf9a45f |
271 | //======================================================================= |
272 | // function: computeFrustum |
273 | // purpose : Internal function that checks if a current selecting frustum |
274 | // needs to be scaled and transformed for the entity and performs |
275 | // necessary calculations |
276 | //======================================================================= |
277 | void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt, |
099f3513 |
278 | const SelectMgr_SelectingVolumeManager& theMgr, |
91d96372 |
279 | const gp_GTrsf& theInvTrsf, |
3bf9a45f |
280 | SelectMgr_FrustumCache& theCachedMgrs, |
281 | SelectMgr_SelectingVolumeManager& theResMgr) |
282 | { |
7479f643 |
283 | Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1; |
91d96372 |
284 | const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf; |
7479f643 |
285 | const Standard_Boolean toScale = aScale != 1; |
286 | const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity; |
287 | if (toScale && toTransform) |
3bf9a45f |
288 | { |
099f3513 |
289 | theResMgr = theMgr.ScaleAndTransform (aScale, aTrsfMtr, NULL); |
3bf9a45f |
290 | } |
291 | else if (toScale) |
292 | { |
293 | if (!theCachedMgrs.IsBound (aScale)) |
294 | { |
099f3513 |
295 | theCachedMgrs.Bind (aScale, theMgr.ScaleAndTransform (aScale, gp_Trsf(), NULL)); |
3bf9a45f |
296 | } |
3bf9a45f |
297 | theResMgr = theCachedMgrs.Find (aScale); |
298 | } |
7479f643 |
299 | else if (toTransform) |
300 | { |
099f3513 |
301 | theResMgr = theMgr.ScaleAndTransform (1, aTrsfMtr, NULL); |
7479f643 |
302 | } |
3bf9a45f |
303 | } |
304 | |
f751596e |
305 | //======================================================================= |
306 | // function: traverseObject |
307 | // purpose : Internal function that checks if there is possible overlap |
308 | // between some entity of selectable object theObject and |
309 | // current selecting volume |
310 | //======================================================================= |
099f3513 |
311 | void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject, |
312 | const SelectMgr_SelectingVolumeManager& theMgr, |
313 | const Handle(Graphic3d_Camera)& theCamera, |
314 | const Graphic3d_Mat4d& theProjectionMat, |
315 | const Graphic3d_Mat4d& theWorldViewMat, |
316 | const Standard_Integer theViewportWidth, |
317 | const Standard_Integer theViewportHeight) |
7fd59977 |
318 | { |
f5b72419 |
319 | Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); |
f751596e |
320 | if (anEntitySet->Size() == 0) |
f5b72419 |
321 | { |
f751596e |
322 | return; |
f5b72419 |
323 | } |
7fd59977 |
324 | |
f5b72419 |
325 | const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH(); |
91d96372 |
326 | gp_GTrsf aInversedTrsf; |
778cd667 |
327 | if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull()) |
825aa485 |
328 | { |
778cd667 |
329 | if (theObject->TransformPersistence().IsNull()) |
825aa485 |
330 | { |
331 | aInversedTrsf = theObject->InversedTransformation(); |
332 | } |
333 | else |
334 | { |
91d96372 |
335 | gp_GTrsf aTPers; |
778cd667 |
336 | Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight); |
099f3513 |
337 | |
91d96372 |
338 | aTPers.SetValue (1, 1, aMat.GetValue (0, 0)); |
339 | aTPers.SetValue (1, 2, aMat.GetValue (0, 1)); |
340 | aTPers.SetValue (1, 3, aMat.GetValue (0, 2)); |
341 | aTPers.SetValue (2, 1, aMat.GetValue (1, 0)); |
342 | aTPers.SetValue (2, 2, aMat.GetValue (1, 1)); |
343 | aTPers.SetValue (2, 3, aMat.GetValue (1, 2)); |
344 | aTPers.SetValue (3, 1, aMat.GetValue (2, 0)); |
345 | aTPers.SetValue (3, 2, aMat.GetValue (2, 1)); |
346 | aTPers.SetValue (3, 3, aMat.GetValue (2, 2)); |
347 | aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3))); |
348 | |
349 | aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted(); |
825aa485 |
350 | } |
351 | } |
352 | |
353 | SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity |
099f3513 |
354 | ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL) |
355 | : theMgr; |
7fd59977 |
356 | |
3bf9a45f |
357 | SelectMgr_FrustumCache aScaledTrnsfFrustums; |
28ee613b |
358 | |
f751596e |
359 | Standard_Integer aNode = 0; // a root node |
360 | if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0), |
361 | aSensitivesTree->MaxPoint (0))) |
362 | { |
363 | return; |
7fd59977 |
364 | } |
f5b72419 |
365 | Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; |
f751596e |
366 | Standard_Integer aHead = -1; |
367 | for (;;) |
368 | { |
369 | if (!aSensitivesTree->IsOuter (aNode)) |
370 | { |
f2474958 |
371 | const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode); |
372 | const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode); |
f751596e |
373 | const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx), |
374 | aSensitivesTree->MaxPoint (aLeftChildIdx)); |
375 | const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx), |
376 | aSensitivesTree->MaxPoint (aRightChildIdx)); |
377 | if (isLeftChildIn |
378 | && isRightChildIn) |
379 | { |
380 | aNode = aLeftChildIdx; |
381 | ++aHead; |
382 | aStack[aHead] = aRightChildIdx; |
383 | } |
384 | else if (isLeftChildIn |
385 | || isRightChildIn) |
386 | { |
387 | aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; |
388 | } |
389 | else |
390 | { |
391 | if (aHead < 0) |
392 | { |
393 | break; |
394 | } |
7fd59977 |
395 | |
f751596e |
396 | aNode = aStack[aHead]; |
397 | --aHead; |
398 | } |
399 | } |
400 | else |
401 | { |
402 | Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode); |
403 | Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode); |
404 | for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) |
405 | { |
7ab15952 |
406 | const Handle(SelectMgr_SensitiveEntity)& aSensitive = |
f751596e |
407 | anEntitySet->GetSensitiveById (anIdx); |
408 | if (aSensitive->IsActiveForSelection()) |
409 | { |
28ee613b |
410 | const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive(); |
411 | SelectMgr_SelectingVolumeManager aTmpMgr = aMgr; |
099f3513 |
412 | computeFrustum (anEnt, theMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr); |
aa75c0cf |
413 | checkOverlap (anEnt, aInversedTrsf, aTmpMgr); |
f751596e |
414 | } |
415 | } |
416 | if (aHead < 0) |
417 | { |
418 | break; |
419 | } |
7fd59977 |
420 | |
f751596e |
421 | aNode = aStack[aHead]; |
422 | --aHead; |
423 | } |
7fd59977 |
424 | } |
425 | } |
426 | |
f751596e |
427 | //======================================================================= |
428 | // function: TraverseSensitives |
429 | // purpose : Traverses BVH containing all added selectable objects and |
430 | // finds candidates for further search of overlap |
431 | //======================================================================= |
432 | void SelectMgr_ViewerSelector::TraverseSensitives() |
7fd59977 |
433 | { |
434 | mystored.Clear(); |
435 | |
099f3513 |
436 | Standard_Integer aWidth; |
437 | Standard_Integer aHeight; |
438 | mySelectingVolumeMgr.WindowSize (aWidth, aHeight); |
439 | mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(), |
440 | mySelectingVolumeMgr.ProjectionMatrix(), |
441 | mySelectingVolumeMgr.WorldViewMatrix(), |
442 | mySelectingVolumeMgr.WorldViewProjState(), |
443 | aWidth, aHeight); |
444 | |
445 | for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt) |
f751596e |
446 | { |
099f3513 |
447 | SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset = |
448 | static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt); |
449 | |
450 | if (mySelectableObjects.IsEmpty (aBVHSubset)) |
4269bd1b |
451 | { |
099f3513 |
452 | continue; |
453 | } |
454 | |
455 | gp_GTrsf aTFrustum; |
456 | |
457 | SelectMgr_SelectingVolumeManager aMgr (Standard_False); |
458 | |
459 | // for 2D space selection transform selecting volumes to perform overap testing |
460 | // directly in camera's eye space omitting the camera position, which is not |
461 | // needed there at all |
462 | if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent) |
463 | { |
464 | const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix(); |
465 | aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0)); |
466 | aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1)); |
467 | aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2)); |
468 | aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0)); |
469 | aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1)); |
470 | aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2)); |
471 | aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0)); |
472 | aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1)); |
473 | aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2)); |
474 | aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3))); |
475 | |
476 | // define corresponding frustum builder parameters |
477 | Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder(); |
478 | aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix()); |
896faa72 |
479 | aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT); |
099f3513 |
480 | aBuilder->SetWindowSize (aWidth, aHeight); |
481 | aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder); |
825aa485 |
482 | } |
483 | else |
484 | { |
099f3513 |
485 | aMgr = mySelectingVolumeMgr; |
825aa485 |
486 | } |
487 | |
099f3513 |
488 | const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera(); |
489 | const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix(); |
490 | const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent |
491 | ? mySelectingVolumeMgr.WorldViewMatrix() |
896faa72 |
492 | : SelectMgr_ViewerSelector_THE_IDENTITY_MAT; |
099f3513 |
493 | |
f5b72419 |
494 | const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset); |
099f3513 |
495 | |
825aa485 |
496 | Standard_Integer aNode = 0; |
099f3513 |
497 | if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0))) |
825aa485 |
498 | { |
499 | continue; |
500 | } |
501 | |
f5b72419 |
502 | Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; |
825aa485 |
503 | Standard_Integer aHead = -1; |
504 | for (;;) |
505 | { |
506 | if (!aBVHTree->IsOuter (aNode)) |
507 | { |
f2474958 |
508 | const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode); |
509 | const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode); |
825aa485 |
510 | const Standard_Boolean isLeftChildIn = |
099f3513 |
511 | aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx)); |
825aa485 |
512 | const Standard_Boolean isRightChildIn = |
099f3513 |
513 | aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx)); |
825aa485 |
514 | if (isLeftChildIn |
515 | && isRightChildIn) |
516 | { |
517 | aNode = aLeftChildIdx; |
518 | ++aHead; |
519 | aStack[aHead] = aRightChildIdx; |
520 | } |
521 | else if (isLeftChildIn |
522 | || isRightChildIn) |
523 | { |
524 | aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; |
525 | } |
526 | else |
527 | { |
528 | if (aHead < 0) |
529 | { |
530 | break; |
531 | } |
532 | |
533 | aNode = aStack[aHead]; |
534 | --aHead; |
535 | } |
f751596e |
536 | } |
537 | else |
538 | { |
825aa485 |
539 | Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode); |
540 | Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode); |
541 | for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) |
542 | { |
099f3513 |
543 | const Handle(SelectMgr_SelectableObject)& aSelectableObject = |
544 | mySelectableObjects.GetObjectById (aBVHSubset, anIdx); |
825aa485 |
545 | |
099f3513 |
546 | traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight); |
825aa485 |
547 | } |
f751596e |
548 | if (aHead < 0) |
4269bd1b |
549 | { |
f751596e |
550 | break; |
4269bd1b |
551 | } |
7fd59977 |
552 | |
f751596e |
553 | aNode = aStack[aHead]; |
554 | --aHead; |
7fd59977 |
555 | } |
556 | } |
7fd59977 |
557 | } |
4269bd1b |
558 | |
f751596e |
559 | SortResult(); |
7fd59977 |
560 | } |
4269bd1b |
561 | |
7fd59977 |
562 | //================================================== |
563 | // Function: Picked |
564 | // Purpose : |
565 | //================================================== |
566 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector |
567 | ::Picked() const |
568 | { |
f751596e |
569 | Standard_Integer RankInMap = myIndexes->Value (myCurRank); |
7fd59977 |
570 | const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap); |
c5f3a425 |
571 | Handle(SelectMgr_EntityOwner) Ownr = Handle(SelectMgr_EntityOwner)::DownCast (toto); |
7fd59977 |
572 | return Ownr; |
573 | } |
574 | |
7fd59977 |
575 | //======================================================================= |
aa75c0cf |
576 | //function : Picked |
4269bd1b |
577 | //purpose : |
7fd59977 |
578 | //======================================================================= |
aa75c0cf |
579 | Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const |
7fd59977 |
580 | { |
aa75c0cf |
581 | Handle(SelectMgr_EntityOwner) anOwner; |
582 | if (theRank < 1 || theRank > NbPicked()) |
583 | { |
584 | return anOwner; |
7fd59977 |
585 | } |
586 | |
aa75c0cf |
587 | const Standard_Integer anOwnerIdx = myIndexes->Value (theRank); |
588 | const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx); |
589 | anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner); |
590 | return anOwner; |
7fd59977 |
591 | } |
592 | |
7fd59977 |
593 | //======================================================================= |
aa75c0cf |
594 | //function : PickedData |
4269bd1b |
595 | //purpose : |
7fd59977 |
596 | //======================================================================= |
aa75c0cf |
597 | const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const |
7fd59977 |
598 | { |
aa75c0cf |
599 | Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index"); |
600 | const Standard_Integer anOwnerIdx = myIndexes->Value (theRank); |
601 | return mystored.FindFromIndex (anOwnerIdx); |
7fd59977 |
602 | } |
603 | |
7fd59977 |
604 | //=================================================== |
605 | // |
606 | // INTERNAL METHODS .... |
607 | // |
608 | //================================================== |
609 | |
f5b72419 |
610 | //================================================== |
611 | // Function: SetEntitySetBuilder |
612 | // Purpose : |
613 | //================================================== |
614 | void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder) |
615 | { |
616 | myEntitySetBuilder = theBuilder; |
617 | for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next()) |
618 | { |
619 | aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder); |
620 | } |
621 | } |
622 | |
7fd59977 |
623 | //================================================== |
624 | // Function: Contains |
4269bd1b |
625 | // Purpose : |
7fd59977 |
626 | //================================================== |
f751596e |
627 | Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const |
7fd59977 |
628 | { |
099f3513 |
629 | return mySelectableObjects.Contains (theObject); |
7fd59977 |
630 | } |
631 | |
7fd59977 |
632 | //================================================== |
633 | // Function: ActiveModes |
634 | // Purpose : return all the modes with a given state for an object |
635 | //================================================== |
f751596e |
636 | Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
637 | TColStd_ListOfInteger& theModeList, |
638 | const SelectMgr_StateOfSelection theWantedState) const |
7fd59977 |
639 | { |
825aa485 |
640 | Standard_Boolean hasActivatedStates = Contains (theSelectableObject); |
f751596e |
641 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
642 | { |
643 | if (theWantedState == SelectMgr_SOS_Any) |
644 | { |
645 | theModeList.Append (theSelectableObject->CurrentSelection()->Mode()); |
646 | } |
647 | else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState()) |
648 | { |
649 | theModeList.Append (theSelectableObject->CurrentSelection()->Mode()); |
650 | } |
7fd59977 |
651 | } |
7fd59977 |
652 | |
f751596e |
653 | return hasActivatedStates; |
654 | } |
7fd59977 |
655 | |
f751596e |
656 | //================================================== |
657 | // Function: IsActive |
658 | // Purpose : |
659 | //================================================== |
660 | Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
661 | const Standard_Integer theMode) const |
7fd59977 |
662 | { |
825aa485 |
663 | if (!Contains (theSelectableObject)) |
f751596e |
664 | return Standard_False; |
665 | |
666 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
667 | { |
668 | if (theMode == theSelectableObject->CurrentSelection()->Mode()) |
669 | { |
670 | return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated; |
7fd59977 |
671 | } |
672 | } |
f751596e |
673 | |
7fd59977 |
674 | return Standard_False; |
675 | } |
676 | |
f751596e |
677 | //================================================== |
678 | // Function: IsInside |
679 | // Purpose : |
680 | //================================================== |
681 | Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject, |
682 | const Standard_Integer theMode) const |
7fd59977 |
683 | { |
825aa485 |
684 | if (!Contains (theSelectableObject)) |
f751596e |
685 | return Standard_False; |
7fd59977 |
686 | |
f751596e |
687 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
688 | { |
689 | if (theMode == theSelectableObject->CurrentSelection()->Mode()) |
690 | { |
691 | return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown; |
7fd59977 |
692 | } |
693 | } |
f751596e |
694 | |
7fd59977 |
695 | return Standard_False; |
696 | } |
697 | |
698 | |
699 | //======================================================================= |
700 | //function : Status |
4269bd1b |
701 | //purpose : |
7fd59977 |
702 | //======================================================================= |
703 | |
f751596e |
704 | SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const |
7fd59977 |
705 | { |
f751596e |
706 | return theSelection->GetSelectionState(); |
7fd59977 |
707 | } |
708 | |
7fd59977 |
709 | //================================================== |
710 | // Function: Status |
711 | // Purpose : gives Information about selectors |
712 | //================================================== |
713 | |
f751596e |
714 | TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const |
7fd59977 |
715 | { |
f751596e |
716 | TCollection_AsciiString aStatus ("Status Object :\n\t"); |
717 | |
718 | for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next()) |
719 | { |
720 | if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown) |
7fd59977 |
721 | { |
f751596e |
722 | aStatus = aStatus + "Mode " + |
723 | TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) + |
724 | " present - "; |
725 | if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated) |
726 | { |
727 | aStatus = aStatus + " Active \n\t"; |
728 | } |
7fd59977 |
729 | else |
f751596e |
730 | { |
731 | aStatus = aStatus + " Inactive \n\t"; |
732 | } |
7fd59977 |
733 | } |
734 | } |
735 | |
825aa485 |
736 | if (!Contains (theSelectableObject)) |
7fd59977 |
737 | { |
f751596e |
738 | aStatus = aStatus + "Not Present in the selector\n\n"; |
7fd59977 |
739 | } |
f751596e |
740 | |
741 | return aStatus; |
7fd59977 |
742 | } |
743 | |
744 | //======================================================================= |
745 | //function : SortResult |
4269bd1b |
746 | //purpose : there is a certain number of entities ranged by criteria |
81bba717 |
747 | // (depth, size, priority, mouse distance from borders or |
748 | // CDG of the detected primitive. Parsing : |
749 | // maximum priorities . |
750 | // then a reasonable compromise between depth and distance... |
751 | // finally the ranges are stored in myindexes depending on the parsing. |
4269bd1b |
752 | // so, it is possible to only read |
7fd59977 |
753 | //======================================================================= |
754 | void SelectMgr_ViewerSelector::SortResult() |
755 | { |
756 | if(mystored.IsEmpty()) return; |
757 | |
758 | const Standard_Integer anExtent = mystored.Extent(); |
759 | if(myIndexes.IsNull() || anExtent != myIndexes->Length()) |
760 | myIndexes = new TColStd_HArray1OfInteger (1, anExtent); |
761 | |
f5b72419 |
762 | TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1(); |
763 | for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter) |
764 | { |
765 | anIndexArray.SetValue (anIndexIter, anIndexIter); |
766 | } |
767 | std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored)); |
f751596e |
768 | } |
769 | |
770 | //======================================================================= |
771 | //function : HasDepthClipping |
772 | //purpose : Stub |
773 | //======================================================================= |
774 | Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const |
775 | { |
776 | return Standard_False; |
777 | } |
778 | |
779 | //======================================================================= |
780 | // function : AddSelectableObject |
781 | // purpose : Adds new object to the map of selectable objects |
782 | //======================================================================= |
783 | void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
784 | { |
785 | if (!myMapOfObjectSensitives.IsBound (theObject)) |
786 | { |
099f3513 |
787 | mySelectableObjects.Append (theObject); |
f5b72419 |
788 | Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder); |
f751596e |
789 | myMapOfObjectSensitives.Bind (theObject, anEntitySet); |
7fd59977 |
790 | } |
f751596e |
791 | } |
7fd59977 |
792 | |
f751596e |
793 | //======================================================================= |
794 | // function : AddSelectionToObject |
795 | // purpose : Adds new selection to the object and builds its BVH tree |
796 | //======================================================================= |
797 | void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject, |
798 | const Handle(SelectMgr_Selection)& theSelection) |
799 | { |
f5b72419 |
800 | if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject)) |
f751596e |
801 | { |
f5b72419 |
802 | (*anEntitySet)->Append (theSelection); |
803 | (*anEntitySet)->BVH(); |
f751596e |
804 | } |
805 | else |
806 | { |
807 | AddSelectableObject (theObject); |
808 | AddSelectionToObject (theObject, theSelection); |
809 | } |
7fd59977 |
810 | } |
811 | |
1d92133e |
812 | //======================================================================= |
813 | // function : MoveSelectableObject |
814 | // purpose : |
815 | //======================================================================= |
816 | void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
817 | { |
099f3513 |
818 | mySelectableObjects.ChangeSubset (theObject); |
1d92133e |
819 | } |
820 | |
f751596e |
821 | //======================================================================= |
822 | // function : RemoveSelectableObject |
823 | // purpose : Removes selectable object from map of selectable ones |
824 | //======================================================================= |
825 | void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject) |
826 | { |
f5b72419 |
827 | Handle(SelectMgr_SelectableObject) anObj = theObject; |
828 | if (myMapOfObjectSensitives.UnBind (theObject)) |
f751596e |
829 | { |
099f3513 |
830 | mySelectableObjects.Remove (theObject); |
f751596e |
831 | } |
832 | } |
7fd59977 |
833 | |
834 | //======================================================================= |
f751596e |
835 | // function : RemoveSelectionOfObject |
836 | // purpose : Removes selection of the object and marks its BVH tree |
837 | // for rebuild |
7fd59977 |
838 | //======================================================================= |
f751596e |
839 | void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject, |
840 | const Handle(SelectMgr_Selection)& theSelection) |
7fd59977 |
841 | { |
f5b72419 |
842 | if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject)) |
f751596e |
843 | { |
f5b72419 |
844 | (*anEntitySet)->Remove (theSelection); |
f751596e |
845 | } |
7fd59977 |
846 | } |
847 | |
848 | //======================================================================= |
f751596e |
849 | // function : RebuildObjectsTree |
850 | // purpose : Marks BVH of selectable objects for rebuild |
7fd59977 |
851 | //======================================================================= |
f751596e |
852 | void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce) |
7fd59977 |
853 | { |
825aa485 |
854 | mySelectableObjects.MarkDirty(); |
f751596e |
855 | |
856 | if (theIsForce) |
857 | { |
099f3513 |
858 | Standard_Integer aViewportWidth, aViewportHeight; |
91d96372 |
859 | mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight); |
825aa485 |
860 | |
099f3513 |
861 | Standard_Integer aWidth; |
862 | Standard_Integer aHeight; |
863 | mySelectingVolumeMgr.WindowSize (aWidth, aHeight); |
864 | mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(), |
865 | mySelectingVolumeMgr.ProjectionMatrix(), |
866 | mySelectingVolumeMgr.WorldViewMatrix(), |
867 | mySelectingVolumeMgr.WorldViewProjState(), |
868 | aWidth, aHeight); |
f751596e |
869 | } |
7fd59977 |
870 | } |
4269bd1b |
871 | |
872 | //======================================================================= |
f751596e |
873 | // function : RebuildSensitivesTree |
874 | // purpose : Marks BVH of sensitive entities of particular selectable |
875 | // object for rebuild |
4269bd1b |
876 | //======================================================================= |
f751596e |
877 | void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject, |
878 | const Standard_Boolean theIsForce) |
4269bd1b |
879 | { |
825aa485 |
880 | if (!Contains (theObject)) |
f751596e |
881 | return; |
882 | |
f5b72419 |
883 | Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject); |
f751596e |
884 | anEntitySet->MarkDirty(); |
885 | |
886 | if (theIsForce) |
887 | { |
888 | anEntitySet->BVH(); |
889 | } |
4269bd1b |
890 | } |
891 | |
892 | //======================================================================= |
f751596e |
893 | // function : resetSelectionActivationStatus |
894 | // purpose : Marks all added sensitive entities of all objects as |
895 | // non-selectable |
4269bd1b |
896 | //======================================================================= |
29a4908e |
897 | void SelectMgr_ViewerSelector::ResetSelectionActivationStatus() |
4269bd1b |
898 | { |
f5b72419 |
899 | for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next()) |
f751596e |
900 | { |
f5b72419 |
901 | Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue(); |
902 | const Standard_Integer anEntitiesNb = anEntitySet->Size(); |
f751596e |
903 | for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) |
904 | { |
905 | anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus(); |
906 | } |
907 | } |
4269bd1b |
908 | } |
909 | |
910 | //======================================================================= |
f751596e |
911 | // function : DetectedEntity |
912 | // purpose : Returns sensitive entity that was detected during the |
913 | // previous run of selection algorithm |
4269bd1b |
914 | //======================================================================= |
f751596e |
915 | const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const |
4269bd1b |
916 | { |
aa75c0cf |
917 | const Standard_Integer aRankInMap = myIndexes->Value(myCurRank); |
918 | return mystored.FindFromIndex (aRankInMap).Entity; |
4269bd1b |
919 | } |
920 | |
921 | //======================================================================= |
f751596e |
922 | // function : ActiveOwners |
923 | // purpose : Returns the list of active entity owners |
4269bd1b |
924 | //======================================================================= |
751955d4 |
925 | void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const |
4269bd1b |
926 | { |
f751596e |
927 | for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next()) |
928 | { |
f5b72419 |
929 | const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value(); |
930 | const Standard_Integer anEntitiesNb = anEntitySet->Size(); |
f751596e |
931 | for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx) |
932 | { |
f5b72419 |
933 | const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx); |
934 | if (aSensitive->IsActiveForSelection()) |
f751596e |
935 | { |
f5b72419 |
936 | theOwners.Append (aSensitive->BaseSensitive()->OwnerId()); |
f751596e |
937 | } |
938 | } |
939 | } |
4269bd1b |
940 | } |
29a4908e |
941 | |
942 | //======================================================================= |
943 | //function : AllowOverlapDetection |
944 | //purpose : Sets the detection type: if theIsToAllow is false, |
945 | // only fully included sensitives will be detected, otherwise |
946 | // the algorithm will mark both included and overlapped entities |
947 | // as matched |
948 | //======================================================================= |
949 | void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow) |
950 | { |
951 | mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow); |
952 | } |