0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[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>
0ef04197 23#include <Select3D_SensitiveEntity.hxx>
f751596e 24#include <SelectBasics_PickResult.hxx>
45fc824b 25#include <SelectMgr.hxx>
f751596e 26#include <SelectMgr_EntityOwner.hxx>
e1eb39d2 27#include <SelectMgr_FrustumBuilder.hxx>
45fc824b 28#include <SelectMgr_SelectionImageFiller.hxx>
f751596e 29#include <SelectMgr_SensitiveEntitySet.hxx>
45fc824b 30#include <SelectMgr_SortCriterion.hxx>
f751596e 31#include <TColStd_Array1OfInteger.hxx>
32#include <TCollection_AsciiString.hxx>
33#include <TColStd_HArray1OfInteger.hxx>
34#include <TColStd_ListOfInteger.hxx>
45fc824b 35#include <V3d_View.hxx>
f751596e 36
e35db416 37#include <algorithm>
38
f5b72419 39IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
92efcf78 40
99ee8f1a 41namespace
42{
43 //! Comparison operator for sorting selection results
e35db416 44 class CompareResults
45 {
46 public:
99ee8f1a 47
8c36926a 48 CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& theMapOfCriterion,
49 bool theToPreferClosest)
50 : myMapOfCriterion (&theMapOfCriterion),
51 myToPreferClosest (theToPreferClosest) {}
e35db416 52
53 Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
54 {
8c36926a 55 const SelectMgr_SortCriterion& anElemLeft = myMapOfCriterion->FindFromIndex (theLeft);
56 const SelectMgr_SortCriterion& anElemRight = myMapOfCriterion->FindFromIndex (theRight);
57 if (myToPreferClosest)
58 {
59 return anElemLeft.IsCloserDepth (anElemRight);
60 }
61 else
62 {
63 return anElemLeft.IsHigherPriority (anElemRight);
64 }
e35db416 65 }
66
67 private:
99ee8f1a 68 const SelectMgr_IndexedDataMapOfOwnerCriterion* myMapOfCriterion;
8c36926a 69 bool myToPreferClosest;
e35db416 70 };
f751596e 71
fe76088c 72 static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
73}
74
75//=======================================================================
76// function : updatePoint3d
77// purpose :
78//=======================================================================
79void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
17017555 80 const SelectBasics_PickResult& thePickResult,
0ef04197 81 const Handle(Select3D_SensitiveEntity)& theEntity,
fe76088c 82 const gp_GTrsf& theInversedTrsf,
83 const SelectMgr_SelectingVolumeManager& theMgr) const
84{
e1eb39d2 85 if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Point)
4269bd1b 86 {
fe76088c 87 return;
88 }
949c9b7f 89
2615c2d7 90 bool hasNormal = false;
17017555 91 if (thePickResult.HasPickedPoint())
92 {
2615c2d7 93 theCriterion.Point = thePickResult.PickedPoint();
94 theCriterion.Normal = thePickResult.SurfaceNormal();
95 const float aNormLen2 = theCriterion.Normal.SquareModulus();
96 if (aNormLen2 > ShortRealEpsilon())
97 {
98 hasNormal = true;
99 theCriterion.Normal *= 1.0f / sqrtf (aNormLen2);
100 }
17017555 101 }
b44bf0f8 102 else if (!thePickResult.IsValid())
103 {
104 theCriterion.Point = thePickResult.PickedPoint();
105 return;
106 }
17017555 107 else
108 {
109 theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
110 }
111
fe76088c 112 gp_GTrsf anInvTrsf = theInversedTrsf;
113 if (theCriterion.Entity->HasInitLocation())
114 {
115 anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
116 }
117 if (anInvTrsf.Form() != gp_Identity)
118 {
2615c2d7 119 const gp_GTrsf anInvInvTrsd = anInvTrsf.Inverted();
120 anInvInvTrsd.Transforms (theCriterion.Point.ChangeCoord());
121 if (hasNormal)
122 {
123 Graphic3d_Mat4d aMat4;
124 anInvInvTrsd.GetMat4 (aMat4);
125 const Graphic3d_Vec4d aNormRes = aMat4 * Graphic3d_Vec4d (Graphic3d_Vec3d (theCriterion.Normal), 0.0);
126 theCriterion.Normal = Graphic3d_Vec3 (aNormRes.xyz());
127 }
f751596e 128 }
aa75c0cf 129
8c36926a 130 const Standard_Real aSensFactor = myDepthTolType == SelectMgr_TypeOfDepthTolerance_SensitivityFactor ? theEntity->SensitivityFactor() : myDepthTolerance;
131 switch (myDepthTolType)
fe76088c 132 {
8c36926a 133 case SelectMgr_TypeOfDepthTolerance_Uniform:
134 {
135 theCriterion.Tolerance = myDepthTolerance;
136 break;
137 }
138 case SelectMgr_TypeOfDepthTolerance_UniformPixels:
139 case SelectMgr_TypeOfDepthTolerance_SensitivityFactor:
140 {
f035e071 141 if (theMgr.Camera().IsNull())
8c36926a 142 {
143 // fallback for an arbitrary projection matrix
144 theCriterion.Tolerance = aSensFactor / 33.0;
145 }
f035e071 146 else if (theMgr.Camera()->IsOrthographic())
8c36926a 147 {
148 theCriterion.Tolerance = myCameraScale * aSensFactor;
149 }
150 else
151 {
152 const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ()));
153 theCriterion.Tolerance = aDistFromEye * myCameraScale * aSensFactor;
154 }
155 break;
156 }
fe76088c 157 }
f751596e 158}
159
7fd59977 160//==================================================
161// Function: Initialize
162// Purpose :
163//==================================================
8c36926a 164SelectMgr_ViewerSelector::SelectMgr_ViewerSelector()
165: myDepthTolerance (0.0),
166 myDepthTolType (SelectMgr_TypeOfDepthTolerance_SensitivityFactor),
167 myToPreferClosest (Standard_True),
8c36926a 168 myCameraScale (1.0),
169 myToPrebuildBVH (Standard_False),
6054db8a 170 myIsSorted (Standard_False),
8c36926a 171 myIsLeftChildQueuedFirst (Standard_False)
7fd59977 172{
f5b72419 173 myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
7fd59977 174}
175
7f24b768 176//=======================================================================
177// Function: SetPixelTolerance
178// Purpose :
179//=======================================================================
180void SelectMgr_ViewerSelector::SetPixelTolerance (const Standard_Integer theTolerance)
181{
182 if (myTolerances.Tolerance() == theTolerance)
183 {
184 return;
185 }
7f24b768 186 if (theTolerance < 0)
187 {
188 myTolerances.ResetDefaults();
189 }
190 else
191 {
192 myTolerances.SetCustomTolerance (theTolerance);
193 }
194}
195
7fd59977 196//==================================================
197// Function: Activate
198// Purpose :
199//==================================================
f751596e 200void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
7fd59977 201{
b5cce1ab 202 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
7fd59977 203 {
b5cce1ab 204 aSelEntIter.Value()->SetActiveForSelection();
4269bd1b 205 }
7fd59977 206
82d23ad5 207 if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
208 {
209 theSelection->SetSelectionState (SelectMgr_SOS_Activated);
7fd59977 210
82d23ad5 211 myTolerances.Add (theSelection->Sensitivity());
82d23ad5 212 }
7fd59977 213}
214
7fd59977 215//==================================================
f751596e 216// Function: Deactivate
7fd59977 217// Purpose :
218//==================================================
f751596e 219void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
4269bd1b 220{
b5cce1ab 221 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
f751596e 222 {
b5cce1ab 223 aSelEntIter.Value()->ResetSelectionActiveStatus();
7fd59977 224 }
7fd59977 225
82d23ad5 226 if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
227 {
228 theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
7fd59977 229
82d23ad5 230 myTolerances.Decrement (theSelection->Sensitivity());
82d23ad5 231 }
7fd59977 232}
233
28ee613b 234//=======================================================================
235// function: isToScaleFrustum
236// purpose : Checks if the entity given requires to scale current selecting frustum
237//=======================================================================
0ef04197 238Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity)
28ee613b 239{
e1eb39d2 240 return mySelectingVolumeMgr.IsScalableActiveVolume()
29a4908e 241 && sensitivity (theEntity) < myTolerances.Tolerance();
28ee613b 242}
243
29a4908e 244//=======================================================================
245// function: sensitivity
246// purpose : In case if custom tolerance is set, this method will return sum of entity
247// sensitivity and custom tolerance.
248//=======================================================================
0ef04197 249Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(Select3D_SensitiveEntity)& theEntity) const
29a4908e 250{
251 return myTolerances.IsCustomTolSet() ?
252 theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
253}
254
f751596e 255//=======================================================================
256// function: checkOverlap
257// purpose : Internal function that checks if a particular sensitive
258// entity theEntity overlaps current selecting volume precisely
259//=======================================================================
0ef04197 260void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity,
aa75c0cf 261 const gp_GTrsf& theInversedTrsf,
f751596e 262 SelectMgr_SelectingVolumeManager& theMgr)
7fd59977 263{
0ef04197 264 const Handle(SelectMgr_EntityOwner)& anOwner = theEntity->OwnerId();
fe525c6f 265 Handle(SelectMgr_SelectableObject) aSelectable = !anOwner.IsNull() ? anOwner->Selectable() : Handle(SelectMgr_SelectableObject)();
f751596e 266 SelectBasics_PickResult aPickResult;
3202bf1e 267 const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
3202bf1e 268 if (!isMatched
269 || anOwner.IsNull())
270 {
271 return;
272 }
273
3202bf1e 274 SelectMgr_SortCriterion aCriterion;
b1c235df 275 myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
3202bf1e 276 aCriterion.Entity = theEntity;
277 aCriterion.Priority = anOwner->Priority();
278 aCriterion.Depth = aPickResult.Depth();
279 aCriterion.MinDist = aPickResult.DistToGeomCenter();
3202bf1e 280
be7fc29e 281 if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
3202bf1e 282 {
be7fc29e 283 ++aPrevCriterion->NbOwnerMatches;
284 aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
e1eb39d2 285 if (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Box)
3202bf1e 286 {
b0afa94d 287 updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
8c36926a 288 if (aCriterion.IsCloserDepth (*aPrevCriterion))
f751596e 289 {
be7fc29e 290 *aPrevCriterion = aCriterion;
7fd59977 291 }
292 }
7fd59977 293 }
3202bf1e 294 else
295 {
be7fc29e 296 aCriterion.NbOwnerMatches = 1;
17017555 297 updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
3202bf1e 298 mystored.Add (anOwner, aCriterion);
299 }
7fd59977 300}
301
45fc824b 302//=======================================================================
303// Function: updateZLayers
304// Purpose :
305//=======================================================================
306void SelectMgr_ViewerSelector::updateZLayers (const Handle(V3d_View)& theView)
307{
308 myZLayerOrderMap.Clear();
309 TColStd_SequenceOfInteger aZLayers;
310 theView->Viewer()->GetAllZLayers (aZLayers);
311 Standard_Integer aPos = 0;
312 Standard_Boolean isPrevDepthWrite = true;
313 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aZLayers); aLayerIter.More(); aLayerIter.Next())
314 {
315 Graphic3d_ZLayerSettings aSettings = theView->Viewer()->ZLayerSettings (aLayerIter.Value());
316 if (aSettings.ToClearDepth()
317 || isPrevDepthWrite != aSettings.ToEnableDepthWrite())
318 {
319 ++aPos;
320 }
321 isPrevDepthWrite = aSettings.ToEnableDepthWrite();
322 myZLayerOrderMap.Bind (aLayerIter.Value(), aPos);
323 }
324}
325
3bf9a45f 326//=======================================================================
327// function: computeFrustum
208dc370 328// purpose :
3bf9a45f 329//=======================================================================
0ef04197 330void SelectMgr_ViewerSelector::computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt,
208dc370 331 const SelectMgr_SelectingVolumeManager& theMgrGlobal,
332 const SelectMgr_SelectingVolumeManager& theMgrObject,
333 const gp_GTrsf& theInvTrsf,
334 SelectMgr_FrustumCache& theCachedMgrs,
335 SelectMgr_SelectingVolumeManager& theResMgr)
3bf9a45f 336{
7479f643 337 Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
91d96372 338 const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
7479f643 339 const Standard_Boolean toScale = aScale != 1;
340 const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
341 if (toScale && toTransform)
3bf9a45f 342 {
208dc370 343 theResMgr = theMgrGlobal.ScaleAndTransform (aScale, aTrsfMtr, NULL);
344 theResMgr.SetViewClipping (theMgrObject);
3bf9a45f 345 }
346 else if (toScale)
347 {
208dc370 348 if (!theCachedMgrs.Find (aScale, theResMgr))
3bf9a45f 349 {
208dc370 350 theResMgr = theMgrGlobal.ScaleAndTransform (aScale, gp_Trsf(), NULL);
351 theCachedMgrs.Bind (aScale, theResMgr);
3bf9a45f 352 }
208dc370 353 theResMgr.SetViewClipping (theMgrObject);
3bf9a45f 354 }
7479f643 355 else if (toTransform)
356 {
208dc370 357 theResMgr = theMgrGlobal.ScaleAndTransform (1, aTrsfMtr, NULL);
358 theResMgr.SetViewClipping (theMgrObject);
359 }
360 else
361 {
362 theResMgr = theMgrObject;
7479f643 363 }
3bf9a45f 364}
365
f751596e 366//=======================================================================
367// function: traverseObject
368// purpose : Internal function that checks if there is possible overlap
369// between some entity of selectable object theObject and
370// current selecting volume
371//=======================================================================
099f3513 372void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
373 const SelectMgr_SelectingVolumeManager& theMgr,
374 const Handle(Graphic3d_Camera)& theCamera,
375 const Graphic3d_Mat4d& theProjectionMat,
376 const Graphic3d_Mat4d& theWorldViewMat,
4e993e4d 377 const Graphic3d_Vec2i& theWinSize)
7fd59977 378{
f5b72419 379 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
f751596e 380 if (anEntitySet->Size() == 0)
f5b72419 381 {
f751596e 382 return;
f5b72419 383 }
7fd59977 384
4e993e4d 385 const bool hasEntityTrsfPers = anEntitySet->HasEntityWithPersistence()
386 && !theCamera.IsNull();
f5b72419 387 const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
91d96372 388 gp_GTrsf aInversedTrsf;
778cd667 389 if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
825aa485 390 {
778cd667 391 if (theObject->TransformPersistence().IsNull())
825aa485 392 {
393 aInversedTrsf = theObject->InversedTransformation();
394 }
395 else
396 {
e1eb39d2 397 if (theCamera.IsNull())
398 {
399 return;
400 }
91d96372 401
4e993e4d 402 const Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera,
403 theProjectionMat, theWorldViewMat,
404 theWinSize.x(), theWinSize.y());
405 gp_GTrsf aTPers;
406 aTPers.SetMat4 (aMat);
91d96372 407 aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
825aa485 408 }
409 }
410
411 SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
099f3513 412 ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
413 : theMgr;
4e993e4d 414 if (!hasEntityTrsfPers
415 && !aMgr.OverlapsBox (aSensitivesTree->MinPoint (0),
03c9cc86 416 aSensitivesTree->MaxPoint (0)))
f751596e 417 {
418 return;
7fd59977 419 }
be7fc29e 420
fe525c6f 421 if (!theObject->ClipPlanes().IsNull()
422 && theObject->ClipPlanes()->ToOverrideGlobal())
423 {
72e9e867 424 aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
fe525c6f 425 }
426 else if (!theObject->TransformPersistence().IsNull())
427 {
428 if (theObject->TransformPersistence()->IsZoomOrRotate()
429 && !theMgr.ViewClipping().IsNull())
430 {
431 // Zoom/rotate persistence object lives in two worlds at the same time.
432 // Global clipping planes can not be trivially applied without being converted
433 // into local space of transformation persistence object.
434 // As more simple alternative - just clip entire object by its anchor point defined in the world space.
435 const gp_Pnt anAnchor = theObject->TransformPersistence()->AnchorPoint();
436 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*theMgr.ViewClipping()); aPlaneIt.More(); aPlaneIt.Next())
437 {
438 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
439 if (!aPlane->IsOn())
440 {
441 continue;
442 }
443
444 const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
445 if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
446 {
447 return;
448 }
449 }
450 }
451
72e9e867 452 aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
fe525c6f 453 }
454 else if (!theObject->ClipPlanes().IsNull()
455 && !theObject->ClipPlanes()->IsEmpty())
456 {
72e9e867 457 aMgr.SetViewClipping (theMgr.ViewClipping(), theObject->ClipPlanes(), &theMgr);
fe525c6f 458 }
459
8996b449 460 if (!theMgr.ViewClipping().IsNull() &&
e1eb39d2 461 theMgr.GetActiveSelectionType() == SelectMgr_SelectionType_Box)
8996b449 462 {
463 Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (0), aSensitivesTree->MaxPoint (0));
464 // If box selection is active, and the whole sensitive tree is out of the clip planes
465 // selection is empty for this object
466 const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
467
468 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
469 {
470 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
471 if (!aPlane->IsOn())
472 {
473 continue;
474 }
475
476 Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
477 if (aState == Graphic3d_ClipState_Out) // do not process only whole trees, next check on the tree node
478 {
479 return;
480 }
481 }
482 }
483
be7fc29e 484 const Standard_Integer aFirstStored = mystored.Extent() + 1;
485
f5b72419 486 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
f751596e 487 Standard_Integer aHead = -1;
fe525c6f 488 Standard_Integer aNode = 0; // a root node
489 SelectMgr_FrustumCache aScaledTrnsfFrustums;
e1eb39d2 490 SelectMgr_SelectingVolumeManager aTmpMgr;
f751596e 491 for (;;)
492 {
493 if (!aSensitivesTree->IsOuter (aNode))
494 {
f2474958 495 const Standard_Integer aLeftChildIdx = aSensitivesTree->Child<0> (aNode);
496 const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
4e993e4d 497 const Standard_Boolean isLeftChildIn = hasEntityTrsfPers
498 || aMgr.OverlapsBox (aSensitivesTree->MinPoint (aLeftChildIdx),
499 aSensitivesTree->MaxPoint (aLeftChildIdx));
500 const Standard_Boolean isRightChildIn = hasEntityTrsfPers
501 || aMgr.OverlapsBox (aSensitivesTree->MinPoint (aRightChildIdx),
03c9cc86 502 aSensitivesTree->MaxPoint (aRightChildIdx));
f751596e 503 if (isLeftChildIn
4e993e4d 504 && isRightChildIn)
f751596e 505 {
506 aNode = aLeftChildIdx;
507 ++aHead;
508 aStack[aHead] = aRightChildIdx;
509 }
510 else if (isLeftChildIn
511 || isRightChildIn)
512 {
513 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
514 }
515 else
516 {
517 if (aHead < 0)
518 {
519 break;
520 }
7fd59977 521
f751596e 522 aNode = aStack[aHead];
523 --aHead;
524 }
525 }
526 else
527 {
8996b449 528 bool aClipped = false;
529 if (!theMgr.ViewClipping().IsNull() &&
e1eb39d2 530 theMgr.GetActiveSelectionType() == SelectMgr_SelectionType_Box)
8996b449 531 {
532 Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (aNode), aSensitivesTree->MaxPoint (aNode));
533 // If box selection is active, and the whole sensitive tree is out of the clip planes
534 // selection is empty for this object
535 const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
536
537 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
538 {
539 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
540 if (!aPlane->IsOn())
541 {
542 continue;
543 }
544 Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
545 if (aState == Graphic3d_ClipState_Out)
546 {
547 aClipped = true;
548 break;
549 }
550 if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
551 {
552 if (aPlane->ProbeBoxTouch (aBBox))
553 continue;
554 aClipped = true;
555 break;
556 }
557 }
558 }
559 if (!aClipped)
f751596e 560 {
4e993e4d 561 const Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
562 const Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
8996b449 563 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
f751596e 564 {
8996b449 565 const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
4e993e4d 566 if (!aSensitive->IsActiveForSelection())
567 {
568 continue;
569 }
570
571 const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
572
573 gp_GTrsf aInvSensTrsf = aInversedTrsf;
574 if (!anEnt->TransformPersistence().IsNull())
8996b449 575 {
4e993e4d 576 if (theCamera.IsNull())
577 {
578 continue;
579 }
580 const Graphic3d_Mat4d aMat = anEnt->TransformPersistence()->Compute (theCamera,
581 theProjectionMat, theWorldViewMat,
582 theWinSize.x(), theWinSize.y());
583 gp_GTrsf aTPers;
584 aTPers.SetMat4 (aMat);
585 aInvSensTrsf = (aTPers * gp_GTrsf(theObject->Transformation())).Inverted();
8996b449 586 }
4e993e4d 587
588 computeFrustum (anEnt, theMgr, aMgr, aInvSensTrsf, aScaledTrnsfFrustums, aTmpMgr);
589 checkOverlap (anEnt, aInvSensTrsf, aTmpMgr);
f751596e 590 }
591 }
592 if (aHead < 0)
593 {
594 break;
595 }
7fd59977 596
f751596e 597 aNode = aStack[aHead];
598 --aHead;
599 }
7fd59977 600 }
be7fc29e 601
602 // in case of Box/Polyline selection - keep only Owners having all Entities detected
603 if (mySelectingVolumeMgr.IsOverlapAllowed()
e1eb39d2 604 || (theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Box
605 && theMgr.GetActiveSelectionType() != SelectMgr_SelectionType_Polyline))
be7fc29e 606 {
607 return;
608 }
609
610 for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter)
611 {
612 const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter);
0ef04197 613 const Handle(SelectMgr_EntityOwner)& anOwner = aCriterion.Entity->OwnerId();
be7fc29e 614 Standard_Integer aNbOwnerEntities = 0;
266877a7 615 anEntitySet->Owners().Find (anOwner, aNbOwnerEntities);
616 if (aNbOwnerEntities > aCriterion.NbOwnerMatches)
be7fc29e 617 {
266877a7 618 mystored.RemoveFromIndex (aStoredIter);
be7fc29e 619 }
620 }
7fd59977 621}
622
f751596e 623//=======================================================================
624// function: TraverseSensitives
625// purpose : Traverses BVH containing all added selectable objects and
626// finds candidates for further search of overlap
627//=======================================================================
86d6c284 628void SelectMgr_ViewerSelector::TraverseSensitives (const Standard_Integer theViewId)
7fd59977 629{
6a2fb7a1 630 SelectMgr_BVHThreadPool::Sentry aSentry (myBVHThreadPool);
631
7fd59977 632 mystored.Clear();
6054db8a 633 myIsSorted = false;
7fd59977 634
4e993e4d 635 Graphic3d_Vec2i aWinSize;
636 mySelectingVolumeMgr.WindowSize (aWinSize.x(), aWinSize.y());
f035e071 637 const double aPixelSize = aWinSize.x() > 0 && aWinSize.y() > 0
638 ? Max (1.0 / aWinSize.x(), 1.0 / aWinSize.y())
639 : 1.0;
51d4a4f9 640
fe76088c 641 const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
51d4a4f9 642 Graphic3d_Mat4d aProjectionMat, aWorldViewMat;
643 Graphic3d_WorldViewProjState aViewState;
fe76088c 644 if (!aCamera.IsNull())
645 {
51d4a4f9 646 aProjectionMat = aCamera->ProjectionMatrix();
647 aWorldViewMat = aCamera->OrientationMatrix();
648 aViewState = aCamera->WorldViewProjState();
649
fe76088c 650 myCameraEye = aCamera->Eye().XYZ();
651 myCameraDir = aCamera->Direction().XYZ();
fe76088c 652 }
4e993e4d 653 mySelectableObjects.UpdateBVH (aCamera, aWinSize);
099f3513 654
655 for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
f751596e 656 {
807340d9 657 const SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset = (SelectMgr_SelectableObjectSet::BVHSubset )aBVHSetIt;
099f3513 658 if (mySelectableObjects.IsEmpty (aBVHSubset))
4269bd1b 659 {
099f3513 660 continue;
661 }
807340d9 662 if (aCamera.IsNull()
663 && aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_3d)
664 {
665 continue;
666 }
099f3513 667
e1eb39d2 668 SelectMgr_SelectingVolumeManager aMgr;
099f3513 669
807340d9 670 // for 2D space selection transform selecting volumes to perform overlap testing
099f3513 671 // directly in camera's eye space omitting the camera position, which is not
672 // needed there at all
f035e071 673 if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
674 || aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_ortho2dPersistent)
099f3513 675 {
51d4a4f9 676 gp_GTrsf aTFrustum;
677 aTFrustum.SetValue (1, 1, aWorldViewMat.GetValue (0, 0));
678 aTFrustum.SetValue (1, 2, aWorldViewMat.GetValue (0, 1));
679 aTFrustum.SetValue (1, 3, aWorldViewMat.GetValue (0, 2));
680 aTFrustum.SetValue (2, 1, aWorldViewMat.GetValue (1, 0));
681 aTFrustum.SetValue (2, 2, aWorldViewMat.GetValue (1, 1));
682 aTFrustum.SetValue (2, 3, aWorldViewMat.GetValue (1, 2));
683 aTFrustum.SetValue (3, 1, aWorldViewMat.GetValue (2, 0));
684 aTFrustum.SetValue (3, 2, aWorldViewMat.GetValue (2, 1));
685 aTFrustum.SetValue (3, 3, aWorldViewMat.GetValue (2, 2));
686 aTFrustum.SetTranslationPart (gp_XYZ (aWorldViewMat.GetValue (0, 3),
687 aWorldViewMat.GetValue (1, 3),
688 aWorldViewMat.GetValue (2, 3)));
099f3513 689
f035e071 690 // define corresponding frustum builder parameters for 2d persistence.
099f3513 691 Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
51d4a4f9 692 Handle(Graphic3d_Camera) aNewCamera = new Graphic3d_Camera();
693 aNewCamera->CopyMappingData (aCamera);
694 aNewCamera->SetIdentityOrientation();
f035e071 695 if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_ortho2dPersistent)
696 {
697 aNewCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
698 }
51d4a4f9 699 aWorldViewMat = aNewCamera->OrientationMatrix(); // should be identity matrix
700 aProjectionMat = aNewCamera->ProjectionMatrix(); // should be the same to aProjectionMat
701 aBuilder->SetCamera (aNewCamera);
4e993e4d 702 aBuilder->SetWindowSize (aWinSize.x(), aWinSize.y());
099f3513 703 aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
825aa485 704 }
f035e071 705 else if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_ortho3dPersistent)
706 {
707 // define corresponding frustum builder parameters for 3d orthographic persistence.
708 Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
709 Handle(Graphic3d_Camera) aNewCamera = new Graphic3d_Camera (*aCamera);
710 aNewCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
711 aWorldViewMat = aNewCamera->OrientationMatrix(); // should be the same to aWorldViewMat
712 aProjectionMat = aNewCamera->ProjectionMatrix(); // should be orthographic projection
713 aBuilder->SetCamera (aNewCamera);
714 aBuilder->SetWindowSize (aWinSize.x(), aWinSize.y());
715 aMgr = mySelectingVolumeMgr.CopyWithBuilder (aBuilder);
716 }
825aa485 717 else
718 {
099f3513 719 aMgr = mySelectingVolumeMgr;
825aa485 720 }
721
f035e071 722 if (!aMgr.Camera().IsNull())
723 {
724 myCameraScale = aMgr.Camera()->IsOrthographic()
725 ? aMgr.Camera()->Scale()
726 : 2.0 * Tan (aMgr.Camera()->FOVy() * M_PI / 360.0);
727 myCameraScale *= aPixelSize;
728 }
729
f5b72419 730 const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
099f3513 731
825aa485 732 Standard_Integer aNode = 0;
03c9cc86 733 if (!aMgr.OverlapsBox (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
825aa485 734 {
735 continue;
736 }
737
f5b72419 738 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
825aa485 739 Standard_Integer aHead = -1;
740 for (;;)
741 {
742 if (!aBVHTree->IsOuter (aNode))
743 {
f2474958 744 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
745 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
825aa485 746 const Standard_Boolean isLeftChildIn =
03c9cc86 747 aMgr.OverlapsBox (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
825aa485 748 const Standard_Boolean isRightChildIn =
03c9cc86 749 aMgr.OverlapsBox (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
825aa485 750 if (isLeftChildIn
751 && isRightChildIn)
752 {
753 aNode = aLeftChildIdx;
754 ++aHead;
755 aStack[aHead] = aRightChildIdx;
756 }
757 else if (isLeftChildIn
758 || isRightChildIn)
759 {
760 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
761 }
762 else
763 {
764 if (aHead < 0)
765 {
766 break;
767 }
768
769 aNode = aStack[aHead];
770 --aHead;
771 }
f751596e 772 }
773 else
774 {
86d6c284 775 const Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
776 const Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
825aa485 777 for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
778 {
86d6c284 779 const Handle(SelectMgr_SelectableObject)& aSelObj = mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
780 const Handle(Graphic3d_ViewAffinity)& aViewAffinity = aSelObj->ViewAffinity();
781 if (theViewId == -1 || aViewAffinity->IsVisible (theViewId))
782 {
783 traverseObject (aSelObj, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWinSize);
784 }
825aa485 785 }
f751596e 786 if (aHead < 0)
4269bd1b 787 {
f751596e 788 break;
4269bd1b 789 }
7fd59977 790
f751596e 791 aNode = aStack[aHead];
792 --aHead;
7fd59977 793 }
794 }
7fd59977 795 }
4269bd1b 796
f751596e 797 SortResult();
7fd59977 798}
4269bd1b 799
8a590580 800//==================================================
801// Function: ClearPicked
802// Purpose :
803//==================================================
804void SelectMgr_ViewerSelector::ClearPicked()
805{
806 mystored.Clear();
6054db8a 807 myIsSorted = true;
808}
809
810//==================================================
811// Function: RemovePicked
812// Purpose :
813//==================================================
814bool SelectMgr_ViewerSelector::RemovePicked (const Handle(SelectMgr_SelectableObject)& theObject)
815{
816 if (mystored.IsEmpty()
817 || !mySelectableObjects.Contains (theObject))
818 {
819 return false;
820 }
821
822 bool isRemoved = false;
823 for (Standard_Integer aPickIter = 1; aPickIter <= mystored.Extent(); ++aPickIter)
824 {
825 const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (aPickIter);
826 if (!aStoredOwner.IsNull()
827 && aStoredOwner->IsSameSelectable (theObject))
828 {
829 mystored.RemoveFromIndex (aPickIter);
830 --aPickIter;
831 isRemoved = true;
832 }
833 }
834 if (isRemoved)
835 {
836 myIsSorted = false;
837 }
838 return isRemoved;
8a590580 839}
840
7fd59977 841//=======================================================================
aa75c0cf 842//function : Picked
4269bd1b 843//purpose :
7fd59977 844//=======================================================================
aa75c0cf 845Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
7fd59977 846{
aa75c0cf 847 if (theRank < 1 || theRank > NbPicked())
848 {
0ef04197 849 return Handle(SelectMgr_EntityOwner)();
7fd59977 850 }
851
6054db8a 852 if (!myIsSorted)
853 {
854 SortResult();
855 }
856
857 const Standard_Integer anOwnerIdx = myIndexes.Value (theRank);
0ef04197 858 const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
859 return aStoredOwner;
7fd59977 860}
861
7fd59977 862//=======================================================================
aa75c0cf 863//function : PickedData
4269bd1b 864//purpose :
7fd59977 865//=======================================================================
aa75c0cf 866const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
7fd59977 867{
aa75c0cf 868 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
6054db8a 869 if (!myIsSorted)
870 {
871 SortResult();
872 }
873
874 const Standard_Integer anOwnerIdx = myIndexes.Value (theRank);
aa75c0cf 875 return mystored.FindFromIndex (anOwnerIdx);
7fd59977 876}
877
7fd59977 878//===================================================
879//
880// INTERNAL METHODS ....
881//
882//==================================================
883
f5b72419 884//==================================================
885// Function: SetEntitySetBuilder
886// Purpose :
887//==================================================
888void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
889{
890 myEntitySetBuilder = theBuilder;
891 for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
892 {
893 aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
894 }
895}
896
7fd59977 897//==================================================
898// Function: Contains
4269bd1b 899// Purpose :
7fd59977 900//==================================================
f751596e 901Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
7fd59977 902{
099f3513 903 return mySelectableObjects.Contains (theObject);
7fd59977 904}
905
7fd59977 906//==================================================
907// Function: ActiveModes
908// Purpose : return all the modes with a given state for an object
909//==================================================
f751596e 910Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
911 TColStd_ListOfInteger& theModeList,
912 const SelectMgr_StateOfSelection theWantedState) const
7fd59977 913{
825aa485 914 Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
b5cce1ab 915 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
f751596e 916 {
82d23ad5 917 if (theWantedState == SelectMgr_SOS_Any)
918 {
919 theModeList.Append (aSelIter.Value()->Mode());
920 }
921 else if (theWantedState == aSelIter.Value()->GetSelectionState())
922 {
923 theModeList.Append (aSelIter.Value()->Mode());
924 }
7fd59977 925 }
7fd59977 926
f751596e 927 return hasActivatedStates;
928}
7fd59977 929
f751596e 930//==================================================
931// Function: IsActive
932// Purpose :
933//==================================================
934Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
935 const Standard_Integer theMode) const
7fd59977 936{
825aa485 937 if (!Contains (theSelectableObject))
f751596e 938 return Standard_False;
939
b5cce1ab 940 const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
941 return !aSel.IsNull()
942 && aSel->GetSelectionState() == SelectMgr_SOS_Activated;
7fd59977 943}
944
f751596e 945//==================================================
946// Function: IsInside
947// Purpose :
948//==================================================
949Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
950 const Standard_Integer theMode) const
7fd59977 951{
825aa485 952 if (!Contains (theSelectableObject))
f751596e 953 return Standard_False;
7fd59977 954
b5cce1ab 955 const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
956 return !aSel.IsNull()
957 && aSel->GetSelectionState() != SelectMgr_SOS_Unknown;
7fd59977 958}
959
960
961//=======================================================================
962//function : Status
4269bd1b 963//purpose :
7fd59977 964//=======================================================================
965
f751596e 966SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
7fd59977 967{
f751596e 968 return theSelection->GetSelectionState();
7fd59977 969}
970
7fd59977 971//==================================================
972// Function: Status
973// Purpose : gives Information about selectors
974//==================================================
975
f751596e 976TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
7fd59977 977{
f751596e 978 TCollection_AsciiString aStatus ("Status Object :\n\t");
b5cce1ab 979 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
f751596e 980 {
b5cce1ab 981 if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown)
7fd59977 982 {
b5cce1ab 983 aStatus = aStatus + "Mode " + TCollection_AsciiString (aSelIter.Value()->Mode()) + " present - "
984 + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" : " Inactive \n\t");
7fd59977 985 }
986 }
987
825aa485 988 if (!Contains (theSelectableObject))
7fd59977 989 {
f751596e 990 aStatus = aStatus + "Not Present in the selector\n\n";
7fd59977 991 }
f751596e 992
993 return aStatus;
7fd59977 994}
995
996//=======================================================================
997//function : SortResult
8c36926a 998//purpose :
7fd59977 999//=======================================================================
6054db8a 1000void SelectMgr_ViewerSelector::SortResult() const
7fd59977 1001{
8c36926a 1002 if (mystored.IsEmpty())
1003 {
6054db8a 1004 myIsSorted = true;
8c36926a 1005 return;
1006 }
7fd59977 1007
1008 const Standard_Integer anExtent = mystored.Extent();
6054db8a 1009 if (anExtent != myIndexes.Length())
8c36926a 1010 {
6054db8a 1011 myIndexes.Resize (1, anExtent, false);
8c36926a 1012 }
7fd59977 1013
f5b72419 1014 for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
1015 {
6054db8a 1016 myIndexes.SetValue (anIndexIter, anIndexIter);
f5b72419 1017 }
6054db8a 1018 std::sort (myIndexes.begin(), myIndexes.end(), CompareResults (mystored, myToPreferClosest));
1019 myIsSorted = true;
f751596e 1020}
1021
f751596e 1022//=======================================================================
1023// function : AddSelectableObject
1024// purpose : Adds new object to the map of selectable objects
1025//=======================================================================
1026void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
1027{
1028 if (!myMapOfObjectSensitives.IsBound (theObject))
1029 {
099f3513 1030 mySelectableObjects.Append (theObject);
f5b72419 1031 Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
f751596e 1032 myMapOfObjectSensitives.Bind (theObject, anEntitySet);
7fd59977 1033 }
f751596e 1034}
7fd59977 1035
f751596e 1036//=======================================================================
1037// function : AddSelectionToObject
1038// purpose : Adds new selection to the object and builds its BVH tree
1039//=======================================================================
1040void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
1041 const Handle(SelectMgr_Selection)& theSelection)
1042{
f5b72419 1043 if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
f751596e 1044 {
f5b72419 1045 (*anEntitySet)->Append (theSelection);
1046 (*anEntitySet)->BVH();
f751596e 1047 }
1048 else
1049 {
1050 AddSelectableObject (theObject);
1051 AddSelectionToObject (theObject, theSelection);
1052 }
7fd59977 1053}
1054
1d92133e 1055//=======================================================================
1056// function : MoveSelectableObject
1057// purpose :
1058//=======================================================================
1059void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
1060{
099f3513 1061 mySelectableObjects.ChangeSubset (theObject);
1d92133e 1062}
1063
f751596e 1064//=======================================================================
1065// function : RemoveSelectableObject
1066// purpose : Removes selectable object from map of selectable ones
1067//=======================================================================
1068void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
1069{
f5b72419 1070 if (myMapOfObjectSensitives.UnBind (theObject))
f751596e 1071 {
6054db8a 1072 RemovePicked (theObject);
099f3513 1073 mySelectableObjects.Remove (theObject);
f751596e 1074 }
1075}
7fd59977 1076
1077//=======================================================================
f751596e 1078// function : RemoveSelectionOfObject
1079// purpose : Removes selection of the object and marks its BVH tree
1080// for rebuild
7fd59977 1081//=======================================================================
f751596e 1082void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
1083 const Handle(SelectMgr_Selection)& theSelection)
7fd59977 1084{
f5b72419 1085 if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
f751596e 1086 {
f5b72419 1087 (*anEntitySet)->Remove (theSelection);
f751596e 1088 }
7fd59977 1089}
1090
1091//=======================================================================
f751596e 1092// function : RebuildObjectsTree
1093// purpose : Marks BVH of selectable objects for rebuild
7fd59977 1094//=======================================================================
f751596e 1095void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
7fd59977 1096{
825aa485 1097 mySelectableObjects.MarkDirty();
f751596e 1098
1099 if (theIsForce)
1100 {
4e993e4d 1101 Graphic3d_Vec2i aWinSize;
1102 mySelectingVolumeMgr.WindowSize (aWinSize.x(), aWinSize.y());
1103 mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(), aWinSize);
f751596e 1104 }
7fd59977 1105}
4269bd1b 1106
1107//=======================================================================
f751596e 1108// function : RebuildSensitivesTree
1109// purpose : Marks BVH of sensitive entities of particular selectable
1110// object for rebuild
4269bd1b 1111//=======================================================================
f751596e 1112void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
1113 const Standard_Boolean theIsForce)
4269bd1b 1114{
825aa485 1115 if (!Contains (theObject))
f751596e 1116 return;
1117
f5b72419 1118 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
f751596e 1119 anEntitySet->MarkDirty();
1120
1121 if (theIsForce)
1122 {
1123 anEntitySet->BVH();
1124 }
4269bd1b 1125}
1126
1127//=======================================================================
f751596e 1128// function : resetSelectionActivationStatus
1129// purpose : Marks all added sensitive entities of all objects as
1130// non-selectable
4269bd1b 1131//=======================================================================
29a4908e 1132void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
4269bd1b 1133{
f5b72419 1134 for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
f751596e 1135 {
f5b72419 1136 Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
1137 const Standard_Integer anEntitiesNb = anEntitySet->Size();
f751596e 1138 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
1139 {
1140 anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
1141 }
1142 }
4269bd1b 1143}
1144
4269bd1b 1145//=======================================================================
f751596e 1146// function : ActiveOwners
1147// purpose : Returns the list of active entity owners
4269bd1b 1148//=======================================================================
0ef04197 1149void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const
4269bd1b 1150{
f751596e 1151 for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
1152 {
f5b72419 1153 const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
1154 const Standard_Integer anEntitiesNb = anEntitySet->Size();
f751596e 1155 for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
1156 {
f5b72419 1157 const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
1158 if (aSensitive->IsActiveForSelection())
f751596e 1159 {
f5b72419 1160 theOwners.Append (aSensitive->BaseSensitive()->OwnerId());
f751596e 1161 }
1162 }
1163 }
4269bd1b 1164}
29a4908e 1165
1166//=======================================================================
1167//function : AllowOverlapDetection
1168//purpose : Sets the detection type: if theIsToAllow is false,
1169// only fully included sensitives will be detected, otherwise
1170// the algorithm will mark both included and overlapped entities
1171// as matched
1172//=======================================================================
1173void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
1174{
1175 mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
1176}
0904aa63 1177
45fc824b 1178//=======================================================================
1179// Function: Pick
1180// Purpose :
1181//=======================================================================
1182void SelectMgr_ViewerSelector::Pick (const Standard_Integer theXPix,
1183 const Standard_Integer theYPix,
1184 const Handle(V3d_View)& theView)
1185{
1186 updateZLayers (theView);
1187
1188 gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
1189 static_cast<Standard_Real> (theYPix));
1190 mySelectingVolumeMgr.InitPointSelectingVolume (aMousePos);
1191
1192 mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
1193 mySelectingVolumeMgr.SetCamera (theView->Camera());
1194 Standard_Integer aWidth = 0, aHeight = 0;
1195 theView->Window()->Size (aWidth, aHeight);
1196 mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
1197
1198 mySelectingVolumeMgr.BuildSelectingVolume();
1199 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
1200
86d6c284 1201 TraverseSensitives (theView->View()->Identification());
45fc824b 1202}
1203
1204//=======================================================================
1205// Function: Pick
1206// Purpose :
1207//=======================================================================
1208void SelectMgr_ViewerSelector::Pick (const Standard_Integer theXPMin,
1209 const Standard_Integer theYPMin,
1210 const Standard_Integer theXPMax,
1211 const Standard_Integer theYPMax,
1212 const Handle(V3d_View)& theView)
1213{
1214 updateZLayers (theView);
1215
1216 gp_Pnt2d aMinMousePos (static_cast<Standard_Real> (theXPMin),
1217 static_cast<Standard_Real> (theYPMin));
1218 gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXPMax),
1219 static_cast<Standard_Real> (theYPMax));
1220 mySelectingVolumeMgr.InitBoxSelectingVolume (aMinMousePos,
1221 aMaxMousePos);
1222
1223 mySelectingVolumeMgr.SetCamera (theView->Camera());
1224 Standard_Integer aWidth = 0, aHeight = 0;
1225 theView->Window()->Size (aWidth, aHeight);
1226 mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
1227
1228 mySelectingVolumeMgr.BuildSelectingVolume();
1229 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
86d6c284 1230 TraverseSensitives (theView->View()->Identification());
45fc824b 1231}
1232
1233//=======================================================================
1234// Function: Pick
1235// Purpose : Selection using a polyline
1236//=======================================================================
1237void SelectMgr_ViewerSelector::Pick (const TColgp_Array1OfPnt2d& thePolyline,
1238 const Handle(V3d_View)& theView)
1239{
1240 updateZLayers (theView);
1241
1242 mySelectingVolumeMgr.InitPolylineSelectingVolume (thePolyline);
1243 mySelectingVolumeMgr.SetCamera (theView->Camera());
1244 Standard_Integer aWidth = 0, aHeight = 0;
1245 theView->Window()->Size (aWidth, aHeight);
1246 mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
1247 mySelectingVolumeMgr.BuildSelectingVolume();
1248 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
1249
86d6c284 1250 TraverseSensitives (theView->View()->Identification());
45fc824b 1251}
1252
1253//=======================================================================
1254// Function: Pick
1255// Purpose :
1256//=======================================================================
1257void SelectMgr_ViewerSelector::Pick (const gp_Ax1& theAxis,
1258 const Handle(V3d_View)& theView)
1259{
1260 updateZLayers (theView);
1261
1262 mySelectingVolumeMgr.InitAxisSelectingVolume (theAxis);
1263 mySelectingVolumeMgr.BuildSelectingVolume();
1264 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)(), NULL);
1265
86d6c284 1266 TraverseSensitives (theView->View()->Identification());
45fc824b 1267}
1268
1269//=======================================================================
1270//function : ToPixMap
1271//purpose :
1272//=======================================================================
1273Standard_Boolean SelectMgr_ViewerSelector::ToPixMap (Image_PixMap& theImage,
1274 const Handle(V3d_View)& theView,
1275 const StdSelect_TypeOfSelectionImage theType,
1276 const Standard_Integer thePickedIndex)
1277{
1278 if (theImage.IsEmpty())
1279 {
1280 throw Standard_ProgramError ("SelectMgr_ViewerSelector::ToPixMap() has been called with empty image");
1281 }
1282
1283 Handle(SelectMgr_SelectionImageFiller) aFiller = SelectMgr_SelectionImageFiller::CreateFiller (theImage, this, theType);
1284 if (aFiller.IsNull())
1285 {
1286 return Standard_False;
1287 }
1288
1289 const Standard_Integer aSizeX = static_cast<Standard_Integer> (theImage.SizeX());
1290 const Standard_Integer aSizeY = static_cast<Standard_Integer> (theImage.SizeY());
1291 for (Standard_Integer aRowIter = 0; aRowIter < aSizeY; ++aRowIter)
1292 {
1293 for (Standard_Integer aColIter = 0; aColIter < aSizeX; ++aColIter)
1294 {
1295 Pick (aColIter, aRowIter, theView);
1296 aFiller->Fill (aColIter, aRowIter, thePickedIndex);
1297 }
1298 }
1299 aFiller->Flush();
1300 return Standard_True;
1301}
1302
1303//=======================================================================
1304// Function: DisplaySensitive.
1305// Purpose : Display active primitives.
1306//=======================================================================
1307void SelectMgr_ViewerSelector::DisplaySensitive (const Handle(V3d_View)& theView)
1308{
1309 for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
1310 {
1311 Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
1312 const Handle (SelectMgr_SelectableObject)& anObj = aSelectableIt.Value();
1313 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
1314 {
1315 if (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated)
1316 {
1317 SelectMgr::ComputeSensitivePrs (aStruct, aSelIter.Value(), anObj->Transformation(), anObj->TransformPersistence());
1318 }
1319 }
1320
1321 myStructs.Append (aStruct);
1322 }
1323
1324 for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
1325 {
1326 Handle(Graphic3d_Structure)& aStruct = aStructIter.ChangeValue();
e463b2f6 1327 aStruct->SetDisplayPriority (Graphic3d_DisplayPriority_Topmost);
45fc824b 1328 aStruct->Display();
1329 }
1330
1331 theView->Update();
1332}
1333
1334//=======================================================================
1335// Function: ClearSensitive
1336// Purpose :
1337//=======================================================================
1338void SelectMgr_ViewerSelector::ClearSensitive (const Handle(V3d_View)& theView)
1339{
1340 for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
1341 {
1342 const Handle(Graphic3d_Structure)& aPrs = aStructIter.ChangeValue();
1343 aPrs->Erase();
1344 aPrs->Clear();
1345 aPrs->Remove();
1346 }
1347 myStructs.Clear();
1348
1349 if (!theView.IsNull())
1350 {
1351 theView->Update();
1352 }
1353}
1354
1355//=======================================================================
1356//function : DisplaySenstive
1357//purpose :
1358//=======================================================================
1359void SelectMgr_ViewerSelector::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
1360 const gp_Trsf& theTrsf,
1361 const Handle(V3d_View)& theView,
1362 const Standard_Boolean theToClearOthers)
1363{
1364 if (theToClearOthers)
1365 {
1366 ClearSensitive (theView);
1367 }
1368
1369 Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
1370
1371 SelectMgr::ComputeSensitivePrs (aStruct, theSel, theTrsf, Handle(Graphic3d_TransformPers)());
1372
1373 myStructs.Append (aStruct);
e463b2f6 1374 myStructs.Last()->SetDisplayPriority (Graphic3d_DisplayPriority_Topmost);
45fc824b 1375 myStructs.Last()->Display();
1376
1377 theView->Update();
1378}
1379
0904aa63 1380//=======================================================================
1381//function : DumpJson
1382//purpose :
1383//=======================================================================
bc73b006 1384void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
0904aa63 1385{
bc73b006 1386 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
0904aa63 1387
8c36926a 1388 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToPreferClosest)
bc73b006 1389 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mystored.Extent())
0904aa63 1390
a5162275 1391 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &mySelectingVolumeMgr)
bc73b006 1392 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectableObjects)
1393
1394 Standard_Integer aNbOfSelectableObjects = 0;
0904aa63 1395 for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
1396 {
bc73b006 1397 aNbOfSelectableObjects++;
0904aa63 1398 }
bc73b006 1399 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, aNbOfSelectableObjects)
1400
1401 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.Tolerance())
1402 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.CustomTolerance())
1403 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZLayerOrderMap.Extent())
1404
1405 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myEntitySetBuilder.get())
1406 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraEye)
1407 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraDir)
1408 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCameraScale)
1409
6054db8a 1410 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndexes.Size())
bc73b006 1411
bc73b006 1412 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst)
bc73b006 1413 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
45fc824b 1414
1415 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myStructs.Length())
1416 for (Graphic3d_SequenceOfStructure::Iterator aStructsIt (myStructs); aStructsIt.More(); aStructsIt.Next())
1417 {
1418 const Handle(Graphic3d_Structure)& aStructure = aStructsIt.Value();
1419 OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, aStructure)
1420 }
0904aa63 1421}
6a2fb7a1 1422
1423//=======================================================================
1424//function : SetToPrebuildBVH
1425//purpose :
1426//=======================================================================
1427void SelectMgr_ViewerSelector::SetToPrebuildBVH (Standard_Boolean theToPrebuild, Standard_Integer theThreadsNum)
1428{
1429 if (!theToPrebuild && !myBVHThreadPool.IsNull())
1430 {
1431 myBVHThreadPool.Nullify();
1432 }
1433 else if (theToPrebuild)
1434 {
1435 myBVHThreadPool = new SelectMgr_BVHThreadPool (theThreadsNum);
1436 }
1437 myToPrebuildBVH = theToPrebuild;
1438}
1439
1440//=======================================================================
1441//function : QueueBVHBuild
1442//purpose :
1443//=======================================================================
1444void SelectMgr_ViewerSelector::QueueBVHBuild (const Handle(Select3D_SensitiveEntity)& theEntity)
1445{
1446 if (myToPrebuildBVH)
1447 {
1448 myBVHThreadPool->AddEntity (theEntity);
1449 }
1450}
1451
1452//=======================================================================
1453//function : WaitForBVHBuild
1454//purpose :
1455//=======================================================================
1456void SelectMgr_ViewerSelector::WaitForBVHBuild()
1457{
1458 if (myToPrebuildBVH)
1459 {
1460 myBVHThreadPool->WaitThreads();
1461 }
1462}