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