0024947: Redesign OCCT legacy type system -- automatic
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
1 // Created on: 1995-02-15
2 // Created by: Roberc Coublanc
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified by  ...
18 //              ROB JAN/07/98 : Improve Storage of detected entities
19 //              AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
20
21 #include <BVH_Tree.hxx>
22 #include <gp_Pnt.hxx>
23 #include <OSD_Environment.hxx>
24 #include <Precision.hxx>
25 #include <SelectMgr_ViewerSelector.hxx>
26 #include <SelectMgr_CompareResults.hxx>
27 #include <SelectBasics_EntityOwner.hxx>
28 #include <SelectBasics_SensitiveEntity.hxx>
29 #include <SelectBasics_PickResult.hxx>
30 #include <SelectMgr_EntityOwner.hxx>
31 #include <SelectMgr_SortCriterion.hxx>
32 #include <SelectMgr_SensitiveEntitySet.hxx>
33 #include <SortTools_QuickSortOfInteger.hxx>
34 #include <TColStd_Array1OfInteger.hxx>
35 #include <TCollection_AsciiString.hxx>
36 #include <TColStd_HArray1OfInteger.hxx>
37 #include <TColStd_ListOfInteger.hxx>
38
39
40 //=======================================================================
41 // function: SelectMgr_ToleranceMap
42 // purpose : Sets tolerance values to -1.0
43 //=======================================================================
44 SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
45 {
46   myLargestKey = -1.0;
47   myCustomTolerance = -1.0;
48 }
49
50 //=======================================================================
51 // function: ~SelectMgr_ToleranceMap
52 // purpose :
53 //=======================================================================
54 SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
55 {
56   myTolerances.Clear();
57 }
58
59 //=======================================================================
60 // function: Add
61 // purpose : Adds the value given to map, checks if the current tolerance value
62 //           should be replaced by theTolerance
63 //=======================================================================
64 void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
65 {
66   if (myTolerances.IsBound (theTolerance))
67   {
68     Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
69     aFreq++;
70
71     if (aFreq == 1 && theTolerance != myLargestKey)
72       myLargestKey = Max (theTolerance, myLargestKey);
73   }
74   else
75   {
76     if (myTolerances.IsEmpty())
77     {
78       myTolerances.Bind (theTolerance, 1);
79       myLargestKey = theTolerance;
80       return;
81     }
82
83     myTolerances.Bind (theTolerance, 1);
84     myLargestKey = Max (theTolerance, myLargestKey);
85   }
86 }
87
88 //=======================================================================
89 // function: Decrement
90 // purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
91 //           should be recalculated
92 //=======================================================================
93 void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
94 {
95   if (myTolerances.IsBound (theTolerance))
96   {
97     Standard_Integer& aFreq = myTolerances.ChangeFind (theTolerance);
98     aFreq--;
99
100     if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
101     {
102       myLargestKey = 0.0;
103       for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
104       {
105         if (anIter.Value() != 0)
106           myLargestKey = Max (myLargestKey, anIter.Key());
107       }
108     }
109   }
110 }
111
112 //=======================================================================
113 // function: Tolerance
114 // purpose : Returns a current tolerance that must be applied
115 //=======================================================================
116 Standard_Real SelectMgr_ToleranceMap::Tolerance()
117 {
118   return myCustomTolerance < 0.0 ? myLargestKey : myCustomTolerance;
119 }
120
121 //=======================================================================
122 // function: SetCustomTolerance
123 // purpose : Sets tolerance to the given one and disables adaptive checks
124 //=======================================================================
125 void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance)
126 {
127   myCustomTolerance = theTolerance;
128 }
129
130 //=======================================================================
131 // function: ResetDefaults
132 // purpose : Unsets a custom tolerance and enables adaptive checks
133 //=======================================================================
134 void SelectMgr_ToleranceMap::ResetDefaults()
135 {
136   myCustomTolerance = -1.0;
137 }
138
139 //==================================================
140 // Function: Initialize
141 // Purpose :
142 //==================================================
143 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
144 preferclosest(Standard_True),
145 mytolerance(2.0),
146 myToUpdateTolerance (Standard_True),
147 myCurRank (0),
148 myIsLeftChildQueuedFirst (Standard_False),
149 myEntityIdx (0)
150 {
151   mySelectableObjects = new SelectMgr_SelectableObjectSet();
152 }
153
154
155 //==================================================
156 // Function: Activate
157 // Purpose :
158 //==================================================
159 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
160 {
161   for (theSelection->Init(); theSelection->More(); theSelection->Next())
162   {
163     theSelection->Sensitive()->SetActiveForSelection();
164   }
165
166   theSelection->SetSelectionState (SelectMgr_SOS_Activated);
167
168   myTolerances.Add (theSelection->Sensitivity());
169   mytolerance = myTolerances.Tolerance();
170   myToUpdateTolerance = Standard_True;
171 }
172
173
174 //==================================================
175 // Function: Deactivate
176 // Purpose :
177 //==================================================
178 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
179 {
180   for (theSelection->Init(); theSelection->More(); theSelection->Next())
181   {
182     theSelection->Sensitive()->ResetSelectionActiveStatus();
183   }
184
185   theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
186
187   myTolerances.Decrement (theSelection->Sensitivity());
188   mytolerance = myTolerances.Tolerance();
189   myToUpdateTolerance = Standard_True;
190 }
191
192 //==================================================
193 // Function: Clear
194 // Purpose :
195 //==================================================
196 void SelectMgr_ViewerSelector::Clear()
197 {
198   mystored.Clear();
199   myMapOfDetected.Clear();
200 }
201
202 //=======================================================================
203 // function: isToScaleFrustum
204 // purpose : Checks if the entity given requires to scale current selecting frustum
205 //=======================================================================
206 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity)
207 {
208   return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
209     && theEntity->SensitivityFactor() < myTolerances.Tolerance();
210 }
211
212 //=======================================================================
213 // function: scaleAndTransform
214 // purpose : Applies given scale and transformation matrices to the default selecting volume manager
215 //=======================================================================
216 SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale,
217                                                                               const gp_Trsf& theTrsf)
218 {
219   SelectMgr_SelectingVolumeManager aMgr;
220
221   if (theScale > Precision::Angular())
222   {
223     aMgr = mySelectingVolumeMgr.Scale (theScale);
224   }
225
226   if (theTrsf.Form() != gp_Identity)
227   {
228     aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ?
229       mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf);
230   }
231
232   return aMgr;
233 }
234
235 //=======================================================================
236 // function: checkOverlap
237 // purpose : Internal function that checks if a particular sensitive
238 //           entity theEntity overlaps current selecting volume precisely
239 //=======================================================================
240 void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_SensitiveEntity)& theEntity,
241                                              const Standard_Integer theEntityIdx,
242                                              SelectMgr_SelectingVolumeManager& theMgr)
243 {
244   const Handle(SelectMgr_EntityOwner)& anOwner =
245     Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId());
246
247   SelectBasics_PickResult aPickResult;
248   if (theEntity->Matches (theMgr, aPickResult))
249   {
250     if (!anOwner.IsNull())
251     {
252       if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point)
253       {
254         Standard_Boolean isClipped = theMgr.IsClipped (anOwner->Selectable()->GetClipPlanes(),
255                                                        aPickResult.Depth());
256         if (isClipped)
257           return;
258       }
259
260       Standard_Integer aPriority = anOwner->Priority();
261
262       SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
263       if (mystored.Contains (anOwner))
264       {
265         if (theMgr.GetActiveSelectionType() != 1)
266         {
267           SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromKey (anOwner);
268           if (aCriterion > aPrevCriterion)
269           {
270             aPrevCriterion = aCriterion;
271             myMapOfDetected.ChangeFind (anOwner) = theEntityIdx;
272           }
273         }
274       }
275       else
276       {
277         mystored.Add (anOwner, aCriterion);
278         myMapOfDetected.Bind (anOwner, theEntityIdx);
279       }
280     }
281   }
282 }
283
284 //=======================================================================
285 // function: traverseObject
286 // purpose : Internal function that checks if there is possible overlap
287 //           between some entity of selectable object theObject and
288 //           current selecting volume
289 //=======================================================================
290 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject)
291 {
292   NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
293     myMapOfObjectSensitives.ChangeFind (theObject);
294
295   if (anEntitySet->Size() == 0)
296     return;
297
298   const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
299
300   SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
301     mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr;
302
303   NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
304
305   Standard_Integer aNode = 0; // a root node
306   if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
307                       aSensitivesTree->MaxPoint (0)))
308   {
309     return;
310   }
311   Standard_Integer aStack[32];
312   Standard_Integer aHead = -1;
313   for (;;)
314   {
315     if (!aSensitivesTree->IsOuter (aNode))
316     {
317       const Standard_Integer aLeftChildIdx  = aSensitivesTree->LeftChild  (aNode);
318       const Standard_Integer aRightChildIdx = aSensitivesTree->RightChild (aNode);
319       const Standard_Boolean isLeftChildIn  =  aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
320                                                               aSensitivesTree->MaxPoint (aLeftChildIdx));
321       const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
322                                                              aSensitivesTree->MaxPoint (aRightChildIdx));
323       if (isLeftChildIn
324           && isRightChildIn)
325       {
326         aNode = aLeftChildIdx;
327         ++aHead;
328         aStack[aHead] = aRightChildIdx;
329       }
330       else if (isLeftChildIn
331         || isRightChildIn)
332       {
333         aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
334       }
335       else
336       {
337         if (aHead < 0)
338         {
339           break;
340         }
341
342         aNode = aStack[aHead];
343         --aHead;
344       }
345     }
346     else
347     {
348       Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
349       Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
350       for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
351       {
352         const Handle(SelectMgr_SensitiveEntity)& aSensitive =
353           anEntitySet->GetSensitiveById (anIdx);
354         if (aSensitive->IsActiveForSelection())
355         {
356           const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
357           SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
358           if (isToScaleFrustum (anEnt))
359           {
360             if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
361             {
362               aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
363                                          scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
364             }
365
366             aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
367           }
368           checkOverlap (anEnt, anIdx, aTmpMgr);
369         }
370       }
371       if (aHead < 0)
372       {
373         break;
374       }
375
376       aNode = aStack[aHead];
377       --aHead;
378     }
379   }
380 }
381
382 //=======================================================================
383 // function: TraverseSensitives
384 // purpose : Traverses BVH containing all added selectable objects and
385 //           finds candidates for further search of overlap
386 //=======================================================================
387 void SelectMgr_ViewerSelector::TraverseSensitives()
388 {
389   mystored.Clear();
390   myMapOfDetected.Clear();
391
392   if (mySelectableObjects->Size() == 0)
393     return;
394
395   const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& anObjectsTree = mySelectableObjects->BVH();
396
397   Standard_Integer aNode = 0;
398   if (!mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (0),
399                                       anObjectsTree->MaxPoint (0)))
400   {
401     return;
402   }
403   Standard_Integer aStack[32];
404   Standard_Integer aHead = -1;
405   for (;;)
406   {
407     if (!anObjectsTree->IsOuter (aNode))
408     {
409       const Standard_Integer aLeftChildIdx  = anObjectsTree->LeftChild  (aNode);
410       const Standard_Integer aRightChildIdx = anObjectsTree->RightChild (aNode);
411       const Standard_Boolean isLeftChildIn  =
412         mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aLeftChildIdx),
413                                        anObjectsTree->MaxPoint (aLeftChildIdx));
414       const Standard_Boolean isRightChildIn =
415         mySelectingVolumeMgr.Overlaps (anObjectsTree->MinPoint (aRightChildIdx),
416                                        anObjectsTree->MaxPoint (aRightChildIdx));
417       if (isLeftChildIn
418         && isRightChildIn)
419       {
420         aNode = aLeftChildIdx;
421         ++aHead;
422         aStack[aHead] = aRightChildIdx;
423       }
424       else if (isLeftChildIn
425         || isRightChildIn)
426       {
427         aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
428       }
429       else
430       {
431         if (aHead < 0)
432         {
433           break;
434         }
435
436         aNode = aStack[aHead];
437         --aHead;
438       }
439     }
440     else
441     {
442       Standard_Integer aStartIdx = anObjectsTree->BegPrimitive (aNode);
443       Standard_Integer anEndIdx = anObjectsTree->EndPrimitive (aNode);
444       for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
445       {
446         traverseObject (mySelectableObjects->GetObjectById (anIdx));
447       }
448       if (aHead < 0)
449       {
450         break;
451       }
452
453       aNode = aStack[aHead];
454       --aHead;
455     }
456   }
457
458   SortResult();
459 }
460
461 //==================================================
462 // Function: Picked
463 // Purpose :
464 //==================================================
465 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
466 ::Picked() const
467 {
468   Standard_Integer RankInMap = myIndexes->Value (myCurRank);
469   const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
470   Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
471   return Ownr;
472 }
473
474
475
476 //=======================================================================
477 //function : More
478 //purpose  :
479 //=======================================================================
480 Standard_Boolean SelectMgr_ViewerSelector::More()
481 {
482   if(mystored.Extent()==0) return Standard_False;
483   if(myCurRank==0) return Standard_False;
484   return myCurRank <= myIndexes->Length();
485 }
486
487 //==================================================
488 // Function: OnePicked
489 // Purpose : only the best one is chosen
490 //           depend on priority and mindist...
491 //==================================================
492
493 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
494 ::OnePicked()
495 {
496
497   Init();
498   if(More()){
499     Standard_Integer RankInMap = myIndexes->Value (myIndexes->Lower());
500     const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
501     Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
502     return Ownr;
503   }
504
505   Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
506   return NullObj;
507 }
508
509
510 //=======================================================================
511 //function : NbPicked
512 //purpose  :
513 //=======================================================================
514
515 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
516 {
517   return mystored.Extent();
518 }
519 //=======================================================================
520 //function : Picked
521 //purpose  :
522 //=======================================================================
523 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
524 {
525
526   Handle(SelectMgr_EntityOwner) anOwner;
527   if (aRank < 1 || aRank > NbPicked())
528     return anOwner;
529   Standard_Integer anOwnerIdx = myIndexes->Value (aRank);
530
531
532   const Handle(SelectBasics_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
533   anOwner = Handle(SelectMgr_EntityOwner)::DownCast (aStoredOwner);
534   return anOwner;
535 }
536
537 //===================================================
538 //
539 //       INTERNAL METHODS ....
540 //
541 //==================================================
542
543 //==================================================
544 // Function: Contains
545 // Purpose :
546 //==================================================
547 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
548 {
549   return mySelectableObjects->Contains (theObject);
550 }
551
552 //==================================================
553 // Function: ActiveModes
554 // Purpose : return all the  modes with a given state for an object
555 //==================================================
556 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
557                                                   TColStd_ListOfInteger& theModeList,
558                                                   const SelectMgr_StateOfSelection theWantedState) const
559 {
560   Standard_Boolean hasActivatedStates = mySelectableObjects->Contains (theSelectableObject);
561   for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
562   {
563       if (theWantedState == SelectMgr_SOS_Any)
564       {
565         theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
566       }
567       else if (theWantedState == theSelectableObject->CurrentSelection()->GetSelectionState())
568       {
569         theModeList.Append (theSelectableObject->CurrentSelection()->Mode());
570       }
571   }
572
573   return hasActivatedStates;
574 }
575
576 //==================================================
577 // Function: IsActive
578 // Purpose :
579 //==================================================
580 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
581                                                      const Standard_Integer theMode) const
582 {
583   if (!mySelectableObjects->Contains (theSelectableObject))
584     return Standard_False;
585
586   for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
587   {
588     if (theMode == theSelectableObject->CurrentSelection()->Mode())
589     {
590       return theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated;
591     }
592   }
593
594   return Standard_False;
595 }
596
597 //==================================================
598 // Function: IsInside
599 // Purpose :
600 //==================================================
601 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
602                                                      const Standard_Integer theMode) const
603 {
604   if (!mySelectableObjects->Contains (theSelectableObject))
605     return Standard_False;
606
607   for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
608   {
609     if (theMode == theSelectableObject->CurrentSelection()->Mode())
610     {
611       return theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown;
612     }
613   }
614
615   return Standard_False;
616 }
617
618
619 //=======================================================================
620 //function : Status
621 //purpose  :
622 //=======================================================================
623
624 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
625 {
626   return theSelection->GetSelectionState();
627 }
628
629 //==================================================
630 // Function: Status
631 // Purpose : gives Information about selectors
632 //==================================================
633
634 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
635 {
636   TCollection_AsciiString aStatus ("Status Object :\n\t");
637
638   for (theSelectableObject->Init(); theSelectableObject->More(); theSelectableObject->Next())
639   {
640     if (theSelectableObject->CurrentSelection()->GetSelectionState() != SelectMgr_SOS_Unknown)
641     {
642       aStatus = aStatus + "Mode " +
643         TCollection_AsciiString (theSelectableObject->CurrentSelection()->Mode()) +
644         " present - ";
645       if (theSelectableObject->CurrentSelection()->GetSelectionState() == SelectMgr_SOS_Activated)
646       {
647         aStatus = aStatus + " Active \n\t";
648       }
649       else
650       {
651         aStatus = aStatus + " Inactive \n\t";
652       }
653     }
654   }
655
656   if (mySelectableObjects->Contains (theSelectableObject))
657   {
658     aStatus = aStatus + "Not Present in the selector\n\n";
659   }
660
661   return aStatus;
662 }
663
664 //=======================================================================
665 //function : SortResult
666 //purpose  :  there is a certain number of entities ranged by criteria
667 //            (depth, size, priority, mouse distance from borders or
668 //            CDG of the detected primitive. Parsing :
669 //             maximum priorities .
670 //             then a reasonable compromise between depth and distance...
671 // finally the ranges are stored in myindexes depending on the parsing.
672 // so, it is possible to only read
673 //=======================================================================
674 void SelectMgr_ViewerSelector::SortResult()
675 {
676   if(mystored.IsEmpty()) return;
677
678   const Standard_Integer anExtent = mystored.Extent();
679   if(myIndexes.IsNull() || anExtent != myIndexes->Length())
680     myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
681
682   // to work faster...
683   TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
684
685   // indices from 1 to N are loaded
686   Standard_Integer I ;
687   for (I=1; I <= anExtent; I++)
688     thearr(I)=I;
689
690   SortTools_QuickSortOfInteger::Sort (thearr,
691     SelectMgr_CompareResults(mystored));
692 }
693
694 //=======================================================================
695 //function : HasDepthClipping
696 //purpose  : Stub
697 //=======================================================================
698 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
699 {
700   return Standard_False;
701 }
702
703 //=======================================================================
704 // function : AddSelectableObject
705 // purpose  : Adds new object to the map of selectable objects
706 //=======================================================================
707 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
708 {
709   if (!myMapOfObjectSensitives.IsBound (theObject))
710   {
711     mySelectableObjects->Append (theObject);
712     NCollection_Handle<SelectMgr_SensitiveEntitySet> anEntitySet = new SelectMgr_SensitiveEntitySet();
713     myMapOfObjectSensitives.Bind (theObject, anEntitySet);
714   }
715 }
716
717 //=======================================================================
718 // function : AddSelectionToObject
719 // purpose  : Adds new selection to the object and builds its BVH tree
720 //=======================================================================
721 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
722                                                      const Handle(SelectMgr_Selection)& theSelection)
723 {
724   if (myMapOfObjectSensitives.IsBound (theObject))
725   {
726     NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
727       myMapOfObjectSensitives.ChangeFind (theObject);
728     anEntitySet->Append (theSelection);
729     anEntitySet->BVH();
730   }
731   else
732   {
733     AddSelectableObject (theObject);
734     AddSelectionToObject (theObject, theSelection);
735   }
736 }
737
738 //=======================================================================
739 // function : RemoveSelectableObject
740 // purpose  : Removes selectable object from map of selectable ones
741 //=======================================================================
742 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
743 {
744   if (myMapOfObjectSensitives.IsBound (theObject))
745   {
746     myMapOfObjectSensitives.UnBind (theObject);
747     mySelectableObjects->Remove (theObject);
748   }
749 }
750
751 //=======================================================================
752 // function : RemoveSelectionOfObject
753 // purpose  : Removes selection of the object and marks its BVH tree
754 //            for rebuild
755 //=======================================================================
756 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
757                                                         const Handle(SelectMgr_Selection)& theSelection)
758 {
759   if (myMapOfObjectSensitives.IsBound (theObject))
760   {
761     NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
762       myMapOfObjectSensitives.ChangeFind (theObject);
763     anEntitySet->Remove (theSelection);
764   }
765 }
766
767 //=======================================================================
768 // function : RebuildObjectsTree
769 // purpose  : Marks BVH of selectable objects for rebuild
770 //=======================================================================
771 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
772 {
773   mySelectableObjects->MarkDirty();
774
775   if (theIsForce)
776   {
777     mySelectableObjects->BVH();
778   }
779 }
780
781 //=======================================================================
782 // function : RebuildSensitivesTree
783 // purpose  : Marks BVH of sensitive entities of particular selectable
784 //            object for rebuild
785 //=======================================================================
786 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
787                                                       const Standard_Boolean theIsForce)
788 {
789   if (!mySelectableObjects->Contains (theObject))
790     return;
791
792   NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
793   anEntitySet->MarkDirty();
794
795   if (theIsForce)
796   {
797     anEntitySet->BVH();
798   }
799 }
800
801 //=======================================================================
802 // function : resetSelectionActivationStatus
803 // purpose  : Marks all added sensitive entities of all objects as
804 //            non-selectable
805 //=======================================================================
806 void SelectMgr_ViewerSelector::resetSelectionActivationStatus()
807 {
808   SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives);
809   for ( ; aSensitivesIter.More(); aSensitivesIter.Next())
810   {
811     NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
812       aSensitivesIter.ChangeValue();
813     Standard_Integer anEntitiesNb = anEntitySet->Size();
814     for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
815     {
816       anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
817     }
818   }
819 }
820
821 //=======================================================================
822 // function : DetectedEntity
823 // purpose  : Returns sensitive entity that was detected during the
824 //            previous run of selection algorithm
825 //=======================================================================
826 const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
827 {
828   const Handle(SelectMgr_EntityOwner)& anOwner = myDetectedIter.Key();
829   const Handle(SelectMgr_SelectableObject)& anObject = anOwner->Selectable();
830   const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet =
831     myMapOfObjectSensitives.Find (anObject);
832
833   return anEntitySet->GetSensitiveById (myDetectedIter.Value())->BaseSensitive();
834 }
835
836 //=======================================================================
837 // function : ActiveOwners
838 // purpose  : Returns the list of active entity owners
839 //=======================================================================
840 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
841 {
842   for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
843   {
844     const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
845     Standard_Integer anEntitiesNb = anEntitySet->Size();
846     for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
847     {
848       if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
849       {
850         theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
851       }
852     }
853   }
854 }