0024070: OpenGL capped object-level clipping planes
[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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // Modified by  ...
22 //              ROB JAN/07/98 : Improve Storage of detected entities
23 //              AGV OCT/23/03 : Optimize the method SortResult() (OCC4201)
24
25 #include <SelectMgr_ViewerSelector.ixx>
26 #include <SelectMgr_CompareResults.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <gp_Pnt.hxx>
29 #include <gp_Lin.hxx>
30 #include <Bnd_HArray1OfBox2d.hxx>
31 #include <Bnd_Array1OfBox2d.hxx>
32 #include <Precision.hxx>
33 #include <TColStd_Array1OfInteger.hxx>
34 #include <TCollection_AsciiString.hxx>
35 #include <NCollection_DataMap.hxx>
36 #include <SelectBasics_EntityOwner.hxx>
37 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
38 #include <SelectBasics_SensitiveEntity.hxx>
39 #include <SelectBasics_ListOfBox2d.hxx>
40 #include <SelectBasics_PickArgs.hxx>
41 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
42 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
43 #include <SelectMgr_SortCriterion.hxx>
44 #include <SortTools_QuickSortOfInteger.hxx>
45 #include <OSD_Environment.hxx>
46
47 static Standard_Boolean SelectDebugModeOnVS()
48 {
49   static Standard_Integer isDebugMode( -1 );
50   if ( isDebugMode < 0 ) {
51     isDebugMode = 1;
52     OSD_Environment selectdb("SELDEBUGMODE");
53     if ( selectdb.Value().IsEmpty() )
54       isDebugMode = 0;
55   }
56   return ( isDebugMode != 0 );
57 }
58
59 namespace
60 {
61   // container to store depth limits in collection map
62   struct SelectMgr_DepthRange
63   {
64     Standard_Real DepthMin;
65     Standard_Real DepthMax;
66     Standard_Boolean IsEmpty() const { return (DepthMin == DepthMax); }
67
68     void Common (const SelectMgr_DepthRange& theOther)
69     {
70       if (theOther.DepthMin > DepthMax || theOther.DepthMax < DepthMin)
71       {
72         DepthMin = RealFirst();
73         DepthMax = RealLast();
74         return;
75       }
76
77       DepthMin = Max (DepthMin, theOther.DepthMin);
78       DepthMax = Min (DepthMax, theOther.DepthMax);
79     }
80   };
81 };
82
83 //==================================================
84 // Function: Initialize
85 // Purpose :
86 //==================================================
87 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
88 toupdate(Standard_True),
89 tosort(Standard_True),
90 preferclosest(Standard_True),
91 mytolerance(0.),
92 myCurRank(0),
93 lastx (Precision::Infinite()),
94 lasty (Precision::Infinite()),
95 myUpdateSortPossible( Standard_True )
96 {
97 }
98
99
100 //==================================================
101 // Function: Activate
102 // Purpose :
103 //==================================================
104 void SelectMgr_ViewerSelector::
105 Activate (const Handle(SelectMgr_Selection)& aSelection,
106           const Standard_Boolean AutomaticProj)
107 {
108   tosort = Standard_True;
109
110   if (!myselections.IsBound(aSelection))
111   {
112     myselections.Bind(aSelection,0);
113   }
114   else if (myselections(aSelection)!=0)
115   {
116     myselections(aSelection)= 0;
117   }
118   if(AutomaticProj)
119     Convert(aSelection);
120 }
121
122
123 //==================================================
124 // Function: Deactivate
125 // Purpose :
126 //==================================================
127 void SelectMgr_ViewerSelector::
128 Deactivate (const Handle(SelectMgr_Selection)& aSel)
129 {
130   if(myselections.IsBound(aSel))
131   {myselections(aSel)=1;
132   tosort = Standard_True;}
133 }
134
135
136
137
138
139 //==================================================
140 // Function: Sleep
141 // Purpose :
142 //==================================================
143 void SelectMgr_ViewerSelector::Sleep()
144 { SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
145 for (;It.More();It.Next()){
146   if(It.Value()==0) myselections(It.Key())= 2;
147 }
148 UpdateSort();
149 }
150 //=======================================================================
151 //function : Sleep
152 //purpose  :
153 //=======================================================================
154
155 void SelectMgr_ViewerSelector::Sleep(const Handle(SelectMgr_SelectableObject)& SO)
156 {
157
158   for(SO->Init();SO->More();SO->Next()){
159     if(myselections.IsBound(SO->CurrentSelection())){
160       myselections(SO->CurrentSelection()) = 2;
161     }
162   }
163   UpdateSort();
164 }
165
166
167 //==================================================
168 // Function: Awake
169 // Purpose :
170 //==================================================
171 void SelectMgr_ViewerSelector::Awake(const Standard_Boolean AutomaticProj)
172 {
173   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
174   for (;It.More();It.Next()){
175     if(It.Value()==2)
176       myselections(It.Key())=0;
177     if(AutomaticProj)
178       UpdateConversion();
179     UpdateSort();
180   }
181 }
182
183 void SelectMgr_ViewerSelector::Awake(const Handle(SelectMgr_SelectableObject)& SO,
184                                      const Standard_Boolean AutomaticProj)
185 {
186   for(SO->Init();SO->More();SO->Next()){
187     if(myselections.IsBound(SO->CurrentSelection())){
188       myselections(SO->CurrentSelection()) =0;
189       if(AutomaticProj)
190         Convert(SO->CurrentSelection());
191     }
192   }
193
194 }
195 //==================================================
196 // Function: Clear
197 // Purpose :
198 //==================================================
199 void SelectMgr_ViewerSelector::Clear()
200 {
201   myentities.Clear();
202   myselections.Clear();
203   toupdate = Standard_True;
204   tosort = Standard_True;
205   mystored.Clear();
206   lastx = Precision::Infinite();
207   lasty = Precision::Infinite();
208
209 }
210
211 //==================================================
212 // Function: UpdateConversion
213 // Purpose :
214 //==================================================
215 void SelectMgr_ViewerSelector::UpdateConversion()
216 {
217   if( SelectDebugModeOnVS() )
218     cout<<"\t\t\t\t\t SelectMgr_VS::UpdateConversion"<<endl;
219
220   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
221   for(;It.More();It.Next()){
222     //Convert only if active...
223     if(It.Value()==0)
224       Convert(It.Key());
225   }
226   toupdate = Standard_False;
227   tosort = Standard_True;
228 }
229
230
231 //==================================================
232 // Function: Convert
233 // Purpose :
234 //==================================================
235 void SelectMgr_ViewerSelector::
236 Convert (const Handle(SelectMgr_Selection)& /*aSel*/) {tosort=Standard_True;}
237
238
239 //==================================================
240 // Function: UpdateSort
241 // Purpose :
242 //==================================================
243 void SelectMgr_ViewerSelector::UpdateSort()
244 {
245   if( !myUpdateSortPossible )
246     return;
247
248   if( SelectDebugModeOnVS() )
249     cout<<"\t\t\t\t\t SelectMgr_ViewerSelector::UpdateSort()"<<endl;
250   mystored.Clear();
251   myentities.Clear();
252   myactivenb = NbBoxes();
253
254   if(myactivenb > 0) {
255     Standard_Boolean NoClip = myclip.IsVoid();
256     Handle(Bnd_HArray1OfBox2d) refToTab = new Bnd_HArray1OfBox2d(1,myactivenb);
257     Bnd_Array1OfBox2d & tab = refToTab->ChangeArray1();
258     Standard_Real xmin=Precision::Infinite(),ymin=Precision::Infinite(),xmax=-Precision::Infinite(),ymax=-Precision::Infinite();
259     Standard_Real curxmin,curymin,curxmax,curymax;
260     //    Standard_Integer boxindex=0,indexsel=0,indexprim=0;
261     Standard_Integer boxindex=0;
262
263     SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It;
264     SelectBasics_ListIteratorOfListOfBox2d LIt;
265     Handle(SelectMgr_Selection) curEntity;
266     Standard_Real ScaleFactor;
267     for(It.Initialize(myselections);It.More();It.Next()){
268       if(It.Value()== 0)
269       { curEntity = It.Key();
270       for(curEntity->Init();curEntity->More();curEntity->Next())
271       {
272         static SelectBasics_ListOfBox2d BoxList;
273         BoxList.Clear();
274         curEntity->Sensitive()->Areas(BoxList);
275         ScaleFactor = curEntity->Sensitive()->SensitivityFactor();
276
277
278         for(LIt.Initialize(BoxList);LIt.More();LIt.Next()){
279           boxindex++;
280
281           tab.SetValue(boxindex,LIt.Value());
282
283           tab(boxindex).SetGap(mytolerance*ScaleFactor);
284           myentities.Bind(boxindex,curEntity->Sensitive());
285           if(NoClip){
286             if (!tab(boxindex).IsVoid()) {
287               tab(boxindex).Get(curxmin,curymin,curxmax,curymax);
288               if(curxmin<xmin) xmin=curxmin;
289               if(curxmax>xmax) xmax=curxmax;
290               if(curymin<ymin) ymin=curymin;
291               if(curymax>ymax) ymax=curymax;
292             }
293           }
294         }
295       }
296       }
297     }
298
299
300     if(NoClip) {myclip.SetVoid();myclip.Update(xmin,ymin,xmax,ymax);}
301     myselector.Initialize(myclip, mytolerance,refToTab);
302     tosort = Standard_False;
303     if(NoClip) myclip.SetVoid();
304   }
305 }
306
307
308 //==================================================
309 // Function: Remove
310 // Purpose :
311 //==================================================
312 void SelectMgr_ViewerSelector::
313 Remove(const Handle(SelectMgr_Selection)& aSel)
314 {
315   if (myselections.IsBound(aSel))
316   { myselections.UnBind(aSel);
317   tosort = Standard_True;
318   }
319 }
320
321 //==================================================
322 // Function: SetSensitivity
323 // Purpose :
324 //==================================================
325 void SelectMgr_ViewerSelector::SetSensitivity(const Standard_Real aVal)
326 {mytolerance = aVal;
327 tosort=Standard_True;}
328
329 //==================================================
330 // Function: SetClipping
331 // Purpose :
332 //==================================================
333 void SelectMgr_ViewerSelector::SetClipping(const Standard_Real Xc,
334                                            const Standard_Real Yc,
335                                            const Standard_Real Height,
336                                            const Standard_Real Width)
337 {
338   Bnd_Box2d aClip;
339   aClip.Set(gp_Pnt2d(Xc-Width/2, Yc-Height/2));
340   aClip.Add(gp_Pnt2d(Xc+Width/2, Yc+Height/2));
341   myclip = aClip;
342   tosort = Standard_True;
343 }
344
345
346 //==================================================
347 // Function: SetClipping
348 // Purpose :
349 //==================================================
350 void SelectMgr_ViewerSelector::SetClipping (const Bnd_Box2d& abox)
351 {myclip = abox;
352 tosort = Standard_True;
353 }
354
355 //==================================================
356 // Function: InitSelect
357 // Purpose :
358 //==================================================
359 void SelectMgr_ViewerSelector::InitSelect(const Standard_Real Xr,
360                                           const Standard_Real Yr)
361 {
362   Standard_OutOfRange_Raise_if(Abs(Xr-Precision::Infinite())<=Precision::Confusion() ||
363     Abs(Yr-Precision::Infinite())<=Precision::Confusion(),
364     " Infinite values in IniSelect");
365   mystored.Clear();
366   myprim.Clear();
367   if (toupdate) UpdateConversion();
368   if (tosort) UpdateSort();
369   if(myactivenb!=0){
370     myselector.InitSelect(Xr,Yr);
371     if(myselector.More()) {lastx = Xr;lasty=Yr;}
372     LoadResult();
373   }
374 }
375
376 //==================================================
377 // Function: InitSelect
378 // Purpose :
379 //==================================================
380 void SelectMgr_ViewerSelector::InitSelect(const Bnd_Box2d& aBox)
381 {
382   mystored.Clear();
383   if(toupdate) UpdateConversion();
384   if (tosort) UpdateSort();
385   if (myactivenb!=0){
386     myselector.InitSelect(aBox);
387     LoadResult(aBox);
388   }
389 }
390
391 //==================================================
392 // Function: InitSelect
393 // Purpose :
394 //==================================================
395 void SelectMgr_ViewerSelector::InitSelect(const Standard_Real Xmin,
396                                           const Standard_Real Ymin,
397                                           const Standard_Real Xmax,
398                                           const Standard_Real Ymax)
399 {
400   mystored.Clear();
401
402   if (toupdate) UpdateConversion();
403   if (tosort)   UpdateSort();
404   if (myactivenb!=0){
405     Bnd_Box2d aBox;
406     aBox.Update(Xmin,Ymin,Xmax,Ymax);
407     myselector.InitSelect(aBox);
408     LoadResult(aBox);
409   }
410 }
411
412 //==================================================
413 // Function: InitSelect
414 // Purpose : Polyline Selection
415 //==================================================
416 void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly)
417 {
418   mystored.Clear();
419
420   if (toupdate) UpdateConversion();
421   if (tosort)   UpdateSort();
422   if (myactivenb!=0){
423     // the Bnd boxes are used for the first time
424     Bnd_Box2d aBox;
425     Standard_Integer NbPnt = aPoly.Length();
426     Standard_Integer i;
427     for(i=1;i<=NbPnt;i++) {
428       aBox.Update(aPoly(i).X(),aPoly(i).Y());
429     }
430     myselector.InitSelect(aBox);
431     LoadResult(aPoly);
432     //    LoadResult(aBox);
433   }
434 }
435
436
437 //==================================================
438 // Function: LoadResult
439 // Purpose : for the moment the size of the primitive
440 //           is not taken into account in the search criteriai...
441 //           The priority, the depth and the min. distance to CDG or Borders is taken...
442 //==================================================
443 void SelectMgr_ViewerSelector::LoadResult()
444 {
445   if (myselector.More())
446   {
447     NCollection_DataMap<Handle(SelectMgr_EntityOwner), SelectMgr_DepthRange> aMapOfOwnerRanges;
448
449     // collect information on depth clipping from implementations
450     gp_Lin aPickLine = PickingLine (lastx, lasty);
451     SelectMgr_DepthRange aViewDRange;
452     DepthClipping (lastx, lasty, aViewDRange.DepthMin, aViewDRange.DepthMax);
453
454     Standard_Real aDMin;
455     Standard_Real aDepthMin;
456     Standard_Integer aNument;
457
458     if (!aViewDRange.IsEmpty())
459     {
460       for (; myselector.More(); myselector.Next())
461       {
462         aNument = myselector.Value();
463
464         const Handle(SelectBasics_SensitiveEntity)& SE = myentities (aNument);
465         const Handle(SelectMgr_EntityOwner)& anOwner =
466           Handle(SelectMgr_EntityOwner)::DownCast (SE->OwnerId());
467
468         // compute depth range for sensitives of entity owner
469         SelectMgr_DepthRange anEntityDRange (aViewDRange);
470         if (!anOwner.IsNull() && HasDepthClipping (anOwner) && !aMapOfOwnerRanges.Find (anOwner, anEntityDRange))
471         {
472           // get depth range from implementation
473           SelectMgr_DepthRange aGetRange;
474           DepthClipping (lastx, lasty, anOwner, aGetRange.DepthMin, aGetRange.DepthMax);
475
476           // concatenate and remember depth range for pefromance increase
477           anEntityDRange.Common (aGetRange);
478           aMapOfOwnerRanges.Bind (anOwner, anEntityDRange);
479         }
480
481         if (anEntityDRange.IsEmpty())
482         {
483           continue;
484         }
485
486         SelectBasics_PickArgs aPickArgs (lastx, lasty, mytolerance,
487                                          anEntityDRange.DepthMin,
488                                          anEntityDRange.DepthMax,
489                                          aPickLine);
490
491         if (SE->Matches (aPickArgs, aDMin, aDepthMin))
492         {
493           if (!anOwner.IsNull())
494           {
495             Standard_Integer aPrior = anOwner->Priority();
496
497             SelectMgr_SortCriterion SC (aPrior, aDepthMin, aDMin, mytolerance, preferclosest);
498             if (mystored.Contains (anOwner))
499             {
500               SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey (anOwner);
501               if (SC > Crit)
502               {
503                 Crit = SC;
504
505                 // update previously recorded entity for this owner
506                 for (int i = 1; i <= myprim.Length(); i++)
507                 {
508                   if (myentities (myprim(i))->OwnerId() == anOwner)
509                   {
510                     myprim.SetValue (i, aNument);
511                     break;
512                   }
513                 }
514               }
515             }
516             else
517             {
518               mystored.Add (anOwner, SC);
519
520               // record entity
521               myprim.Append (aNument);
522             }
523           }
524         }
525       }
526     }
527
528     SortResult();
529   }
530
531   if (SelectDebugModeOnVS())
532   {
533     cout<<"\tSelectMgr_VS:: Resultat du move"<<endl;
534     cout<<"\tNb Detectes :"<<mystored.Extent()<<endl;
535
536     for(Standard_Integer i=1; i<=mystored.Extent(); i++)
537     {
538       const SelectMgr_SortCriterion& Crit = mystored (myIndexes->Value(i));
539       cout << "\t" << i << " - Prior" << Crit.Priority()
540            << " - prof :" << Crit.Depth()
541            << "  - Dist. :" << Crit.MinDist() << endl;
542     }
543   }
544 }
545
546 //==================================================
547 // Function: LoadResult
548 // Purpose :
549 //==================================================
550 void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox)
551 {
552   mystored.Clear();
553
554   //  Handle(SelectMgr_EntityOwner)  OWNR;
555   if(myselector.More())
556   { Standard_Real xmin,ymin,xmax,ymax;
557   abox.Get(xmin,ymin,xmax,ymax);
558   //      Standard_Boolean Found(Standard_False);
559   //      Standard_Real DMin=0.;
560   Standard_Integer nument;
561   for(;myselector.More();myselector.Next()){
562     nument = myselector.Value();
563     const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument);
564     if (SE->Matches(xmin,ymin,xmax,ymax,0.0)){
565       const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId();
566       if(!OWNR.IsNull()){
567         if(!mystored.Contains(OWNR)){
568           SelectMgr_SortCriterion SC(OWNR->Priority(),Precision::Infinite(),
569             Precision::Infinite(),mytolerance,preferclosest);
570           mystored.Add(OWNR,SC);
571           myprim.Append(nument);
572         }
573       }
574     }
575   }
576
577   // do not parse in case of selection by elastic rectangle (BUG ANALYST)
578   if(mystored.IsEmpty()) return;
579   if(myIndexes.IsNull())
580     myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent());
581   else if(mystored.Extent() !=myIndexes->Length())
582     myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent());
583
584   // to work faster...
585   TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
586   for(Standard_Integer I=1;I<=mystored.Extent();I++)
587     thearr(I)=I;
588   }
589 }
590 //==================================================
591 // Function: LoadResult
592 // Purpose :
593 //==================================================
594 void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly)
595 {
596   mystored.Clear();
597   Bnd_Box2d aBox;
598   Standard_Integer NbPnt = aPoly.Length();
599   Standard_Integer i;
600   for(i=1;i<=NbPnt;i++) {
601     aBox.Update(aPoly(i).X(),aPoly(i).Y());
602   }
603   Standard_Integer NB=0;
604   //  Handle(SelectMgr_EntityOwner)  OWNR;
605   if(myselector.More())
606   {
607     Standard_Integer nument;
608
609     for(;myselector.More();myselector.Next()){
610       NB++;
611       nument = myselector.Value();
612       const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument);
613       if (SE->Matches(aPoly,aBox,0.0)){
614         const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId();
615         if(!OWNR.IsNull()){
616           if(!mystored.Contains(OWNR)){
617             SelectMgr_SortCriterion SC(OWNR->Priority(),Precision::Infinite(),
618               Precision::Infinite(),mytolerance,preferclosest);
619             mystored.Add(OWNR,SC);
620             myprim.Append(nument);
621           }
622         }
623       }
624     }
625
626     if(mystored.IsEmpty()) return;
627     if(myIndexes.IsNull())
628       myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent());
629     else if(mystored.Extent() !=myIndexes->Length())
630       myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent());
631
632     // to work faster...
633     TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
634     for(Standard_Integer I=1;I<=mystored.Extent();I++)
635       thearr(I)=I;
636   }
637 }
638
639
640 //==================================================
641 // Function: HasStored
642 // Purpose :
643 //==================================================
644 Standard_Boolean SelectMgr_ViewerSelector::
645 HasStored ()
646 {
647   if(Abs(lastx-Precision::Infinite())<=Precision::Confusion()) return Standard_False;
648   if(Abs(lasty-Precision::Infinite())<=Precision::Confusion()) return Standard_False;
649   InitSelect(lastx,lasty);
650   Init();
651   return More();
652 }
653
654
655
656
657 //==================================================
658 // Function: Picked
659 // Purpose :
660 //==================================================
661 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
662 ::Picked() const
663 {
664   Standard_Integer RankInMap = myIndexes->Value(myCurRank);
665   const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
666   Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
667   return Ownr;
668 }
669
670
671
672 //=======================================================================
673 //function : More
674 //purpose  :
675 //=======================================================================
676 Standard_Boolean SelectMgr_ViewerSelector::More()
677 {
678   if(mystored.Extent()==0) return Standard_False;
679   if(myCurRank==0) return Standard_False;
680   return myCurRank <= myIndexes->Length();
681 }
682
683 //==================================================
684 // Function: OnePicked
685 // Purpose : only the best one is chosen
686 //           depend on priority and mindist...
687 //==================================================
688
689 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
690 ::OnePicked()
691 {
692
693   Init();
694   if(More()){
695     Standard_Integer RankInMap = myIndexes->Value(1);
696     const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(RankInMap);
697     Handle(SelectMgr_EntityOwner) Ownr = *((Handle(SelectMgr_EntityOwner)*) &toto);
698     return Ownr;
699   }
700
701   Handle (SelectMgr_EntityOwner) NullObj; //returns a null Handle if there was not successfull pick...
702   return NullObj;
703 }
704
705
706 //=======================================================================
707 //function : NbPicked
708 //purpose  :
709 //=======================================================================
710
711 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
712 {
713   return mystored.Extent();
714 }
715 //=======================================================================
716 //function : Picked
717 //purpose  :
718 //=======================================================================
719 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
720 {
721
722   Handle(SelectMgr_EntityOwner) Own;
723   if (aRank<1 || aRank>NbPicked())
724     return Own;
725   Standard_Integer Indx = myIndexes->Value(aRank);
726
727
728   const Handle(SelectBasics_EntityOwner)& toto = mystored.FindKey(Indx);
729   Own = *((Handle(SelectMgr_EntityOwner)*) &toto);
730   return Own;
731 }
732 //=======================================================================
733 //function : Primitive
734 //purpose  :
735 //=======================================================================
736 Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive
737 (const Standard_Integer /*Index*/) const
738 {
739   return myentities(myprim(myCurRank));
740 }
741
742
743 //==================================================
744 // Function: LastPosition
745 // Purpose :
746 //==================================================
747 void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast,
748                                             Standard_Real& YLast) const
749 {   Xlast = lastx;YLast = lasty;}
750
751
752
753 //===================================================
754 //
755 //       INTERNAL METHODS ....
756 //
757 //==================================================
758
759
760
761
762 //==================================================
763 // Function: NbBoxes
764 // Purpose :
765 //==================================================
766 Standard_Integer SelectMgr_ViewerSelector::NbBoxes()
767 {
768   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
769   //  Standard_Integer Nbb=0, first,last;
770   Standard_Integer Nbb=0;
771
772   for(;It.More();It.Next()){
773     if(It.Value()==0){
774       for(It.Key()->Init();It.Key()->More();It.Key()->Next())
775       {Nbb+= It.Key()->Sensitive()->MaxBoxes();}
776     }
777   }
778   return Nbb;
779 }
780
781
782
783
784 //==================================================
785 // Function: Contains
786 // Purpose :
787 //==================================================
788 Standard_Boolean SelectMgr_ViewerSelector::
789 Contains(const Handle(SelectMgr_SelectableObject)& anObject) const
790 {
791   for (anObject->Init();anObject->More();anObject->Next()){
792     if(myselections.IsBound(anObject->CurrentSelection()))
793       return Standard_True;
794   }
795   return Standard_False;
796 }
797
798
799
800 //==================================================
801 // Function: ActiveModes
802 // Purpose : return all the  modes with a given state for an object
803 //==================================================
804
805
806 Standard_Boolean SelectMgr_ViewerSelector::
807 Modes(const Handle(SelectMgr_SelectableObject)& SO,
808       TColStd_ListOfInteger& TheActiveList,
809       const SelectMgr_StateOfSelection WantedState) const
810 {
811   Standard_Boolean Found= Standard_False;
812   for(SO->Init();SO->More();SO->Next()){
813     if(myselections.IsBound(SO->CurrentSelection())){
814       if(WantedState==SelectMgr_SOS_Any)
815         TheActiveList.Append(SO->CurrentSelection()->Mode());
816       else if( myselections(SO->CurrentSelection())==WantedState)
817         TheActiveList.Append(SO->CurrentSelection()->Mode());
818
819       if(!Found) Found=Standard_True;
820     }
821   }
822   return Found;
823 }
824
825
826 Standard_Boolean SelectMgr_ViewerSelector::
827 IsActive(const Handle(SelectMgr_SelectableObject)& SO,
828          const Standard_Integer aMode) const
829 {
830   for(SO->Init();SO->More();SO->Next()){
831     if(aMode==SO->CurrentSelection()->Mode()){
832       if(myselections.IsBound(SO->CurrentSelection()) &&
833         myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated)
834         return Standard_True;
835       else return Standard_False;
836     }
837   }
838   return Standard_False;
839 }
840
841
842 Standard_Boolean SelectMgr_ViewerSelector::
843 IsInside(const Handle(SelectMgr_SelectableObject)& SO,
844          const Standard_Integer aMode) const
845 {
846   for(SO->Init();SO->More();SO->Next()){
847     if(aMode==SO->CurrentSelection()->Mode()){
848       if(myselections.IsBound(SO->CurrentSelection())) return Standard_True;
849       else return Standard_False;
850
851     }
852   }
853   return Standard_False;
854 }
855
856
857 //=======================================================================
858 //function : Status
859 //purpose  :
860 //=======================================================================
861
862 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const
863 {
864   if(!myselections.IsBound(aSel)) return SelectMgr_SOS_Unknown;
865   //JR/Hp
866   Standard_Integer ie = myselections(aSel) ;
867   return SelectMgr_StateOfSelection( ie );
868   //  return SelectMgr_StateOfSelection(myselections(aSel));
869
870 }
871
872
873
874 //=======================================================================
875 //function : Dump
876 //purpose  :
877 //=======================================================================
878
879 void SelectMgr_ViewerSelector::Dump(Standard_OStream& S) const
880 {
881   S<<"=========================="<<endl;
882   S<<" SelectMgr_ViewerSelector "<<endl;
883   S<<"=========================="<<endl;
884   S<<" "<<endl;
885 }
886
887
888
889 //==================================================
890 // Function: Status
891 // Purpose : gives Information about selectors
892 //==================================================
893
894 TCollection_AsciiString SelectMgr_ViewerSelector::
895 Status(const Handle(SelectMgr_SelectableObject)& SO) const
896 {
897   TCollection_AsciiString Status("Status Object :\n\t");
898   Standard_Boolean Found= Standard_False;
899   for(SO->Init();SO->More();SO->Next()){
900     if(myselections.IsBound(SO->CurrentSelection()))
901     {
902       Found = Standard_True;
903       Status = Status + "Mode " +
904         TCollection_AsciiString(SO->CurrentSelection()->Mode()) +
905         " present - " ;
906       if(myselections(SO->CurrentSelection()))
907         Status = Status + " Active \n\t";
908       else
909         Status = Status + " Inactive \n\t";
910     }
911   }
912
913   if(!Found) Status = Status + "Not Present in the selector\n\n";
914   return Status;
915 }
916
917
918 TCollection_AsciiString SelectMgr_ViewerSelector::
919 Status () const
920 {
921   // sevsitive primitives present
922   //-----------------------------
923   TCollection_AsciiString Status("\t\tSelector Status :\n\t");
924   // selections
925   //-----------
926   Standard_Integer NbActive =0,NbPrim=0;
927   Status = Status + "Number of already computed selections : " +
928     TCollection_AsciiString(myselections.Extent());
929
930   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
931   for(;It.More();It.Next())
932   {
933     if(It.Value()==0) {NbActive++;
934     for(It.Key()->Init();It.Key()->More();It.Key()->Next()){NbPrim++;}
935     }
936   }
937   Status = Status + " - " + TCollection_AsciiString(NbActive) + " activated ones\n\t";
938   Status = Status + "Number of active sensitive primitives : " +
939     TCollection_AsciiString(NbPrim)+"\n\t";
940   Status = Status + "Real stored Pick Tolerance : " + TCollection_AsciiString(mytolerance) +"\n\t";
941   if(toupdate) {
942     Status = Status + "\nWARNING : those informations will be obsolete for the next Pick\n"
943       +"to get the real status of the selector - make One pick and call Status again\n";
944   }
945   return Status;
946 }
947
948 //=======================================================================
949 //function : SortResult
950 //purpose  :  there is a certain number of entities ranged by criteria
951 //            (depth, size, priority, mouse distance from borders or
952 //            CDG of the detected primitive. Parsing :
953 //             maximum priorities .
954 //             then a reasonable compromise between depth and distance...
955 // finally the ranges are stored in myindexes depending on the parsing.
956 // so, it is possible to only read
957 //=======================================================================
958 void SelectMgr_ViewerSelector::SortResult()
959 {
960   if(mystored.IsEmpty()) return;
961
962   const Standard_Integer anExtent = mystored.Extent();
963   if(myIndexes.IsNull() || anExtent != myIndexes->Length())
964     myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
965
966   // to work faster...
967   TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
968
969   // indices from 1 to N are loaded
970   Standard_Integer I ;
971   for (I=1; I <= anExtent; I++)
972     thearr(I)=I;
973
974   // OCC4201 (AGV): This loop is inefficient on large arrays, so I replace it
975   //                with a standard sort algo
976   //  // on trie suivant les criteres  (i) (Owner) (SortCriterion)
977   //  Standard_Boolean OKSort;
978   //  Standard_Integer temp,indx,indx1;
979   //  Standard_Integer tmprim;
980   //  // merci lbr...
981   //  do{
982   //    OKSort =Standard_True;
983   //    for(I=1;I<thearr.Length();I++){
984   //      indx = thearr(I);
985   //      indx1 = thearr(I+1);
986   //      if(mystored(indx) < mystored(indx1)){
987   //      OKSort = Standard_False;
988   //
989   //      temp = thearr(I+1);
990   //      thearr(I+1) = thearr (I);
991   //      thearr(I) = temp;
992   //
993   //      tmprim = myprim(I+1);
994   //      myprim(I+1) = myprim(I);
995   //      myprim(I) = tmprim;
996   //
997   //      }
998   //    }
999   //  } while (OKSort==Standard_False);
1000   //
1001   // OCC4201 (AGV): debut
1002
1003   SortTools_QuickSortOfInteger::Sort (thearr,
1004     SelectMgr_CompareResults(mystored));
1005   TColStd_Array1OfInteger myPrimArr (1, myprim.Length());
1006   for (I = 1; I <= myPrimArr.Length(); I++)
1007     myPrimArr (I) = myprim (I);
1008   for (I = 1; I <= thearr.Length(); I++) {
1009     const Standard_Integer ind = thearr(I);
1010     if (ind > 0 && ind <= myPrimArr.Upper())
1011       myprim (I) = myPrimArr (ind);
1012   }
1013   // OCC4201 (AGV): fin
1014   // it is enough to return owners corresponding to parced indices...
1015
1016 }
1017
1018
1019 //=======================================================================
1020 //function :
1021 //purpose  :
1022 //=======================================================================
1023 Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const
1024 {
1025   return myUpdateSortPossible;
1026 }
1027
1028 //=======================================================================
1029 //function :
1030 //purpose  :
1031 //=======================================================================
1032 void SelectMgr_ViewerSelector::SetUpdateSortPossible( const Standard_Boolean possible )
1033 {
1034   myUpdateSortPossible = possible;
1035 }
1036
1037 //=======================================================================
1038 //function : PickingLine
1039 //purpose  : Stub
1040 //=======================================================================
1041 gp_Lin SelectMgr_ViewerSelector::PickingLine (const Standard_Real /*theX*/,
1042                                               const Standard_Real /*theY*/) const
1043 {
1044   return gp_Lin();
1045 }
1046
1047 //=======================================================================
1048 //function : DepthClipping
1049 //purpose  : Stub
1050 //=======================================================================
1051 void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
1052                                               const Standard_Real /*theY*/,
1053                                               Standard_Real& theMin,
1054                                               Standard_Real& theMax) const
1055 {
1056   theMin = RealFirst();
1057   theMax = RealLast();
1058 }
1059
1060 //=======================================================================
1061 //function : DepthClipping
1062 //purpose  : Stub
1063 //=======================================================================
1064 void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
1065                                               const Standard_Real /*theY*/,
1066                                               const Handle(SelectMgr_EntityOwner)& /*theOwner*/,
1067                                               Standard_Real& theMin,
1068                                               Standard_Real& theMax) const
1069 {
1070   theMin = RealFirst();
1071   theMax = RealLast();
1072 }
1073
1074 //=======================================================================
1075 //function : HasDepthClipping
1076 //purpose  : Stub
1077 //=======================================================================
1078 Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
1079 {
1080   return Standard_False;
1081 }