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