0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
CommitLineData
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>
0ef04197 24#include <Select3D_SensitiveEntity.hxx>
f751596e 25#include <SelectBasics_PickResult.hxx>
26#include <SelectMgr_EntityOwner.hxx>
7fd59977 27#include <SelectMgr_SortCriterion.hxx>
f751596e 28#include <SelectMgr_SensitiveEntitySet.hxx>
f751596e 29#include <TColStd_Array1OfInteger.hxx>
30#include <TCollection_AsciiString.hxx>
31#include <TColStd_HArray1OfInteger.hxx>
32#include <TColStd_ListOfInteger.hxx>
33
e35db416 34#include <algorithm>
35
f5b72419 36IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
92efcf78 37
e35db416 38namespace {
39 // Comparison operator for sorting selection results
40 class CompareResults
41 {
42 public:
43
44 CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion)
45 : myMapOfCriterion (aMapOfCriterion)
46 {
47 }
48
49 Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
50 {
51 return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight);
52 }
53
54 private:
55 void operator = (const CompareResults&);
56
57 private:
58 const SelectMgr_IndexedDataMapOfOwnerCriterion& myMapOfCriterion;
59 };
f751596e 60
fe76088c 61 static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
62}
63
64//=======================================================================
65// function : updatePoint3d
66// purpose :
67//=======================================================================
68void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
17017555 69 const SelectBasics_PickResult& thePickResult,
0ef04197 70 const Handle(Select3D_SensitiveEntity)& theEntity,
fe76088c 71 const gp_GTrsf& theInversedTrsf,
72 const SelectMgr_SelectingVolumeManager& theMgr) const
73{
74 if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
4269bd1b 75 {
fe76088c 76 return;
77 }
949c9b7f 78
2615c2d7 79 bool hasNormal = false;
17017555 80 if (thePickResult.HasPickedPoint())
81 {
2615c2d7 82 theCriterion.Point = thePickResult.PickedPoint();
83 theCriterion.Normal = thePickResult.SurfaceNormal();
84 const float aNormLen2 = theCriterion.Normal.SquareModulus();
85 if (aNormLen2 > ShortRealEpsilon())
86 {
87 hasNormal = true;
88 theCriterion.Normal *= 1.0f / sqrtf (aNormLen2);
89 }
17017555 90 }
b44bf0f8 91 else if (!thePickResult.IsValid())
92 {
93 theCriterion.Point = thePickResult.PickedPoint();
94 return;
95 }
17017555 96 else
97 {
98 theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
99 }
100
fe76088c 101 gp_GTrsf anInvTrsf = theInversedTrsf;
102 if (theCriterion.Entity->HasInitLocation())
103 {
104 anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
105 }
106 if (anInvTrsf.Form() != gp_Identity)
107 {
2615c2d7 108 const gp_GTrsf anInvInvTrsd = anInvTrsf.Inverted();
109 anInvInvTrsd.Transforms (theCriterion.Point.ChangeCoord());
110 if (hasNormal)
111 {
112 Graphic3d_Mat4d aMat4;
113 anInvInvTrsd.GetMat4 (aMat4);
114 const Graphic3d_Vec4d aNormRes = aMat4 * Graphic3d_Vec4d (Graphic3d_Vec3d (theCriterion.Normal), 0.0);
115 theCriterion.Normal = Graphic3d_Vec3 (aNormRes.xyz());
116 }
f751596e 117 }
aa75c0cf 118
fe76088c 119 if (mySelectingVolumeMgr.Camera().IsNull())
120 {
121 theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
122 }
123 else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
124 {
125 theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor();
126 }
127 else
128 {
b44bf0f8 129 const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ()));
fe76088c 130 theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor();
131 }
f751596e 132}
133
7fd59977 134//==================================================
135// Function: Initialize
136// Purpose :
137//==================================================
138SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
7fd59977 139preferclosest(Standard_True),
f751596e 140myToUpdateTolerance (Standard_True),
fe76088c 141myCameraScale (1.0),
f751596e 142myCurRank (0),
143myIsLeftChildQueuedFirst (Standard_False),
144myEntityIdx (0)
7fd59977 145{
f5b72419 146 myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
7fd59977 147}
148
7f24b768 149//=======================================================================
150// Function: SetPixelTolerance
151// Purpose :
152//=======================================================================
153void SelectMgr_ViewerSelector::SetPixelTolerance (const Standard_Integer theTolerance)
154{
155 if (myTolerances.Tolerance() == theTolerance)
156 {
157 return;
158 }
159
160 myToUpdateTolerance = Standard_True;
161 if (theTolerance < 0)
162 {
163 myTolerances.ResetDefaults();
164 }
165 else
166 {
167 myTolerances.SetCustomTolerance (theTolerance);
168 }
169}
170
7fd59977 171//==================================================
172// Function: Activate
173// Purpose :
174//==================================================
f751596e 175void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
7fd59977 176{
b5cce1ab 177 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
7fd59977 178 {
b5cce1ab 179 aSelEntIter.Value()->SetActiveForSelection();
4269bd1b 180 }
7fd59977 181
82d23ad5 182 if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
183 {
184 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
7fd59977 185
82d23ad5 186 myTolerances.Add (theSelection->Sensitivity());
187 myToUpdateTolerance = Standard_True;
188 }
7fd59977 189}
190
7fd59977 191//==================================================
f751596e 192// Function: Deactivate
7fd59977 193// Purpose :
194//==================================================
f751596e 195void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
4269bd1b 196{
b5cce1ab 197 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
f751596e 198 {
b5cce1ab 199 aSelEntIter.Value()->ResetSelectionActiveStatus();
7fd59977 200 }
7fd59977 201
82d23ad5 202 if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
203 {
204 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
7fd59977 205
82d23ad5 206 myTolerances.Decrement (theSelection->Sensitivity());
207 myToUpdateTolerance = Standard_True;
208 }
7fd59977 209}
210
7fd59977 211//==================================================
212// Function: Clear
213// Purpose :
214//==================================================
215void SelectMgr_ViewerSelector::Clear()
216{
7fd59977 217 mystored.Clear();
7fd59977 218}
219
28ee613b 220//=======================================================================
221// function: isToScaleFrustum
222// purpose : Checks if the entity given requires to scale current selecting frustum
223//=======================================================================
0ef04197 224Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity)
28ee613b 225{
226 return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
29a4908e 227 && sensitivity (theEntity) < myTolerances.Tolerance();
28ee613b 228}
229
29a4908e 230//=======================================================================
231// function: sensitivity
232// purpose : In case if custom tolerance is set, this method will return sum of entity
233// sensitivity and custom tolerance.
234//=======================================================================
0ef04197 235Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(Select3D_SensitiveEntity)& theEntity) const
29a4908e 236{
237 return myTolerances.IsCustomTolSet() ?
238 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
239}
240
f751596e 241//=======================================================================
242// function: checkOverlap
243// purpose : Internal function that checks if a particular sensitive
244// entity theEntity overlaps current selecting volume precisely
245//=======================================================================
0ef04197 246void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity,
aa75c0cf 247 const gp_GTrsf& theInversedTrsf,
f751596e 248 SelectMgr_SelectingVolumeManager& theMgr)
7fd59977 249{
0ef04197 250 const Handle(SelectMgr_EntityOwner)& anOwner = theEntity->OwnerId();
fe525c6f 251 Handle(SelectMgr_SelectableObject) aSelectable = !anOwner.IsNull() ? anOwner->Selectable() : Handle(SelectMgr_SelectableObject)();
f751596e 252 SelectBasics_PickResult aPickResult;
3202bf1e 253 const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
3202bf1e 254 if (!isMatched
255 || anOwner.IsNull())
256 {
257 return;
258 }
259
3202bf1e 260 SelectMgr_SortCriterion aCriterion;
b1c235df 261 myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
3202bf1e 262 aCriterion.Entity = theEntity;
263 aCriterion.Priority = anOwner->Priority();
264 aCriterion.Depth = aPickResult.Depth();
265 aCriterion.MinDist = aPickResult.DistToGeomCenter();
3202bf1e 266 aCriterion.ToPreferClosest = preferclosest;
267
be7fc29e 268 if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
3202bf1e 269 {
be7fc29e 270 ++aPrevCriterion->NbOwnerMatches;
271 aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
3202bf1e 272 if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
273 {
be7fc29e 274 if (aCriterion > *aPrevCriterion)
f751596e 275 {
17017555 276 updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
be7fc29e 277 *aPrevCriterion = aCriterion;
7fd59977 278 }
279 }
7fd59977 280 }
3202bf1e 281 else
282 {
be7fc29e 283 aCriterion.NbOwnerMatches = 1;
17017555 284 updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
3202bf1e 285 mystored.Add (anOwner, aCriterion);
286 }
7fd59977 287}
288
3bf9a45f 289//=======================================================================
290// function: computeFrustum
208dc370 291// purpose :
3bf9a45f 292//=======================================================================
0ef04197 293void SelectMgr_ViewerSelector::computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt,
208dc370 294 const SelectMgr_SelectingVolumeManager& theMgrGlobal,
295 const SelectMgr_SelectingVolumeManager& theMgrObject,
296 const gp_GTrsf& theInvTrsf,
297 SelectMgr_FrustumCache& theCachedMgrs,
298 SelectMgr_SelectingVolumeManager& theResMgr)
3bf9a45f 299{
7479f643 300 Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
91d96372 301 const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
7479f643 302 const Standard_Boolean toScale = aScale != 1;
303 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
304 if (toScale && toTransform)
3bf9a45f 305 {
208dc370 306 theResMgr = theMgrGlobal.ScaleAndTransform (aScale, aTrsfMtr, NULL);
307 theResMgr.SetViewClipping (theMgrObject);
3bf9a45f 308 }
309 else if (toScale)
310 {
208dc370 311 if (!theCachedMgrs.Find (aScale, theResMgr))
3bf9a45f 312 {
208dc370 313 theResMgr = theMgrGlobal.ScaleAndTransform (aScale, gp_Trsf(), NULL);
314 theCachedMgrs.Bind (aScale, theResMgr);
3bf9a45f 315 }
208dc370 316 theResMgr.SetViewClipping (theMgrObject);
3bf9a45f 317 }
7479f643 318 else if (toTransform)
319 {
208dc370 320 theResMgr = theMgrGlobal.ScaleAndTransform (1, aTrsfMtr, NULL);
321 theResMgr.SetViewClipping (theMgrObject);
322 }
323 else
324 {
325 theResMgr = theMgrObject;
7479f643 326 }
3bf9a45f 327}
328
f751596e 329//=======================================================================
330// function: traverseObject
331// purpose : Internal function that checks if there is possible overlap
332// between some entity of selectable object theObject and
333// current selecting volume
334//=======================================================================
099f3513 335void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
336 const SelectMgr_SelectingVolumeManager& theMgr,
337 const Handle(Graphic3d_Camera)& theCamera,
338 const Graphic3d_Mat4d& theProjectionMat,
339 const Graphic3d_Mat4d& theWorldViewMat,
340 const Standard_Integer theViewportWidth,
341 const Standard_Integer theViewportHeight)
7fd59977 342{
f5b72419 343 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
f751596e 344 if (anEntitySet->Size() == 0)
f5b72419 345 {
f751596e 346 return;
f5b72419 347 }
7fd59977 348
f5b72419 349 const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
91d96372 350 gp_GTrsf aInversedTrsf;
778cd667 351 if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
825aa485 352 {
778cd667 353 if (theObject->TransformPersistence().IsNull())
825aa485 354 {
355 aInversedTrsf = theObject->InversedTransformation();
356 }
357 else
358 {
91d96372 359 gp_GTrsf aTPers;
778cd667 360 Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
099f3513 361
91d96372 362 aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
363 aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
364 aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
365 aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
366 aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
367 aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
368 aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
369 aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
370 aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
371 aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
372
373 aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
825aa485 374 }
375 }
376
377 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
099f3513 378 ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
379 : theMgr;
f751596e 380 if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
381 aSensitivesTree->MaxPoint (0)))
382 {
383 return;
7fd59977 384 }
be7fc29e 385
fe525c6f 386 if (!theObject->ClipPlanes().IsNull()
387 && theObject->ClipPlanes()->ToOverrideGlobal())
388 {
72e9e867 389 aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
fe525c6f 390 }
391 else if (!theObject->TransformPersistence().IsNull())
392 {
393 if (theObject->TransformPersistence()->IsZoomOrRotate()
394 && !theMgr.ViewClipping().IsNull())
395 {
396 // Zoom/rotate persistence object lives in two worlds at the same time.
397 // Global clipping planes can not be trivially applied without being converted
398 // into local space of transformation persistence object.
399 // As more simple alternative - just clip entire object by its anchor point defined in the world space.
400 const gp_Pnt anAnchor = theObject->TransformPersistence()->AnchorPoint();
401 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*theMgr.ViewClipping()); aPlaneIt.More(); aPlaneIt.Next())
402 {
403 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
404 if (!aPlane->IsOn())
405 {
406 continue;
407 }
408
409 const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
410 if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
411 {
412 return;
413 }
414 }
415 }
416
72e9e867 417 aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
fe525c6f 418 }
419 else if (!theObject->ClipPlanes().IsNull()
420 && !theObject->ClipPlanes()->IsEmpty())
421 {
72e9e867 422 aMgr.SetViewClipping (theMgr.ViewClipping(), theObject->ClipPlanes(), &theMgr);
fe525c6f 423 }
424
8996b449 425 if (!theMgr.ViewClipping().IsNull() &&
426 theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
427 {
428 Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (0), aSensitivesTree->MaxPoint (0));
429 // If box selection is active, and the whole sensitive tree is out of the clip planes
430 // selection is empty for this object
431 const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
432
433 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
434 {
435 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
436 if (!aPlane->IsOn())
437 {
438 continue;
439 }
440
441 Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
442 if (aState == Graphic3d_ClipState_Out) // do not process only whole trees, next check on the tree node
443 {
444 return;
445 }
446 }
447 }
448
be7fc29e 449 const Standard_Integer aFirstStored = mystored.Extent() + 1;
450
f5b72419 451 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
f751596e 452 Standard_Integer aHead = -1;
fe525c6f 453 Standard_Integer aNode = 0; // a root node
454 SelectMgr_FrustumCache aScaledTrnsfFrustums;
d7fa57a7 455 SelectMgr_SelectingVolumeManager aTmpMgr (false);
f751596e 456 for (;;)
457 {
458 if (!aSensitivesTree->IsOuter (aNode))
459 {
f2474958 460 const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
461 const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
f751596e 462 const Standard_Boolean isLeftChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
463 aSensitivesTree->MaxPoint (aLeftChildIdx));
464 const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
465 aSensitivesTree->MaxPoint (aRightChildIdx));
466 if (isLeftChildIn
467 && isRightChildIn)
468 {
469 aNode = aLeftChildIdx;
470 ++aHead;
471 aStack[aHead] = aRightChildIdx;
472 }
473 else if (isLeftChildIn
474 || isRightChildIn)
475 {
476 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
477 }
478 else
479 {
480 if (aHead < 0)
481 {
482 break;
483 }
7fd59977 484
f751596e 485 aNode = aStack[aHead];
486 --aHead;
487 }
488 }
489 else
490 {
8996b449 491 bool aClipped = false;
492 if (!theMgr.ViewClipping().IsNull() &&
493 theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
494 {
495 Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (aNode), aSensitivesTree->MaxPoint (aNode));
496 // If box selection is active, and the whole sensitive tree is out of the clip planes
497 // selection is empty for this object
498 const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
499
500 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
501 {
502 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
503 if (!aPlane->IsOn())
504 {
505 continue;
506 }
507 Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
508 if (aState == Graphic3d_ClipState_Out)
509 {
510 aClipped = true;
511 break;
512 }
513 if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
514 {
515 if (aPlane->ProbeBoxTouch (aBBox))
516 continue;
517 aClipped = true;
518 break;
519 }
520 }
521 }
522 if (!aClipped)
f751596e 523 {
8996b449 524 Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
525 Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
526 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
f751596e 527 {
8996b449 528 const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
529 if (aSensitive->IsActiveForSelection())
530 {
531 const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
208dc370 532 computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
8996b449 533 checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
534 }
f751596e 535 }
536 }
537 if (aHead < 0)
538 {
539 break;
540 }
7fd59977 541
f751596e 542 aNode = aStack[aHead];
543 --aHead;
544 }
7fd59977 545 }
be7fc29e 546
547 // in case of Box/Polyline selection - keep only Owners having all Entities detected
548 if (mySelectingVolumeMgr.IsOverlapAllowed()
549 || (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box
550 && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
551 {
552 return;
553 }
554
555 for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter)
556 {
557 const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter);
0ef04197 558 const Handle(SelectMgr_EntityOwner)& anOwner = aCriterion.Entity->OwnerId();
be7fc29e 559 Standard_Integer aNbOwnerEntities = 0;
560 for (SelectMgr_IndexedMapOfHSensitive::Iterator aSensIter (anEntitySet->Sensitives()); aSensIter.More(); aSensIter.Next())
561 {
562 if (aSensIter.Value()->BaseSensitive()->OwnerId() == anOwner)
563 {
564 if (++aNbOwnerEntities > aCriterion.NbOwnerMatches)
565 {
566 // Remove from index map.
567 // Considering NCollection_IndexedDataMap implementation, the values for lower indexes will not be modified.
568 // Hence, just keep iterating in backward direction.
569 mystored.RemoveFromIndex (aStoredIter);
570 break;
571 }
572 }
573 }
574 }
7fd59977 575}
576
f751596e 577//=======================================================================
578// function: TraverseSensitives
579// purpose : Traverses BVH containing all added selectable objects and
580// finds candidates for further search of overlap
581//=======================================================================
582void SelectMgr_ViewerSelector::TraverseSensitives()
7fd59977 583{
584 mystored.Clear();
585
099f3513 586 Standard_Integer aWidth;
587 Standard_Integer aHeight;
588 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
589 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
590 mySelectingVolumeMgr.ProjectionMatrix(),
591 mySelectingVolumeMgr.WorldViewMatrix(),
592 mySelectingVolumeMgr.WorldViewProjState(),
593 aWidth, aHeight);
fe76088c 594 const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
595 if (!aCamera.IsNull())
596 {
597 myCameraEye = aCamera->Eye().XYZ();
598 myCameraDir = aCamera->Direction().XYZ();
599 myCameraScale = aCamera->IsOrthographic()
600 ? aCamera->Scale()
601 : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
602 const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
603 myCameraScale *= aPixelSize;
604 }
099f3513 605
606 for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
f751596e 607 {
099f3513 608 SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
609 static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
610
611 if (mySelectableObjects.IsEmpty (aBVHSubset))
4269bd1b 612 {
099f3513 613 continue;
614 }
615
616 gp_GTrsf aTFrustum;
617
618 SelectMgr_SelectingVolumeManager aMgr (Standard_False);
619
620 // for 2D space selection transform selecting volumes to perform overap testing
621 // directly in camera's eye space omitting the camera position, which is not
622 // needed there at all
623 if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent)
624 {
625 const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix();
626 aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0));
627 aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1));
628 aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2));
629 aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0));
630 aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1));
631 aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2));
632 aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0));
633 aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1));
634 aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2));
635 aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
636
637 // define corresponding frustum builder parameters
638 Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
639 aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
896faa72 640 aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
099f3513 641 aBuilder->SetWindowSize (aWidth, aHeight);
642 aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
825aa485 643 }
644 else
645 {
099f3513 646 aMgr = mySelectingVolumeMgr;
825aa485 647 }
648
099f3513 649 const Graphic3d_Mat4d& aProjectionMat = mySelectingVolumeMgr.ProjectionMatrix();
650 const Graphic3d_Mat4d& aWorldViewMat = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
651 ? mySelectingVolumeMgr.WorldViewMatrix()
896faa72 652 : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
099f3513 653
f5b72419 654 const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
099f3513 655
825aa485 656 Standard_Integer aNode = 0;
099f3513 657 if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
825aa485 658 {
659 continue;
660 }
661
f5b72419 662 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
825aa485 663 Standard_Integer aHead = -1;
664 for (;;)
665 {
666 if (!aBVHTree->IsOuter (aNode))
667 {
f2474958 668 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
669 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
825aa485 670 const Standard_Boolean isLeftChildIn =
099f3513 671 aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
825aa485 672 const Standard_Boolean isRightChildIn =
099f3513 673 aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
825aa485 674 if (isLeftChildIn
675 && isRightChildIn)
676 {
677 aNode = aLeftChildIdx;
678 ++aHead;
679 aStack[aHead] = aRightChildIdx;
680 }
681 else if (isLeftChildIn
682 || isRightChildIn)
683 {
684 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
685 }
686 else
687 {
688 if (aHead < 0)
689 {
690 break;
691 }
692
693 aNode = aStack[aHead];
694 --aHead;
695 }
f751596e 696 }
697 else
698 {
825aa485 699 Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
700 Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
701 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
702 {
099f3513 703 const Handle(SelectMgr_SelectableObject)& aSelectableObject =
704 mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
825aa485 705
099f3513 706 traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
825aa485 707 }
f751596e 708 if (aHead < 0)
4269bd1b 709 {
f751596e 710 break;
4269bd1b 711 }
7fd59977 712
f751596e 713 aNode = aStack[aHead];
714 --aHead;
7fd59977 715 }
716 }
7fd59977 717 }
4269bd1b 718
f751596e 719 SortResult();
7fd59977 720}
4269bd1b 721
8a590580 722//==================================================
723// Function: ClearPicked
724// Purpose :
725//==================================================
726void SelectMgr_ViewerSelector::ClearPicked()
727{
728 mystored.Clear();
729}
730
7fd59977 731//==================================================
732// Function: Picked
733// Purpose :
734//==================================================
0ef04197 735Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked() const
7fd59977 736{
0ef04197 737 const Standard_Integer aRankInMap = myIndexes->Value (myCurRank);
738 const Handle(SelectMgr_EntityOwner)& anOwner = mystored.FindKey (aRankInMap);
739 return anOwner;
7fd59977 740}
741
7fd59977 742//=======================================================================
aa75c0cf 743//function : Picked
4269bd1b 744//purpose :
7fd59977 745//=======================================================================
aa75c0cf 746Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
7fd59977 747{
aa75c0cf 748 if (theRank < 1 || theRank > NbPicked())
749 {
0ef04197 750 return Handle(SelectMgr_EntityOwner)();
7fd59977 751 }
752
aa75c0cf 753 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
0ef04197 754 const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
755 return aStoredOwner;
7fd59977 756}
757
7fd59977 758//=======================================================================
aa75c0cf 759//function : PickedData
4269bd1b 760//purpose :
7fd59977 761//=======================================================================
aa75c0cf 762const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
7fd59977 763{
aa75c0cf 764 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
765 const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
766 return mystored.FindFromIndex (anOwnerIdx);
7fd59977 767}
768
7fd59977 769//===================================================
770//
771// INTERNAL METHODS ....
772//
773//==================================================
774
f5b72419 775//==================================================
776// Function: SetEntitySetBuilder
777// Purpose :
778//==================================================
779void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
780{
781 myEntitySetBuilder = theBuilder;
782 for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
783 {
784 aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
785 }
786}
787
7fd59977 788//==================================================
789// Function: Contains
4269bd1b 790// Purpose :
7fd59977 791//==================================================
f751596e 792Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
7fd59977 793{
099f3513 794 return mySelectableObjects.Contains (theObject);
7fd59977 795}
796
7fd59977 797//==================================================
798// Function: ActiveModes
799// Purpose : return all the modes with a given state for an object
800//==================================================
f751596e 801Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
802 TColStd_ListOfInteger& theModeList,
803 const SelectMgr_StateOfSelection theWantedState) const
7fd59977 804{
825aa485 805 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
b5cce1ab 806 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
f751596e 807 {
82d23ad5 808 if (theWantedState == SelectMgr_SOS_Any)
809 {
810 theModeList.Append (aSelIter.Value()->Mode());
811 }
812 else if (theWantedState == aSelIter.Value()->GetSelectionState())
813 {
814 theModeList.Append (aSelIter.Value()->Mode());
815 }
7fd59977 816 }
7fd59977 817
f751596e 818 return hasActivatedStates;
819}
7fd59977 820
f751596e 821//==================================================
822// Function: IsActive
823// Purpose :
824//==================================================
825Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
826 const Standard_Integer theMode) const
7fd59977 827{
825aa485 828 if (!Contains (theSelectableObject))
f751596e 829 return Standard_False;
830
b5cce1ab 831 const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
832 return !aSel.IsNull()
833 && aSel->GetSelectionState() == SelectMgr_SOS_Activated;
7fd59977 834}
835
f751596e 836//==================================================
837// Function: IsInside
838// Purpose :
839//==================================================
840Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
841 const Standard_Integer theMode) const
7fd59977 842{
825aa485 843 if (!Contains (theSelectableObject))
f751596e 844 return Standard_False;
7fd59977 845
b5cce1ab 846 const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
847 return !aSel.IsNull()
848 && aSel->GetSelectionState() != SelectMgr_SOS_Unknown;
7fd59977 849}
850
851
852//=======================================================================
853//function : Status
4269bd1b 854//purpose :
7fd59977 855//=======================================================================
856
f751596e 857SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
7fd59977 858{
f751596e 859 return theSelection->GetSelectionState();
7fd59977 860}
861
7fd59977 862//==================================================
863// Function: Status
864// Purpose : gives Information about selectors
865//==================================================
866
f751596e 867TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
7fd59977 868{
f751596e 869 TCollection_AsciiString aStatus ("Status Object :\n\t");
b5cce1ab 870 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
f751596e 871 {
b5cce1ab 872 if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown)
7fd59977 873 {
b5cce1ab 874 aStatus = aStatus + "Mode " + TCollection_AsciiString (aSelIter.Value()->Mode()) + " present - "
875 + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" : " Inactive \n\t");
7fd59977 876 }
877 }
878
825aa485 879 if (!Contains (theSelectableObject))
7fd59977 880 {
f751596e 881 aStatus = aStatus + "Not Present in the selector\n\n";
7fd59977 882 }
f751596e 883
884 return aStatus;
7fd59977 885}
886
887//=======================================================================
888//function : SortResult
4269bd1b 889//purpose : there is a certain number of entities ranged by criteria
81bba717 890// (depth, size, priority, mouse distance from borders or
891// CDG of the detected primitive. Parsing :
892// maximum priorities .
893// then a reasonable compromise between depth and distance...
894// finally the ranges are stored in myindexes depending on the parsing.
4269bd1b 895// so, it is possible to only read
7fd59977 896//=======================================================================
897void SelectMgr_ViewerSelector::SortResult()
898{
899 if(mystored.IsEmpty()) return;
900
901 const Standard_Integer anExtent = mystored.Extent();
902 if(myIndexes.IsNull() || anExtent != myIndexes->Length())
903 myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
904
f5b72419 905 TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
906 for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
907 {
908 anIndexArray.SetValue (anIndexIter, anIndexIter);
909 }
910 std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
f751596e 911}
912
f751596e 913//=======================================================================
914// function : AddSelectableObject
915// purpose : Adds new object to the map of selectable objects
916//=======================================================================
917void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
918{
919 if (!myMapOfObjectSensitives.IsBound (theObject))
920 {
099f3513 921 mySelectableObjects.Append (theObject);
f5b72419 922 Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
f751596e 923 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
7fd59977 924 }
f751596e 925}
7fd59977 926
f751596e 927//=======================================================================
928// function : AddSelectionToObject
929// purpose : Adds new selection to the object and builds its BVH tree
930//=======================================================================
931void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
932 const Handle(SelectMgr_Selection)& theSelection)
933{
f5b72419 934 if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
f751596e 935 {
f5b72419 936 (*anEntitySet)->Append (theSelection);
937 (*anEntitySet)->BVH();
f751596e 938 }
939 else
940 {
941 AddSelectableObject (theObject);
942 AddSelectionToObject (theObject, theSelection);
943 }
7fd59977 944}
945
1d92133e 946//=======================================================================
947// function : MoveSelectableObject
948// purpose :
949//=======================================================================
950void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
951{
099f3513 952 mySelectableObjects.ChangeSubset (theObject);
1d92133e 953}
954
f751596e 955//=======================================================================
956// function : RemoveSelectableObject
957// purpose : Removes selectable object from map of selectable ones
958//=======================================================================
959void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
960{
f5b72419 961 Handle(SelectMgr_SelectableObject) anObj = theObject;
962 if (myMapOfObjectSensitives.UnBind (theObject))
f751596e 963 {
099f3513 964 mySelectableObjects.Remove (theObject);
f751596e 965 }
966}
7fd59977 967
968//=======================================================================
f751596e 969// function : RemoveSelectionOfObject
970// purpose : Removes selection of the object and marks its BVH tree
971// for rebuild
7fd59977 972//=======================================================================
f751596e 973void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
974 const Handle(SelectMgr_Selection)& theSelection)
7fd59977 975{
f5b72419 976 if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
f751596e 977 {
f5b72419 978 (*anEntitySet)->Remove (theSelection);
f751596e 979 }
7fd59977 980}
981
982//=======================================================================
f751596e 983// function : RebuildObjectsTree
984// purpose : Marks BVH of selectable objects for rebuild
7fd59977 985//=======================================================================
f751596e 986void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
7fd59977 987{
825aa485 988 mySelectableObjects.MarkDirty();
f751596e 989
990 if (theIsForce)
991 {
099f3513 992 Standard_Integer aViewportWidth, aViewportHeight;
91d96372 993 mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
825aa485 994
099f3513 995 Standard_Integer aWidth;
996 Standard_Integer aHeight;
997 mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
998 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
999 mySelectingVolumeMgr.ProjectionMatrix(),
1000 mySelectingVolumeMgr.WorldViewMatrix(),
1001 mySelectingVolumeMgr.WorldViewProjState(),
1002 aWidth, aHeight);
f751596e 1003 }
7fd59977 1004}
4269bd1b 1005
1006//=======================================================================
f751596e 1007// function : RebuildSensitivesTree
1008// purpose : Marks BVH of sensitive entities of particular selectable
1009// object for rebuild
4269bd1b 1010//=======================================================================
f751596e 1011void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
1012 const Standard_Boolean theIsForce)
4269bd1b 1013{
825aa485 1014 if (!Contains (theObject))
f751596e 1015 return;
1016
f5b72419 1017 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
f751596e 1018 anEntitySet->MarkDirty();
1019
1020 if (theIsForce)
1021 {
1022 anEntitySet->BVH();
1023 }
4269bd1b 1024}
1025
1026//=======================================================================
f751596e 1027// function : resetSelectionActivationStatus
1028// purpose : Marks all added sensitive entities of all objects as
1029// non-selectable
4269bd1b 1030//=======================================================================
29a4908e 1031void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
4269bd1b 1032{
f5b72419 1033 for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
f751596e 1034 {
f5b72419 1035 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
1036 const Standard_Integer anEntitiesNb = anEntitySet->Size();
f751596e 1037 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
1038 {
1039 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
1040 }
1041 }
4269bd1b 1042}
1043
1044//=======================================================================
f751596e 1045// function : DetectedEntity
1046// purpose : Returns sensitive entity that was detected during the
1047// previous run of selection algorithm
4269bd1b 1048//=======================================================================
0ef04197 1049const Handle(Select3D_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
4269bd1b 1050{
aa75c0cf 1051 const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
1052 return mystored.FindFromIndex (aRankInMap).Entity;
4269bd1b 1053}
1054
1055//=======================================================================
f751596e 1056// function : ActiveOwners
1057// purpose : Returns the list of active entity owners
4269bd1b 1058//=======================================================================
0ef04197 1059void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const
4269bd1b 1060{
f751596e 1061 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
1062 {
f5b72419 1063 const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
1064 const Standard_Integer anEntitiesNb = anEntitySet->Size();
f751596e 1065 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
1066 {
f5b72419 1067 const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
1068 if (aSensitive->IsActiveForSelection())
f751596e 1069 {
f5b72419 1070 theOwners.Append (aSensitive->BaseSensitive()->OwnerId());
f751596e 1071 }
1072 }
1073 }
4269bd1b 1074}
29a4908e 1075
1076//=======================================================================
1077//function : AllowOverlapDetection
1078//purpose : Sets the detection type: if theIsToAllow is false,
1079// only fully included sensitives will be detected, otherwise
1080// the algorithm will mark both included and overlapped entities
1081// as matched
1082//=======================================================================
1083void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
1084{
1085 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
1086}
0904aa63 1087
1088//=======================================================================
1089//function : DumpJson
1090//purpose :
1091//=======================================================================
bc73b006 1092void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
0904aa63 1093{
bc73b006 1094 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
0904aa63 1095
bc73b006 1096 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, preferclosest)
1097 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToUpdateTolerance)
1098 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mystored.Extent())
0904aa63 1099
bc73b006 1100 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectingVolumeMgr)
1101 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectableObjects)
1102
1103 Standard_Integer aNbOfSelectableObjects = 0;
0904aa63 1104 for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
1105 {
bc73b006 1106 aNbOfSelectableObjects++;
0904aa63 1107 }
bc73b006 1108 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, aNbOfSelectableObjects)
1109
1110 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.Tolerance())
1111 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.CustomTolerance())
1112 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZLayerOrderMap.Extent())
1113
1114 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myEntitySetBuilder.get())
1115 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraEye)
1116 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraDir)
1117 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCameraScale)
1118
1119 if (!myIndexes.IsNull())
1120 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndexes->Size())
1121
1122 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurRank)
1123 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst)
1124 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
1125 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
0904aa63 1126}