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