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