0c181b46b5cee49bdbfe630354256ae213f16621
[occt.git] / src / AIS / AIS_InteractiveContext_1.cxx
1 // Created on: 1997-01-29
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1997-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
18 #include <AIS_DataMapIteratorOfDataMapOfIOStatus.hxx>
19 #include <AIS_GlobalStatus.hxx>
20 #include <AIS_InteractiveContext.hxx>
21 #include <AIS_InteractiveObject.hxx>
22 #include <AIS_LocalContext.hxx>
23 #include <AIS_MapIteratorOfMapOfInteractive.hxx>
24 #include <AIS_MapOfInteractive.hxx>
25 #include <AIS_Selection.hxx>
26 #include <AIS_Shape.hxx>
27 #include <AIS_StatusOfDetection.hxx>
28 #include <AIS_StatusOfPick.hxx>
29 #include <Aspect_Grid.hxx>
30 #include <Prs3d_BasicAspect.hxx>
31 #include <Prs3d_LineAspect.hxx>
32 #include <Prs3d_Presentation.hxx>
33 #include <Quantity_Color.hxx>
34 #include <SelectBasics_SensitiveEntity.hxx>
35 #include <SelectMgr_EntityOwner.hxx>
36 #include <SelectMgr_Filter.hxx>
37 #include <SelectMgr_OrFilter.hxx>
38 #include <SelectMgr_Selection.hxx>
39 #include <SelectMgr_SelectionManager.hxx>
40 #include <Standard_Transient.hxx>
41 #include <StdSelect_BRepOwner.hxx>
42 #include <StdSelect_ViewerSelector3d.hxx>
43 #include <TCollection_AsciiString.hxx>
44 #include <TCollection_ExtendedString.hxx>
45 #include <TColStd_ListIteratorOfListOfInteger.hxx>
46 #include <TopLoc_Location.hxx>
47 #include <V3d_AmbientLight.hxx>
48 #include <V3d_DirectionalLight.hxx>
49 #include <V3d_Light.hxx>
50 #include <V3d_PositionalLight.hxx>
51 #include <V3d_SpotLight.hxx>
52 #include <V3d_View.hxx>
53 #include <V3d_Viewer.hxx>
54
55 typedef NCollection_DataMap<Handle(AIS_InteractiveObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > AIS_MapOfObjSelectedOwners;
56
57 namespace
58 {
59   TopoDS_Shape AIS_myDummyShape;
60 }
61
62 //=======================================================================
63 //function : highlightWithColor
64 //purpose  :
65 //=======================================================================
66 void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOwner)& theOwner,
67                                                  const Handle(V3d_Viewer)& theViewer)
68 {
69   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
70   if (anObj.IsNull())
71   {
72     return;
73   }
74
75   const Handle(Prs3d_Drawer)& aStyle = getHiStyle (anObj, theOwner);
76   const Standard_Integer aHiMode = getHilightMode (anObj, aStyle, -1);
77
78   myMainPM->BeginImmediateDraw();
79   theOwner->HilightWithColor (myMainPM, aStyle, aHiMode);
80   myMainPM->EndImmediateDraw (theViewer.IsNull() ? myMainVwr : theViewer);
81 }
82
83 //=======================================================================
84 //function : highlightSelected
85 //purpose  :
86 //=======================================================================
87 void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwner)& theOwner)
88 {
89   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
90   if (anObj.IsNull())
91   {
92     return;
93   }
94
95   if (!theOwner->IsAutoHilight())
96   {
97     SelectMgr_SequenceOfOwner aSeq;
98     for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
99     {
100       if (aSelIter.Value()->IsSameSelectable (anObj))
101       {
102         aSeq.Append (aSelIter.Value());
103       }
104     }
105     anObj->HilightSelected (myMainPM, aSeq);
106   }
107   else
108   {
109     const Handle(Prs3d_Drawer)& aStyle = getSelStyle (anObj, theOwner);
110     const Standard_Integer aHiMode = getHilightMode (anObj, aStyle, -1);
111     theOwner->HilightWithColor (myMainPM, aStyle, aHiMode);
112   }
113 }
114
115 //=======================================================================
116 //function : highlightGlobal
117 //purpose  :
118 //=======================================================================
119 void AIS_InteractiveContext::highlightGlobal (const Handle(AIS_InteractiveObject)& theObj,
120                                               const Handle(Prs3d_Drawer)& theStyle,
121                                               const Standard_Integer theDispMode) const
122 {
123   if (theObj.IsNull())
124   {
125     return;
126   }
127
128   const Standard_Integer aHiMode = getHilightMode (theObj, theStyle, theDispMode);
129   const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
130
131   if (aGlobOwner.IsNull())
132   {
133     myMainPM->Color (theObj, theStyle, aHiMode);
134     return;
135   }
136
137   if (!aGlobOwner->IsAutoHilight())
138   {
139     SelectMgr_SequenceOfOwner aSeq;
140     for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
141     {
142       if (aSelIter.Value()->IsSameSelectable (theObj))
143       {
144         aSeq.Append (aSelIter.Value());
145       }
146     }
147     theObj->HilightSelected (myMainPM, aSeq);
148   }
149   else
150   {
151     aGlobOwner->HilightWithColor (myMainPM, theStyle, aHiMode);
152   }
153 }
154
155 //=======================================================================
156 //function : unhighlightSelected
157 //purpose  :
158 //=======================================================================
159 void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsToHilightSubIntensity)
160 {
161   NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
162   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
163   {
164     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
165     const Handle(AIS_InteractiveObject) anInteractive = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
166     Handle(AIS_GlobalStatus) aStatus;
167     if (!myObjects.Find (anInteractive, aStatus))
168     {
169       continue;
170     }
171
172     if (anOwner->IsAutoHilight())
173     {
174       anOwner->Unhilight (myMainPM);
175       if (theIsToHilightSubIntensity)
176       {
177         if (aStatus->IsSubIntensityOn())
178         {
179           const Standard_Integer aHiMode = getHilightMode (anInteractive, aStatus->HilightStyle(), aStatus->DisplayMode());
180           highlightWithSubintensity (anOwner, aHiMode);
181         }
182       }
183     }
184     else
185     {
186       anObjToClear.Add (anInteractive);
187     }
188     anOwner->SetSelected (Standard_False);
189     if (anOwner == anInteractive->GlobalSelOwner())
190     {
191       myObjects.ChangeFind (anInteractive)->SetHilightStatus (Standard_False);
192     }
193   }
194   for (NCollection_IndexedMap<Handle(AIS_InteractiveObject)>::Iterator anIter (anObjToClear); anIter.More(); anIter.Next())
195   {
196     const Handle(AIS_InteractiveObject)& anObj = anIter.Value();
197     myMainPM->Unhighlight (anObj);
198     anObj->ClearSelected();
199   }
200 }
201
202 //=======================================================================
203 //function : unhighlightGlobal
204 //purpose  :
205 //=======================================================================
206 void AIS_InteractiveContext::unhighlightGlobal (const Handle(AIS_InteractiveObject)& theObj) const
207 {
208   if (theObj.IsNull())
209   {
210     return;
211   }
212
213   const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
214   if (aGlobOwner.IsNull())
215   {
216     myMainPM->Unhighlight (theObj);
217     return;
218   }
219
220   if (aGlobOwner->IsAutoHilight())
221   {
222     aGlobOwner->Unhilight (myMainPM);
223   }
224   else
225   {
226     myMainPM->Unhighlight (theObj);
227     theObj->ClearSelected();
228   }
229 }
230
231 //=======================================================================
232 //function : turnOnSubintensity
233 //purpose  :
234 //=======================================================================
235 void AIS_InteractiveContext::turnOnSubintensity (const Handle(AIS_InteractiveObject)& theObject,
236                                                  const Standard_Integer theDispMode,
237                                                  const Standard_Boolean theIsDisplayedOnly) const
238 {
239   // the only differ with selection highlight is color, so sync transparency values
240   const Handle(Prs3d_Drawer)& aSubStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity];
241   aSubStyle->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
242
243   if (theObject.IsNull())
244   {
245     for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjsIter (myObjects); anObjsIter.More(); anObjsIter.Next())
246     {
247       const Handle(AIS_GlobalStatus)& aStatus = anObjsIter.Value();
248       if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
249         continue;
250
251       aStatus->SubIntensityOn();
252       myMainPM->Color (anObjsIter.Key(), aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
253     }
254   }
255   else
256   {
257     Handle(AIS_GlobalStatus) aStatus;
258     if (!myObjects.Find (theObject, aStatus))
259       return;
260
261     if (aStatus->GraphicStatus() != AIS_DS_Displayed && theIsDisplayedOnly)
262       return;
263
264     aStatus->SubIntensityOn();
265     myMainPM->Color (theObject, aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
266   }
267 }
268
269 //=======================================================================
270 //function : highlightWithSubintensity
271 //purpose  :
272 //=======================================================================
273 void AIS_InteractiveContext::highlightWithSubintensity (const Handle(AIS_InteractiveObject)& theObject,
274                                                         const Standard_Integer theMode) const
275 {
276   // the only differ with selection highlight is color, so
277   // sync transparency values
278   myStyles[Prs3d_TypeOfHighlight_SubIntensity]->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
279
280   myMainPM->Color (theObject, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode);
281 }
282
283 //=======================================================================
284 //function : highlightWithSubintensity
285 //purpose  :
286 //=======================================================================
287 void AIS_InteractiveContext::highlightWithSubintensity (const Handle(SelectMgr_EntityOwner)& theOwner,
288                                                         const Standard_Integer theMode) const
289 {
290   // the only differ with selection highlight is color, so
291   // sync transparency values
292   myStyles[Prs3d_TypeOfHighlight_SubIntensity]->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
293
294   theOwner->HilightWithColor (myMainPM, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode);
295 }
296
297 //=======================================================================
298 //function : MoveTo
299 //purpose  :
300 //=======================================================================
301 AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  theXPix,
302                                                       const Standard_Integer  theYPix,
303                                                       const Handle(V3d_View)& theView,
304                                                       const Standard_Boolean  theToRedrawOnUpdate)
305 {
306   if (HasOpenedContext())
307   {
308     myWasLastMain = Standard_True;
309     return myLocalContexts (myCurLocalIndex)->MoveTo (theXPix, theYPix, theView, theToRedrawOnUpdate);
310   }
311
312   myCurDetected = 0;
313   myCurHighlighted = 0;
314   myDetectedSeq.Clear();
315
316   if (theView->Viewer() != myMainVwr)
317   {
318     return AIS_SOD_Error;
319   }
320
321   // preliminaires
322   myLastPicked  = myLastinMain;
323   myWasLastMain = Standard_True;
324   AIS_StatusOfDetection aStatus        = AIS_SOD_Nothing;
325   Standard_Boolean      toUpdateViewer = Standard_False;
326
327   myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
328   myMainSel->Pick (theXPix, theYPix, theView);
329
330   // filling of myAISDetectedSeq sequence storing information about detected AIS objects
331   // (the objects must be AIS_Shapes)
332   const Standard_Integer aDetectedNb = myMainSel->NbPicked();
333   Standard_Integer aNewDetected = 0;
334   for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
335   {
336     Handle(SelectMgr_EntityOwner) anOwner = myMainSel->Picked (aDetIter);
337     if (anOwner.IsNull()
338      || !myFilters->IsOk (anOwner))
339     {
340       continue;
341     }
342
343     if (aNewDetected < 1)
344     {
345       aNewDetected = aDetIter;
346     }
347
348     myDetectedSeq.Append (aDetIter);
349   }
350
351   if (aNewDetected >= 1)
352   {
353     myCurHighlighted = myDetectedSeq.Lower();
354
355     // Does nothing if previously detected object is equal to the current one.
356     // However in advanced selection modes the owners comparison
357     // is not effective because in that case only one owner manage the
358     // selection in current selection mode. It is necessary to check the current detected
359     // entity and hilight it only if the detected entity is not the same as
360     // previous detected (IsForcedHilight call)
361     Handle(SelectMgr_EntityOwner) aNewPickedOwner = myMainSel->Picked (aNewDetected);
362     if (aNewPickedOwner == myLastPicked && !aNewPickedOwner->IsForcedHilight())
363     {
364       return myLastPicked->IsSelected()
365            ? AIS_SOD_Selected
366            : AIS_SOD_OnlyOneDetected;
367     }
368  
369     // Previously detected object is unhilighted if it is not selected or hilighted 
370     // with selection color if it is selected. Such highlighting with selection color 
371     // is needed only if myToHilightSelected flag is true. In this case previously detected
372     // object has been already highlighted with myHilightColor during previous MoveTo() 
373     // method call. As result it is necessary to rehighligt it with mySelectionColor.
374     if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
375     {
376       clearDynamicHighlight();
377       toUpdateViewer = Standard_True;
378     }
379
380     // initialize myLastPicked field with currently detected object
381     myLastPicked = aNewPickedOwner;
382     myLastinMain = myLastPicked;
383
384     // highlight detected object if it is not selected or myToHilightSelected flag is true
385     if (myLastPicked->HasSelectable())
386     {
387       if (!myLastPicked->IsSelected() || myToHilightSelected)
388       {
389         highlightWithColor (myLastPicked, theView->Viewer());
390         toUpdateViewer = Standard_True;
391       }
392
393       aStatus = myLastPicked->IsSelected()
394               ? AIS_SOD_Selected
395               : AIS_SOD_OnlyOneDetected;
396     }
397   }
398   else
399   {
400     // previously detected object is unhilighted if it is not selected or hilighted
401     // with selection color if it is selected
402     aStatus = AIS_SOD_Nothing;
403     if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
404     {
405       clearDynamicHighlight();
406       toUpdateViewer = Standard_True;
407     }
408
409     myLastinMain.Nullify();
410     myLastPicked.Nullify();
411   }
412
413   if (toUpdateViewer
414    && theToRedrawOnUpdate)
415   {
416     theView->Viewer()->Update();
417   }
418
419   mylastmoveview = theView;
420   return aStatus;
421 }
422
423 //=======================================================================
424 //function : AddSelect
425 //purpose  : 
426 //=======================================================================
427 AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
428 {
429   if (HasOpenedContext())
430   {
431     return myLocalContexts(myCurLocalIndex)->AddSelect (theObject);
432   }
433   mySelection->AddSelect (theObject);
434
435   Standard_Integer aSelNum = NbSelected();
436   return (aSelNum == 0) ? AIS_SOP_NothingSelected
437                         : (aSelNum == 1) ? AIS_SOP_OneSelected
438                                          : AIS_SOP_SeveralSelected;
439 }
440
441 //=======================================================================
442 //function : Select
443 //purpose  : 
444 //=======================================================================
445 AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMin,
446                                                  const Standard_Integer  theYPMin,
447                                                  const Standard_Integer  theXPMax,
448                                                  const Standard_Integer  theYPMax,
449                                                  const Handle(V3d_View)& theView,
450                                                  const Standard_Boolean  toUpdateViewer)
451 {
452   // all objects detected by the selector are taken, previous current objects are emptied,
453   // new objects are put...
454
455   if (HasOpenedContext())
456   {
457     return myLocalContexts(myCurLocalIndex)->Select (theXPMin, theYPMin,
458                                                      theXPMax, theYPMax,
459                                                      theView, toUpdateViewer);
460   }
461
462   ClearSelected (Standard_False);
463
464   Handle(StdSelect_ViewerSelector3d) aSelector;
465
466   if (theView->Viewer() == myMainVwr)
467   {
468     aSelector = myMainSel;
469     myWasLastMain = Standard_True;
470   }
471
472   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
473   for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
474   {
475     const Handle(SelectMgr_EntityOwner)& aCurOwner = aSelector->Picked (aPickIter);
476     if (aCurOwner.IsNull() || !aCurOwner->HasSelectable() || !myFilters->IsOk (aCurOwner))
477       continue;
478
479     mySelection->Select (aCurOwner);
480     aCurOwner->SetSelected (Standard_True);
481   }
482
483   HilightSelected (toUpdateViewer);
484
485   Standard_Integer aSelNum = NbSelected();
486
487   return (aSelNum == 0) ? AIS_SOP_NothingSelected
488                         : (aSelNum == 1) ? AIS_SOP_OneSelected
489                                          : AIS_SOP_SeveralSelected;
490   
491 }
492
493 //=======================================================================
494 //function : Select
495 //purpose  : Selection by polyline
496 //=======================================================================
497 AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
498                                                  const Handle(V3d_View)&     theView,
499                                                  const Standard_Boolean      toUpdateViewer)
500 {
501   // all objects detected by the selector are taken, previous current objects are emptied,
502   // new objects are put...
503
504   if (HasOpenedContext())
505   {
506     return myLocalContexts(myCurLocalIndex)->Select (thePolyline, theView, toUpdateViewer);
507   }
508
509   ClearSelected (Standard_False);
510
511   Handle(StdSelect_ViewerSelector3d) aSelector;
512
513   if (theView->Viewer() == myMainVwr)
514   {
515     aSelector = myMainSel;
516     myWasLastMain = Standard_True;
517   }
518
519   aSelector->Pick (thePolyline, theView);
520   for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
521   {
522     const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
523     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
524       continue;
525
526     mySelection->Select (anOwner);
527     anOwner->SetSelected (Standard_True);
528   }
529
530   HilightSelected (toUpdateViewer);
531
532   Standard_Integer aSelNum = NbSelected();
533
534   return (aSelNum == 0) ? AIS_SOP_NothingSelected
535                         : (aSelNum == 1) ? AIS_SOP_OneSelected
536                                          : AIS_SOP_SeveralSelected;
537   
538 }
539
540 //=======================================================================
541 //function : Select
542 //purpose  : 
543 //=======================================================================
544 AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean toUpdateViewer)
545 {
546   if (HasOpenedContext())
547   {
548     if(myWasLastMain)
549     {
550       return myLocalContexts(myCurLocalIndex)->Select (toUpdateViewer);
551     }
552     else
553     {
554       myLocalContexts(myCurLocalIndex)->SetSelected (Handle(AIS_InteractiveObject)::DownCast (myLastPicked->Selectable()), toUpdateViewer);
555       return AIS_SOP_OneSelected;
556     }
557   }
558
559   clearDynamicHighlight();
560   if (myWasLastMain && !myLastinMain.IsNull())
561   {
562     if (!myLastinMain->IsSelected() || myLastinMain->IsForcedHilight())
563     {
564       SetSelected (myLastinMain, Standard_False);
565       if(toUpdateViewer)
566       {
567         UpdateCurrentViewer();
568       }
569     }
570   }
571   else
572   {
573     unhighlightSelected (Standard_True);
574
575     mySelection->Clear();
576     if (toUpdateViewer && myWasLastMain)
577     {
578         UpdateCurrentViewer();
579     }
580   }
581
582   Standard_Integer aSelNum = NbSelected();
583
584   return (aSelNum == 0) ? AIS_SOP_NothingSelected
585                         : (aSelNum == 1) ? AIS_SOP_OneSelected
586                                          : AIS_SOP_SeveralSelected;
587 }
588
589 //=======================================================================
590 //function : ShiftSelect
591 //purpose  : 
592 //=======================================================================
593 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
594 {
595   if (HasOpenedContext())
596   {
597     if(myWasLastMain)
598     {
599       return myLocalContexts (myCurLocalIndex)->ShiftSelect (toUpdateViewer);
600     }
601     else
602     {
603       myLocalContexts (myCurLocalIndex)->AddOrRemoveSelected (myLastPicked, toUpdateViewer);
604
605       Standard_Integer aSelNum = NbSelected();
606       return (aSelNum == 0) ? AIS_SOP_NothingSelected
607                             : (aSelNum == 1) ? AIS_SOP_OneSelected
608                                              : AIS_SOP_SeveralSelected;
609     }
610   }
611
612   clearDynamicHighlight();
613   if (myWasLastMain && !myLastinMain.IsNull())
614   {
615     AddOrRemoveSelected (myLastinMain, toUpdateViewer);
616   }
617
618   Standard_Integer aSelNum = NbSelected();
619
620   return (aSelNum == 0) ? AIS_SOP_NothingSelected
621                         : (aSelNum == 1) ? AIS_SOP_OneSelected
622                         : AIS_SOP_SeveralSelected;
623 }
624
625 //=======================================================================
626 //function : ShiftSelect
627 //purpose  : 
628 //=======================================================================
629 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer theXPMin,
630                                                       const Standard_Integer theYPMin,
631                                                       const Standard_Integer theXPMax,
632                                                       const Standard_Integer theYPMax,
633                                                       const Handle(V3d_View)& theView,
634                                                       const Standard_Boolean toUpdateViewer)
635 {
636   if (HasOpenedContext())
637   {
638     return myLocalContexts(myCurLocalIndex)->ShiftSelect (theXPMin, theYPMin, theXPMax, theYPMax,
639                                                           theView, toUpdateViewer);
640   }
641
642   UnhilightSelected (Standard_False);
643
644   Handle(StdSelect_ViewerSelector3d) aSelector;
645   if (theView->Viewer() == myMainVwr)
646   {
647     aSelector = myMainSel;
648     myWasLastMain = Standard_True;
649   }
650   else
651   {
652     return AIS_SOP_NothingSelected;
653   }
654
655   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
656   for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
657   {
658     const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
659     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
660       continue;
661
662     AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
663     anOwner->SetSelected (aSelStatus == AIS_SS_Added);
664   }
665
666   HilightSelected (toUpdateViewer);
667
668   Standard_Integer aSelNum = NbSelected();
669
670   return (aSelNum == 0) ? AIS_SOP_NothingSelected
671                         : (aSelNum == 1) ? AIS_SOP_OneSelected
672                                          : AIS_SOP_SeveralSelected;
673
674 }
675
676 //=======================================================================
677 //function : ShiftSelect
678 //purpose  : 
679 //=======================================================================
680 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
681                                                       const Handle(V3d_View)& theView,
682                                                       const Standard_Boolean toUpdateViewer)
683 {
684   if (HasOpenedContext())
685   {
686     return myLocalContexts(myCurLocalIndex)->ShiftSelect (thePolyline, theView, toUpdateViewer);
687   }
688
689   UnhilightSelected (Standard_False);
690
691   Handle(StdSelect_ViewerSelector3d) aSelector;
692
693   if (theView->Viewer() == myMainVwr)
694   {
695     aSelector= myMainSel;
696     myWasLastMain = Standard_True;
697   }
698   else
699   {
700     return AIS_SOP_NothingSelected;
701   }
702
703   aSelector->Pick (thePolyline, theView);
704   for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
705   {
706     const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
707     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
708       continue;
709
710     AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
711     anOwner->SetSelected (aSelStatus == AIS_SS_Added);
712   }
713
714   HilightSelected (toUpdateViewer);
715
716   Standard_Integer aSelNum = NbSelected();
717
718   return (aSelNum == 0) ? AIS_SOP_NothingSelected
719                         : (aSelNum == 1) ? AIS_SOP_OneSelected
720                                          : AIS_SOP_SeveralSelected;
721 }
722
723 //=======================================================================
724 //function : SetCurrentObject
725 //purpose  : OBSOLETE, please use SetSelected() instead
726 //TODO     : Remove in process of local context deletion
727 //=======================================================================
728 void AIS_InteractiveContext::SetCurrentObject (const Handle(AIS_InteractiveObject)& theObject,
729                                                const Standard_Boolean theToUpdateViewer)
730 {
731   if (HasOpenedContext())
732     return;
733
734   SetSelected (theObject, theToUpdateViewer);
735 }
736
737 //=======================================================================
738 //function : AddOrRemoveCurrentObject
739 //purpose  : OBSOLETE, please use AddOrRemoveSelected() instead
740 //TODO     : Remove in process of local context deletion
741 //=======================================================================
742 void AIS_InteractiveContext::AddOrRemoveCurrentObject (const Handle(AIS_InteractiveObject)& theObj,
743                                                        const Standard_Boolean theIsToUpdateViewer)
744 {
745   if (HasOpenedContext())
746     return;
747
748   AddOrRemoveSelected (theObj, theIsToUpdateViewer);
749 }
750 //=======================================================================
751 //function : UpdateCurrent
752 //purpose  : OBSOLETE, please use UpdateSelected() instead
753 //TODO     : Remove in process of local context deletion
754 //=======================================================================
755 void AIS_InteractiveContext::UpdateCurrent()
756 {
757   UpdateSelected (Standard_True);
758 }
759
760 //=======================================================================
761 //function : IsCurrent
762 //purpose  : OBSOLETE, please use IsSelected() instead
763 //TODO     : Remove in process of local context deletion
764 //=======================================================================
765 Standard_Boolean AIS_InteractiveContext::IsCurrent (const Handle(AIS_InteractiveObject)& theObject) const
766 {
767   return IsSelected (theObject);
768 }
769
770 //=======================================================================
771 //function : InitCurrent
772 //purpose  : OBSOLETE, please use InitSelected() instead
773 //TODO     : Remove in process of local context deletion
774 //=======================================================================
775 void AIS_InteractiveContext::InitCurrent()
776 {
777   if (HasOpenedContext())
778     return;
779
780   InitSelected();
781 }
782
783 //=======================================================================
784 //function : MoreCurrent
785 //purpose  : OBSOLETE, please use MoreSelected() instead
786 //TODO     : Remove in process of local context deletion
787 //=======================================================================
788 Standard_Boolean AIS_InteractiveContext::MoreCurrent() const 
789 {
790   return !HasOpenedContext() && MoreSelected();
791 }
792
793 //=======================================================================
794 //function : NextCurrent
795 //purpose  : OBSOLETE, please use NextSelected() instead
796 //TODO     : Remove in process of local context deletion
797 //=======================================================================
798 void AIS_InteractiveContext::NextCurrent()
799 {
800   if (HasOpenedContext())
801     return;
802
803   NextSelected();
804 }
805
806 //=======================================================================
807 //function : Current
808 //purpose  : OBSOLETE, please use SelectedInteractive() instead
809 //TODO     : Remove in process of local context deletion
810 //=======================================================================
811 Handle(AIS_InteractiveObject) AIS_InteractiveContext::Current() const 
812 {
813   return HasOpenedContext() ? NULL : SelectedInteractive();
814 }
815
816 //=======================================================================
817 //function : NbCurrents
818 //purpose  : OBSOLETE, please use NbSelected() instead
819 //TODO     : Remove in process of local context deletion
820 //=======================================================================
821 Standard_Integer AIS_InteractiveContext::NbCurrents()
822 {
823   return HasOpenedContext() ? -1 : NbSelected();
824 }
825
826 //=======================================================================
827 //function : HilightCurrents
828 //purpose  : OBSOLETE, please use HilightSelected() instead
829 //TODO     : Remove in process of local context deletion
830 //=======================================================================
831 void AIS_InteractiveContext::HilightCurrents (const Standard_Boolean theToUpdateViewer)
832 {
833   if (HasOpenedContext())
834     return;
835
836   HilightSelected (theToUpdateViewer);
837 }
838
839 //=======================================================================
840 //function : UnhilightCurrents
841 //purpose  : OBSOLETE, please use UnhilightSelected() instead
842 //TODO     : Remove in process of local context deletion
843 //=======================================================================
844 void AIS_InteractiveContext::UnhilightCurrents (const Standard_Boolean theToUpdateViewer)
845 {
846   if (HasOpenedContext())
847     return;
848
849   UnhilightSelected (theToUpdateViewer);
850 }
851
852 //=======================================================================
853 //function : ClearCurrents
854 //purpose  : OBSOLETE, please use ClearCurrents() instead
855 //TODO     : Remove in process of local context deletion
856 //=======================================================================
857 void AIS_InteractiveContext::ClearCurrents(const Standard_Boolean theToUpdateViewer)
858 {
859   if (HasOpenedContext())
860     return;
861
862   ClearSelected (theToUpdateViewer);
863 }
864
865
866 //=======================================================================
867 //function : HilightSelected
868 //purpose  :
869 //=======================================================================
870 void AIS_InteractiveContext::HilightSelected (const Standard_Boolean theToUpdateViewer)
871 {
872   if (HasOpenedContext())
873   {
874     return myLocalContexts (myCurLocalIndex)->HilightPicked (theToUpdateViewer);
875   }
876
877   // In case of selection without using local context
878   clearDynamicHighlight();
879   AIS_MapOfObjSelectedOwners anObjOwnerMap;
880   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
881   {
882     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
883     const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
884     const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObj, anOwner);
885     Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind(anObj);
886     if (anOwner == anObj->GlobalSelOwner())
887     {
888       aState->SetHilightStatus (Standard_True);
889       aState->SetHilightStyle (anObjSelStyle);
890     }
891     anOwner->SetSelected (Standard_True);
892     if (!anOwner->IsAutoHilight())
893     {
894       NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
895       if (anObjOwnerMap.Find (anObj, aSeq))
896       {
897         aSeq->Append (anOwner);
898       }
899       else
900       {
901         aSeq = new SelectMgr_SequenceOfOwner();
902         aSeq->Append (anOwner);
903         anObjOwnerMap.Bind (anObj, aSeq);
904       }
905     }
906     else
907     {
908       const Standard_Integer aHiMode = getHilightMode (anObj, anObjSelStyle, aState->DisplayMode());
909       anOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
910     }
911   }
912
913   if (!anObjOwnerMap.IsEmpty())
914   {
915     for (AIS_MapOfObjSelectedOwners::Iterator anIter (anObjOwnerMap); anIter.More(); anIter.Next())
916     {
917       anIter.Key()->HilightSelected (myMainPM, *anIter.Value());
918     }
919     anObjOwnerMap.Clear();
920   }
921
922   if (theToUpdateViewer)
923     UpdateCurrentViewer();
924 }
925
926 //=======================================================================
927 //function : UnhilightSelected
928 //purpose  :
929 //=======================================================================
930 void AIS_InteractiveContext::UnhilightSelected (const Standard_Boolean theToUpdateViewer)
931 {
932   if (HasOpenedContext())
933   {
934     return myLocalContexts (myCurLocalIndex)->UnhilightPicked (theToUpdateViewer);
935   }
936
937   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
938   {
939     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
940     const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
941     if (anOwner == anObj->GlobalSelOwner())
942     {
943       myObjects.ChangeFind (anObj)->SetHilightStatus (Standard_False);
944     }
945
946     anOwner->SetSelected (Standard_False);
947     anOwner->Unhilight (myMainPM);
948   }
949
950   if (theToUpdateViewer)
951     UpdateCurrentViewer();
952 }
953
954
955 //=======================================================================
956 //function : ClearSelected
957 //purpose  :
958 //=======================================================================
959 void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateViewer)
960 {
961   if (HasOpenedContext())
962     return myLocalContexts (myCurLocalIndex)->ClearSelected (theToUpdateViewer);
963
964   if (NbSelected() == 0)
965     return;
966
967   unhighlightSelected();
968
969   mySelection->Clear();
970   clearDynamicHighlight();
971
972   if (theToUpdateViewer)
973     UpdateCurrentViewer();
974 }
975
976 //=======================================================================
977 //function : UpdateSelected
978 //purpose  :
979 //=======================================================================
980 void AIS_InteractiveContext::UpdateSelected (const Standard_Boolean theToUpdateViewer)
981 {
982   if (HasOpenedContext())
983   {
984     return myLocalContexts(myCurLocalIndex)->UpdateSelected (theToUpdateViewer);
985   }
986
987   HilightSelected (theToUpdateViewer);
988 }
989
990 //=======================================================================
991 //function : SetSelected
992 //purpose  : Sets the whole object as selected and highlights it with selection color
993 //=======================================================================
994 void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& theObject,
995                                           const Standard_Boolean theToUpdateViewer)
996 {
997   if (HasOpenedContext())
998   {
999     return myLocalContexts (myCurLocalIndex)->SetSelected (theObject, theToUpdateViewer);
1000   }
1001
1002   if (theObject.IsNull())
1003   {
1004     return;
1005   }
1006
1007   if (!myObjects.IsBound (theObject))
1008   {
1009     Display (theObject, Standard_False);
1010   }
1011   if (!theObject->HasSelection (theObject->GlobalSelectionMode()))
1012   {
1013     return;
1014   }
1015   Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
1016   if (anOwner.IsNull())
1017   {
1018     return;
1019   }
1020
1021   const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (theObject, anOwner);
1022   if (NbSelected() == 1 && myObjects (theObject)->IsHilighted())
1023   {
1024     Handle(Prs3d_Drawer) aCustomStyle;
1025     if (HighlightStyle (theObject, aCustomStyle))
1026     {
1027       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
1028       {
1029         HilightWithColor (theObject, anObjSelStyle, theToUpdateViewer);
1030       }
1031     }
1032     return;
1033   }
1034
1035   for (mySelection->Init(); mySelection->More(); mySelection->Next())
1036   {
1037     const Handle(SelectMgr_EntityOwner) aSelOwner = mySelection->Value();
1038     if (!myFilters->IsOk (aSelOwner))
1039     {
1040       continue;
1041     }
1042
1043     Handle(AIS_InteractiveObject) aSelectable = Handle(AIS_InteractiveObject)::DownCast (aSelOwner->Selectable());
1044     Unhilight (aSelectable, Standard_False);
1045     aSelOwner->SetSelected (Standard_False);
1046     if (aSelOwner == aSelectable->GlobalSelOwner())
1047     {
1048       myObjects.ChangeFind (aSelectable)->SetHilightStatus (Standard_False);
1049     }
1050   }
1051
1052   // added to avoid untimely viewer update...
1053   mySelection->ClearAndSelect (anOwner);
1054
1055   Handle(Prs3d_Drawer) aCustomStyle;
1056   if (HighlightStyle (theObject, aCustomStyle))
1057   {
1058     if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
1059     {
1060       HilightWithColor (theObject, anObjSelStyle, Standard_False);
1061     }
1062   }
1063   else
1064   {
1065     HilightWithColor (theObject, anObjSelStyle, Standard_False);
1066   }
1067   anOwner->SetSelected (Standard_True);
1068
1069   if (theToUpdateViewer)
1070     UpdateCurrentViewer();
1071 }
1072
1073 //=======================================================================
1074 //function : SetSelected
1075 //purpose  : Sets the whole object as selected and highlights it with selection color
1076 //=======================================================================
1077 void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1078                                           const Standard_Boolean theToUpdateViewer)
1079 {
1080   if (theOwner.IsNull() || !theOwner->HasSelectable() || !myFilters->IsOk (theOwner))
1081     return;
1082
1083   const Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
1084   const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObject, theOwner);
1085   if (NbSelected() == 1 && theOwner->IsSelected() && !theOwner->IsForcedHilight())
1086   {
1087     Handle(Prs3d_Drawer) aCustomStyle;
1088     if (HighlightStyle (theOwner, aCustomStyle))
1089     {
1090       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
1091       {
1092         const Standard_Integer aHiMode = anObject->HasHilightMode() ? anObject->HilightMode() : 0;
1093         theOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
1094       }
1095     }
1096     return;
1097   }
1098
1099   if (!myObjects.IsBound (anObject))
1100     Display (anObject, Standard_False);
1101
1102   unhighlightSelected();
1103
1104   mySelection->ClearAndSelect (theOwner);
1105   Handle(Prs3d_Drawer) aCustomStyle;
1106   if (!HighlightStyle (theOwner, aCustomStyle) ||
1107     (!aCustomStyle.IsNull() && aCustomStyle != anObjSelStyle))
1108   {
1109     theOwner->SetSelected (Standard_True);
1110     highlightSelected (theOwner);
1111   }
1112
1113   theOwner->SetSelected (Standard_True);
1114   if (theOwner == anObject->GlobalSelOwner())
1115   {
1116     Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObject);
1117     aState->SetHilightStatus (Standard_True);
1118     aState->SetHilightStyle (anObjSelStyle);
1119   }
1120
1121   if (theToUpdateViewer)
1122     UpdateCurrentViewer();
1123 }
1124
1125 //=======================================================================
1126 //function : AddOrRemoveSelected
1127 //purpose  : Adds or removes current object from AIS selection and highlights/unhighlights it.
1128 //           Since this method makes sence only for neutral point selection of a whole object,
1129 //           if 0 selection of the object is empty this method simply does nothing.
1130 //=======================================================================
1131 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveObject)& theObject,
1132                                                   const Standard_Boolean theToUpdateViewer)
1133 {
1134   if (theObject.IsNull())
1135     return;
1136
1137   if (HasOpenedContext())
1138     return myLocalContexts (myCurLocalIndex)->AddOrRemoveSelected (theObject, theToUpdateViewer);
1139
1140   const Standard_Integer aGlobalSelMode = theObject->GlobalSelectionMode();
1141   if (!myObjects.IsBound (theObject) || !theObject->HasSelection (aGlobalSelMode))
1142     return;
1143
1144   setContextToObject (theObject);
1145   const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
1146
1147   if (anOwner.IsNull() || !anOwner->HasSelectable())
1148     return;
1149
1150   AddOrRemoveSelected (anOwner, theToUpdateViewer);
1151 }
1152 //=======================================================================
1153 //function : AddOrRemoveSelected
1154 //purpose  : 
1155 //=======================================================================
1156
1157 void AIS_InteractiveContext::AddOrRemoveSelected (const TopoDS_Shape& aShap,
1158                                             const Standard_Boolean updateviewer)
1159
1160   if(!HasOpenedContext()) {
1161 #ifdef OCCT_DEBUG
1162     cout<<" Attempt to remove a selected shape with no opened local context"<<endl;
1163 #endif
1164     return;
1165   }
1166   
1167   myLocalContexts(myCurLocalIndex)->AddOrRemoveSelected(aShap,updateviewer);
1168   if(updateviewer) UpdateCurrentViewer();
1169   
1170 }
1171
1172 //=======================================================================
1173 //function : AddOrRemoveSelected
1174 //purpose  : Allows to highlight or unhighlight the owner given depending on
1175 //           its selection status
1176 //=======================================================================
1177 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1178                                                   const Standard_Boolean theToUpdateViewer)
1179 {
1180   if (HasOpenedContext())
1181     return myLocalContexts(myCurLocalIndex)->AddOrRemoveSelected (theOwner, theToUpdateViewer);
1182
1183   if (theOwner.IsNull() || !theOwner->HasSelectable())
1184     return;
1185
1186   if (!myFilters->IsOk(theOwner) && !theOwner->IsSelected())
1187     return;
1188
1189   AIS_SelectStatus aSelStat = mySelection->Select (theOwner);
1190   theOwner->SetSelected (aSelStat == AIS_SS_Added);
1191   const Handle(AIS_InteractiveObject) anObj =
1192     Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
1193   const Standard_Boolean isGlobal = anObj->GlobalSelOwner() == theOwner;
1194   Handle(AIS_GlobalStatus)& aStatus = myObjects.ChangeFind (anObj);
1195   if (theOwner->IsSelected())
1196   {
1197     highlightSelected (theOwner);
1198     if (isGlobal)
1199     {
1200       aStatus->SetHilightStatus (Standard_True);
1201       aStatus->SetHilightStyle (getSelStyle (anObj, theOwner));
1202     }
1203   }
1204   else
1205   {
1206     if (theOwner->IsAutoHilight())
1207     {
1208       theOwner->Unhilight (myMainPM);
1209     }
1210     else
1211     {
1212       anObj->ClearSelected();
1213     }
1214     aStatus->SetHilightStatus (Standard_False);
1215     aStatus->SetHilightStyle (Handle(Prs3d_Drawer)());
1216   }
1217
1218   if (theToUpdateViewer)
1219     UpdateCurrentViewer();
1220 }
1221
1222
1223 //=======================================================================
1224 //function : IsSelected
1225 //purpose  :
1226 //=======================================================================
1227 Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(AIS_InteractiveObject)& theObj) const
1228 {
1229   if(HasOpenedContext())
1230     return myLocalContexts(myCurLocalIndex)->IsSelected (theObj);
1231
1232   if (theObj.IsNull() || !myObjects.IsBound (theObj))
1233     return Standard_False;
1234
1235   const Standard_Integer aGlobalSelMode = theObj->GlobalSelectionMode();
1236   const TColStd_ListOfInteger& anActivatedModes = myObjects (theObj)->SelectionModes();
1237   Standard_Boolean isGlobalModeActivated = Standard_False;
1238   for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next())
1239   {
1240     if (aModeIter.Value() == aGlobalSelMode)
1241     {
1242       isGlobalModeActivated = Standard_True;
1243       break;
1244     }
1245   }
1246   if (!theObj->HasSelection (aGlobalSelMode) || !isGlobalModeActivated || theObj->GlobalSelOwner().IsNull())
1247     return Standard_False;
1248
1249   return theObj->GlobalSelOwner()->IsSelected();
1250 }
1251
1252 //=======================================================================
1253 //function : IsSelected
1254 //purpose  : Returns true is the owner given is selected
1255 //=======================================================================
1256 Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
1257 {
1258   if (HasOpenedContext())
1259     return myLocalContexts(myCurLocalIndex)->IsSelected (theOwner);
1260
1261   if (theOwner.IsNull())
1262     return Standard_False;
1263
1264   return theOwner->IsSelected();
1265 }
1266
1267 //=======================================================================
1268 //function : InitSelected
1269 //purpose  :
1270 //=======================================================================
1271 void AIS_InteractiveContext::InitSelected()
1272 {
1273   if (HasOpenedContext())
1274   {
1275     myLocalContexts (myCurLocalIndex)->InitSelected();
1276     return;
1277   }
1278
1279   mySelection->Init();
1280 }
1281
1282 //=======================================================================
1283 //function : MoreSelected
1284 //purpose  :
1285 //=======================================================================
1286 Standard_Boolean AIS_InteractiveContext::MoreSelected() const
1287 {
1288   if (HasOpenedContext())
1289     return myLocalContexts (myCurLocalIndex)->MoreSelected();
1290
1291   return mySelection->More();
1292 }
1293
1294 //=======================================================================
1295 //function : NextSelected
1296 //purpose  :
1297 //=======================================================================
1298 void AIS_InteractiveContext::NextSelected()
1299 {
1300   if(HasOpenedContext())
1301   {
1302     return myLocalContexts (myCurLocalIndex)->NextSelected();
1303   }
1304
1305   mySelection->Next();
1306 }
1307
1308 //=======================================================================
1309 //function : HasSelectedShape
1310 //purpose  :
1311 //=======================================================================
1312 Standard_Boolean AIS_InteractiveContext::HasSelectedShape() const
1313 {
1314   if(HasOpenedContext())
1315   {
1316     return myLocalContexts(myCurLocalIndex)->HasSelectedShape();
1317   }
1318   if (!mySelection->More())
1319     return Standard_False;
1320
1321   const Handle(StdSelect_BRepOwner) anOwner =
1322     Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
1323
1324   return !anOwner.IsNull() && anOwner->HasShape();
1325 }
1326
1327 //=======================================================================
1328 //function : SelectedShape
1329 //purpose  :
1330 //=======================================================================
1331 TopoDS_Shape AIS_InteractiveContext::SelectedShape() const
1332 {
1333   if (HasOpenedContext())
1334   {
1335     return myLocalContexts (myCurLocalIndex)->SelectedShape();
1336   }
1337
1338   if (!mySelection->More())
1339     return TopoDS_Shape();
1340
1341   const Handle(StdSelect_BRepOwner) anOwner =
1342     Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
1343   if (anOwner.IsNull() || !anOwner->HasSelectable())
1344     return TopoDS_Shape();
1345
1346   return anOwner->Shape().Located (anOwner->Location() * anOwner->Shape().Location());
1347 }
1348
1349 //=======================================================================
1350 //function : SelectedInteractive
1351 //purpose  :
1352 //=======================================================================
1353 Handle(AIS_InteractiveObject) AIS_InteractiveContext::SelectedInteractive() const 
1354 {
1355   if (HasOpenedContext())
1356   {
1357     return myLocalContexts(myCurLocalIndex)->SelectedInteractive();
1358   }
1359
1360   return !mySelection->More()
1361        ? Handle(AIS_InteractiveObject)()
1362        : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
1363 }
1364 //=======================================================================
1365 //function : SelectedOwner
1366 //purpose  :
1367 //=======================================================================
1368 Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::SelectedOwner() const
1369 {
1370   if(HasOpenedContext())
1371   {
1372     return myLocalContexts(myCurLocalIndex)->SelectedOwner();
1373   }
1374
1375   return !mySelection->More()
1376        ? Handle(SelectMgr_EntityOwner)()
1377        : mySelection->Value();
1378 }
1379
1380 //=======================================================================
1381 //function : EntityOwners
1382 //purpose  : 
1383 //=======================================================================
1384 void AIS_InteractiveContext::EntityOwners(Handle(SelectMgr_IndexedMapOfOwner)& theOwners,
1385                                           const Handle(AIS_InteractiveObject)& theIObj,
1386                                           const Standard_Integer theMode) const 
1387 {
1388   if ( theIObj.IsNull() )
1389       return;
1390
1391   TColStd_ListOfInteger aModes;
1392   if ( theMode == -1 )
1393     ActivatedModes( theIObj, aModes );
1394   else
1395     aModes.Append( theMode );
1396
1397   if (theOwners.IsNull())
1398     theOwners = new SelectMgr_IndexedMapOfOwner();
1399
1400   TColStd_ListIteratorOfListOfInteger anItr( aModes );
1401   for (; anItr.More(); anItr.Next() )
1402   {
1403     int aMode = anItr.Value();
1404     if ( !theIObj->HasSelection( aMode ) )
1405       continue;
1406
1407     Handle(SelectMgr_Selection) aSel = theIObj->Selection(aMode);
1408
1409     for ( aSel->Init(); aSel->More(); aSel->Next() )
1410     {
1411       Handle(SelectBasics_SensitiveEntity) aEntity = aSel->Sensitive()->BaseSensitive();
1412       if ( aEntity.IsNull() )
1413         continue;
1414
1415       Handle(SelectMgr_EntityOwner) aOwner =
1416         Handle(SelectMgr_EntityOwner)::DownCast(aEntity->OwnerId());
1417       if ( !aOwner.IsNull() )
1418         theOwners->Add( aOwner );
1419     }
1420   }
1421 }
1422
1423 //=======================================================================
1424 //function : NbSelected
1425 //purpose  :
1426 //=======================================================================
1427 Standard_Integer AIS_InteractiveContext::NbSelected()
1428 {
1429   Standard_Integer aNbSelected = 0;
1430   for (InitSelected(); MoreSelected(); NextSelected())
1431   {
1432     aNbSelected++;
1433   }
1434
1435   return aNbSelected;
1436 }
1437
1438 //=======================================================================
1439 //function : HasApplicative
1440 //purpose  :
1441 //=======================================================================
1442   Standard_Boolean AIS_InteractiveContext::HasApplicative() const 
1443 {
1444   return SelectedInteractive()->HasOwner();
1445 }
1446
1447 //=======================================================================
1448 //function : Applicative
1449 //purpose  :
1450 //=======================================================================
1451 Handle(Standard_Transient) AIS_InteractiveContext::Applicative() const 
1452 {
1453   return SelectedInteractive()->GetOwner();
1454 }
1455
1456 //==================================================
1457 // Function: HasDetected
1458 // Purpose :
1459 //==================================================
1460 Standard_Boolean AIS_InteractiveContext::HasDetected() const
1461 {
1462   if(HasOpenedContext())
1463     return myLocalContexts(myCurLocalIndex)->HasDetected();
1464
1465   return !myLastPicked.IsNull();
1466 }
1467
1468 //=======================================================================
1469 //function : HasDetectedShape
1470 //purpose  : 
1471 //=======================================================================
1472
1473 Standard_Boolean AIS_InteractiveContext::HasDetectedShape() const 
1474 {
1475   if(HasOpenedContext())
1476     return myLocalContexts(myCurLocalIndex)->HasDetectedShape();
1477   return Standard_False;
1478 }
1479
1480 //=======================================================================
1481 //function : DetectedShape
1482 //purpose  : 
1483 //=======================================================================
1484
1485 const TopoDS_Shape&
1486 AIS_InteractiveContext::DetectedShape() const
1487 {
1488   return myLocalContexts(myCurLocalIndex)->DetectedShape();
1489 }                                           
1490
1491 //=======================================================================
1492 //function : DetectedInteractive
1493 //purpose  :
1494 //=======================================================================
1495 Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedInteractive() const
1496 {
1497   if (HasOpenedContext())
1498     return myLocalContexts(myCurLocalIndex)->DetectedInteractive();
1499
1500   return Handle(AIS_InteractiveObject)::DownCast (myLastPicked->Selectable());
1501 }
1502
1503 //=======================================================================
1504 //function : HasNextDetected
1505 //purpose  :
1506 //=======================================================================
1507 Standard_Boolean AIS_InteractiveContext::HasNextDetected() const 
1508 {
1509   if (HasOpenedContext())
1510   {
1511     return myLocalContexts(myCurLocalIndex)->HasNextDetected();
1512   }
1513
1514   return !myDetectedSeq.IsEmpty() && myCurHighlighted <= myDetectedSeq.Upper();
1515 }
1516
1517
1518 //=======================================================================
1519 //function : DetectedOwner
1520 //purpose  : 
1521 //=======================================================================
1522 Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::DetectedOwner() const
1523 {
1524   if (HasOpenedContext())
1525     return myLocalContexts(myCurLocalIndex)->DetectedOwner();
1526
1527   return myLastPicked;
1528 }
1529
1530 //=======================================================================
1531 //function : HilightNextDetected
1532 //purpose  :
1533 //=======================================================================
1534 Standard_Integer AIS_InteractiveContext::HilightNextDetected (const Handle(V3d_View)& theView,
1535                                                               const Standard_Boolean  theToRedrawImmediate)
1536 {
1537   if (HasOpenedContext())
1538   {
1539     return myLocalContexts (myCurLocalIndex)->HilightNextDetected (theView, theToRedrawImmediate);
1540   }
1541
1542   myMainPM->ClearImmediateDraw();
1543   if (myDetectedSeq.IsEmpty())
1544   {
1545     return 0;
1546   }
1547
1548   if (++myCurHighlighted > myDetectedSeq.Upper())
1549   {
1550     myCurHighlighted = myDetectedSeq.Lower();
1551   }
1552   const Handle(SelectMgr_EntityOwner)& anOwner = myMainSel->Picked (myDetectedSeq (myCurHighlighted));
1553   if (anOwner.IsNull())
1554   {
1555     return 0;
1556   }
1557
1558   highlightWithColor (anOwner, theView->Viewer());
1559   myLastPicked = anOwner;
1560   myLastinMain = myLastPicked;
1561
1562   if (theToRedrawImmediate)
1563   {
1564     myMainPM->RedrawImmediate (theView->Viewer());
1565     myMainVwr->RedrawImmediate();
1566   }
1567
1568   return myCurHighlighted;
1569 }
1570
1571 //=======================================================================
1572 //function : HilightPreviousDetected
1573 //purpose  :
1574 //=======================================================================
1575 Standard_Integer AIS_InteractiveContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1576                                                                   const Standard_Boolean  theToRedrawImmediate)
1577 {
1578   if (HasOpenedContext())
1579   {
1580     return myLocalContexts (myCurLocalIndex)->HilightPreviousDetected (theView, theToRedrawImmediate);
1581   }
1582
1583   myMainPM->ClearImmediateDraw();
1584   if (myDetectedSeq.IsEmpty())
1585   {
1586     return 0;
1587   }
1588
1589   if (--myCurHighlighted < myDetectedSeq.Lower())
1590   {
1591     myCurHighlighted = myDetectedSeq.Upper();
1592   }
1593   const Handle(SelectMgr_EntityOwner)& anOwner = myMainSel->Picked (myDetectedSeq (myCurHighlighted));
1594   if (anOwner.IsNull())
1595   {
1596     return 0;
1597   }
1598
1599   highlightWithColor (anOwner, theView->Viewer());
1600   myLastPicked = anOwner;
1601   myLastinMain = myLastPicked;
1602
1603   if (theToRedrawImmediate)
1604   {
1605     myMainPM->RedrawImmediate (theView->Viewer());
1606     myMainVwr->RedrawImmediate();
1607   }
1608
1609   return myCurHighlighted;
1610 }
1611
1612 //=======================================================================
1613 //function : InitDetected
1614 //purpose  :
1615 //=======================================================================
1616 void AIS_InteractiveContext::InitDetected()
1617 {
1618   if (HasOpenedContext())
1619   {
1620     myLocalContexts (myCurLocalIndex)->InitDetected();
1621     return;
1622   }
1623
1624   if (!myDetectedSeq.IsEmpty())
1625   {
1626     myCurDetected = myDetectedSeq.Lower();
1627   }
1628 }
1629
1630 //=======================================================================
1631 //function : MoreDetected
1632 //purpose  :
1633 //=======================================================================
1634 Standard_Boolean AIS_InteractiveContext::MoreDetected() const
1635 {
1636   if (HasOpenedContext())
1637   {
1638     return myLocalContexts (myCurLocalIndex)->MoreDetected();
1639   }
1640
1641   return myCurDetected >= myDetectedSeq.Lower() && myCurDetected <= myDetectedSeq.Upper();
1642 }
1643
1644 //=======================================================================
1645 //function : NextDetected
1646 //purpose  :
1647 //=======================================================================
1648 void AIS_InteractiveContext::NextDetected()
1649 {
1650   if (HasOpenedContext())
1651   {
1652     myLocalContexts (myCurLocalIndex)->NextDetected();
1653     return;
1654   }
1655
1656   myCurDetected++;
1657 }
1658
1659 //=======================================================================
1660 //function : DetectedCurrentShape
1661 //purpose  :
1662 //=======================================================================
1663 const TopoDS_Shape& AIS_InteractiveContext::DetectedCurrentShape() const
1664 {
1665   if (HasOpenedContext())
1666   {
1667     return myLocalContexts(myCurLocalIndex)->DetectedCurrentShape();
1668   }
1669
1670   Standard_DISABLE_DEPRECATION_WARNINGS
1671   Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1672   Standard_ENABLE_DEPRECATION_WARNINGS
1673
1674   if (aCurrentShape.IsNull())
1675   {
1676     return AIS_myDummyShape;
1677   }
1678
1679   return aCurrentShape->Shape();
1680 }
1681
1682 //=======================================================================
1683 //function : DetectedCurrentObject
1684 //purpose  :
1685 //=======================================================================
1686 Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedCurrentObject() const
1687 {
1688   if (HasOpenedContext())
1689   {
1690     return myLocalContexts(myCurLocalIndex)->DetectedCurrentObject();
1691   }
1692
1693   return MoreDetected()
1694     ? Handle(AIS_InteractiveObject)::DownCast (myMainSel->Picked (myDetectedSeq (myCurDetected))->Selectable())
1695     : NULL;
1696 }
1697
1698 //=======================================================================
1699 //function : FirstSelectedObject
1700 //purpose  :
1701 //=======================================================================
1702 Handle(AIS_InteractiveObject) AIS_InteractiveContext::FirstSelectedObject()
1703 {
1704   Handle(AIS_InteractiveObject) anObject;
1705
1706   if (HasOpenedContext())
1707     return anObject;
1708
1709   InitSelected();
1710   if (MoreSelected())
1711   {
1712     return SelectedInteractive();
1713   }
1714   return anObject;
1715 }
1716
1717 //=======================================================================
1718 //function : RedrawImmediate
1719 //purpose  : Redisplays immediate strucures of the viewer given according to their visibility
1720 //=======================================================================
1721 void AIS_InteractiveContext::RedrawImmediate (const Handle(V3d_Viewer)& theViewer)
1722 {
1723   myMainPM->RedrawImmediate (theViewer);
1724 }