1e7ac281e18d5737091e19d2f1a736c3515f369e
[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()
568       || myLastinMain->IsForcedHilight()
569       || NbSelected() > 1)
570     {
571       SetSelected (myLastinMain, Standard_False);
572       if(toUpdateViewer)
573       {
574         UpdateCurrentViewer();
575       }
576     }
577   }
578   else
579   {
580     unhighlightSelected (Standard_True);
581
582     mySelection->Clear();
583     if (toUpdateViewer && myWasLastMain)
584     {
585         UpdateCurrentViewer();
586     }
587   }
588
589   Standard_Integer aSelNum = NbSelected();
590
591   return (aSelNum == 0) ? AIS_SOP_NothingSelected
592                         : (aSelNum == 1) ? AIS_SOP_OneSelected
593                                          : AIS_SOP_SeveralSelected;
594 }
595
596 //=======================================================================
597 //function : ShiftSelect
598 //purpose  : 
599 //=======================================================================
600 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
601 {
602   if (HasOpenedContext())
603   {
604     if(myWasLastMain)
605     {
606       return myLocalContexts (myCurLocalIndex)->ShiftSelect (toUpdateViewer);
607     }
608     else
609     {
610       myLocalContexts (myCurLocalIndex)->AddOrRemoveSelected (myLastPicked, toUpdateViewer);
611
612       Standard_Integer aSelNum = NbSelected();
613       return (aSelNum == 0) ? AIS_SOP_NothingSelected
614                             : (aSelNum == 1) ? AIS_SOP_OneSelected
615                                              : AIS_SOP_SeveralSelected;
616     }
617   }
618
619   clearDynamicHighlight();
620   if (myWasLastMain && !myLastinMain.IsNull())
621   {
622     AddOrRemoveSelected (myLastinMain, toUpdateViewer);
623   }
624
625   Standard_Integer aSelNum = NbSelected();
626
627   return (aSelNum == 0) ? AIS_SOP_NothingSelected
628                         : (aSelNum == 1) ? AIS_SOP_OneSelected
629                         : AIS_SOP_SeveralSelected;
630 }
631
632 //=======================================================================
633 //function : ShiftSelect
634 //purpose  : 
635 //=======================================================================
636 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer theXPMin,
637                                                       const Standard_Integer theYPMin,
638                                                       const Standard_Integer theXPMax,
639                                                       const Standard_Integer theYPMax,
640                                                       const Handle(V3d_View)& theView,
641                                                       const Standard_Boolean toUpdateViewer)
642 {
643   if (HasOpenedContext())
644   {
645     return myLocalContexts(myCurLocalIndex)->ShiftSelect (theXPMin, theYPMin, theXPMax, theYPMax,
646                                                           theView, toUpdateViewer);
647   }
648
649   UnhilightSelected (Standard_False);
650
651   Handle(StdSelect_ViewerSelector3d) aSelector;
652   if (theView->Viewer() == myMainVwr)
653   {
654     aSelector = myMainSel;
655     myWasLastMain = Standard_True;
656   }
657   else
658   {
659     return AIS_SOP_NothingSelected;
660   }
661
662   aSelector->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
663   for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
664   {
665     const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
666     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
667       continue;
668
669     AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
670     anOwner->SetSelected (aSelStatus == AIS_SS_Added);
671   }
672
673   HilightSelected (toUpdateViewer);
674
675   Standard_Integer aSelNum = NbSelected();
676
677   return (aSelNum == 0) ? AIS_SOP_NothingSelected
678                         : (aSelNum == 1) ? AIS_SOP_OneSelected
679                                          : AIS_SOP_SeveralSelected;
680
681 }
682
683 //=======================================================================
684 //function : ShiftSelect
685 //purpose  : 
686 //=======================================================================
687 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
688                                                       const Handle(V3d_View)& theView,
689                                                       const Standard_Boolean toUpdateViewer)
690 {
691   if (HasOpenedContext())
692   {
693     return myLocalContexts(myCurLocalIndex)->ShiftSelect (thePolyline, theView, toUpdateViewer);
694   }
695
696   UnhilightSelected (Standard_False);
697
698   Handle(StdSelect_ViewerSelector3d) aSelector;
699
700   if (theView->Viewer() == myMainVwr)
701   {
702     aSelector= myMainSel;
703     myWasLastMain = Standard_True;
704   }
705   else
706   {
707     return AIS_SOP_NothingSelected;
708   }
709
710   aSelector->Pick (thePolyline, theView);
711   for (Standard_Integer aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
712   {
713     const Handle(SelectMgr_EntityOwner) anOwner = aSelector->Picked (aPickIter);
714     if (anOwner.IsNull() || !anOwner->HasSelectable() || !myFilters->IsOk (anOwner))
715       continue;
716
717     AIS_SelectStatus aSelStatus = mySelection->Select (anOwner);
718     anOwner->SetSelected (aSelStatus == AIS_SS_Added);
719   }
720
721   HilightSelected (toUpdateViewer);
722
723   Standard_Integer aSelNum = NbSelected();
724
725   return (aSelNum == 0) ? AIS_SOP_NothingSelected
726                         : (aSelNum == 1) ? AIS_SOP_OneSelected
727                                          : AIS_SOP_SeveralSelected;
728 }
729
730 //=======================================================================
731 //function : SetCurrentObject
732 //purpose  : OBSOLETE, please use SetSelected() instead
733 //TODO     : Remove in process of local context deletion
734 //=======================================================================
735 void AIS_InteractiveContext::SetCurrentObject (const Handle(AIS_InteractiveObject)& theObject,
736                                                const Standard_Boolean theToUpdateViewer)
737 {
738   if (HasOpenedContext())
739     return;
740
741   SetSelected (theObject, theToUpdateViewer);
742 }
743
744 //=======================================================================
745 //function : AddOrRemoveCurrentObject
746 //purpose  : OBSOLETE, please use AddOrRemoveSelected() instead
747 //TODO     : Remove in process of local context deletion
748 //=======================================================================
749 void AIS_InteractiveContext::AddOrRemoveCurrentObject (const Handle(AIS_InteractiveObject)& theObj,
750                                                        const Standard_Boolean theIsToUpdateViewer)
751 {
752   if (HasOpenedContext())
753     return;
754
755   AddOrRemoveSelected (theObj, theIsToUpdateViewer);
756 }
757 //=======================================================================
758 //function : UpdateCurrent
759 //purpose  : OBSOLETE, please use UpdateSelected() instead
760 //TODO     : Remove in process of local context deletion
761 //=======================================================================
762 void AIS_InteractiveContext::UpdateCurrent()
763 {
764   UpdateSelected (Standard_True);
765 }
766
767 //=======================================================================
768 //function : IsCurrent
769 //purpose  : OBSOLETE, please use IsSelected() instead
770 //TODO     : Remove in process of local context deletion
771 //=======================================================================
772 Standard_Boolean AIS_InteractiveContext::IsCurrent (const Handle(AIS_InteractiveObject)& theObject) const
773 {
774   return IsSelected (theObject);
775 }
776
777 //=======================================================================
778 //function : InitCurrent
779 //purpose  : OBSOLETE, please use InitSelected() instead
780 //TODO     : Remove in process of local context deletion
781 //=======================================================================
782 void AIS_InteractiveContext::InitCurrent()
783 {
784   if (HasOpenedContext())
785     return;
786
787   InitSelected();
788 }
789
790 //=======================================================================
791 //function : MoreCurrent
792 //purpose  : OBSOLETE, please use MoreSelected() instead
793 //TODO     : Remove in process of local context deletion
794 //=======================================================================
795 Standard_Boolean AIS_InteractiveContext::MoreCurrent() const 
796 {
797   return !HasOpenedContext() && MoreSelected();
798 }
799
800 //=======================================================================
801 //function : NextCurrent
802 //purpose  : OBSOLETE, please use NextSelected() instead
803 //TODO     : Remove in process of local context deletion
804 //=======================================================================
805 void AIS_InteractiveContext::NextCurrent()
806 {
807   if (HasOpenedContext())
808     return;
809
810   NextSelected();
811 }
812
813 //=======================================================================
814 //function : Current
815 //purpose  : OBSOLETE, please use SelectedInteractive() instead
816 //TODO     : Remove in process of local context deletion
817 //=======================================================================
818 Handle(AIS_InteractiveObject) AIS_InteractiveContext::Current() const 
819 {
820   return HasOpenedContext() ? NULL : SelectedInteractive();
821 }
822
823 //=======================================================================
824 //function : NbCurrents
825 //purpose  : OBSOLETE, please use NbSelected() instead
826 //TODO     : Remove in process of local context deletion
827 //=======================================================================
828 Standard_Integer AIS_InteractiveContext::NbCurrents()
829 {
830   return HasOpenedContext() ? -1 : NbSelected();
831 }
832
833 //=======================================================================
834 //function : HilightCurrents
835 //purpose  : OBSOLETE, please use HilightSelected() instead
836 //TODO     : Remove in process of local context deletion
837 //=======================================================================
838 void AIS_InteractiveContext::HilightCurrents (const Standard_Boolean theToUpdateViewer)
839 {
840   if (HasOpenedContext())
841     return;
842
843   HilightSelected (theToUpdateViewer);
844 }
845
846 //=======================================================================
847 //function : UnhilightCurrents
848 //purpose  : OBSOLETE, please use UnhilightSelected() instead
849 //TODO     : Remove in process of local context deletion
850 //=======================================================================
851 void AIS_InteractiveContext::UnhilightCurrents (const Standard_Boolean theToUpdateViewer)
852 {
853   if (HasOpenedContext())
854     return;
855
856   UnhilightSelected (theToUpdateViewer);
857 }
858
859 //=======================================================================
860 //function : ClearCurrents
861 //purpose  : OBSOLETE, please use ClearCurrents() instead
862 //TODO     : Remove in process of local context deletion
863 //=======================================================================
864 void AIS_InteractiveContext::ClearCurrents(const Standard_Boolean theToUpdateViewer)
865 {
866   if (HasOpenedContext())
867     return;
868
869   ClearSelected (theToUpdateViewer);
870 }
871
872
873 //=======================================================================
874 //function : HilightSelected
875 //purpose  :
876 //=======================================================================
877 void AIS_InteractiveContext::HilightSelected (const Standard_Boolean theToUpdateViewer)
878 {
879   if (HasOpenedContext())
880   {
881     return myLocalContexts (myCurLocalIndex)->HilightPicked (theToUpdateViewer);
882   }
883
884   // In case of selection without using local context
885   clearDynamicHighlight();
886   AIS_MapOfObjSelectedOwners anObjOwnerMap;
887   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
888   {
889     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
890     const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
891     const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObj, anOwner);
892     Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind(anObj);
893     if (anOwner == anObj->GlobalSelOwner())
894     {
895       aState->SetHilightStatus (Standard_True);
896       aState->SetHilightStyle (anObjSelStyle);
897     }
898     anOwner->SetSelected (Standard_True);
899     if (!anOwner->IsAutoHilight())
900     {
901       NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
902       if (anObjOwnerMap.Find (anObj, aSeq))
903       {
904         aSeq->Append (anOwner);
905       }
906       else
907       {
908         aSeq = new SelectMgr_SequenceOfOwner();
909         aSeq->Append (anOwner);
910         anObjOwnerMap.Bind (anObj, aSeq);
911       }
912     }
913     else
914     {
915       const Standard_Integer aHiMode = getHilightMode (anObj, anObjSelStyle, aState->DisplayMode());
916       anOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
917     }
918   }
919
920   if (!anObjOwnerMap.IsEmpty())
921   {
922     for (AIS_MapOfObjSelectedOwners::Iterator anIter (anObjOwnerMap); anIter.More(); anIter.Next())
923     {
924       anIter.Key()->HilightSelected (myMainPM, *anIter.Value());
925     }
926     anObjOwnerMap.Clear();
927   }
928
929   if (theToUpdateViewer)
930     UpdateCurrentViewer();
931 }
932
933 //=======================================================================
934 //function : UnhilightSelected
935 //purpose  :
936 //=======================================================================
937 void AIS_InteractiveContext::UnhilightSelected (const Standard_Boolean theToUpdateViewer)
938 {
939   if (HasOpenedContext())
940   {
941     return myLocalContexts (myCurLocalIndex)->UnhilightPicked (theToUpdateViewer);
942   }
943
944   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
945   {
946     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
947     const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
948     if (anOwner == anObj->GlobalSelOwner())
949     {
950       myObjects.ChangeFind (anObj)->SetHilightStatus (Standard_False);
951     }
952
953     anOwner->SetSelected (Standard_False);
954     anOwner->Unhilight (myMainPM);
955   }
956
957   if (theToUpdateViewer)
958     UpdateCurrentViewer();
959 }
960
961
962 //=======================================================================
963 //function : ClearSelected
964 //purpose  :
965 //=======================================================================
966 void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateViewer)
967 {
968   if (HasOpenedContext())
969     return myLocalContexts (myCurLocalIndex)->ClearSelected (theToUpdateViewer);
970
971   if (NbSelected() == 0)
972     return;
973
974   unhighlightSelected();
975
976   mySelection->Clear();
977   clearDynamicHighlight();
978
979   if (theToUpdateViewer)
980     UpdateCurrentViewer();
981 }
982
983 //=======================================================================
984 //function : UpdateSelected
985 //purpose  :
986 //=======================================================================
987 void AIS_InteractiveContext::UpdateSelected (const Standard_Boolean theToUpdateViewer)
988 {
989   if (HasOpenedContext())
990   {
991     return myLocalContexts(myCurLocalIndex)->UpdateSelected (theToUpdateViewer);
992   }
993
994   HilightSelected (theToUpdateViewer);
995 }
996
997 //=======================================================================
998 //function : SetSelected
999 //purpose  : Sets the whole object as selected and highlights it with selection color
1000 //=======================================================================
1001 void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& theObject,
1002                                           const Standard_Boolean theToUpdateViewer)
1003 {
1004   if (HasOpenedContext())
1005   {
1006     return myLocalContexts (myCurLocalIndex)->SetSelected (theObject, theToUpdateViewer);
1007   }
1008
1009   if (theObject.IsNull())
1010   {
1011     return;
1012   }
1013
1014   if (!myObjects.IsBound (theObject))
1015   {
1016     Display (theObject, Standard_False);
1017   }
1018   if (!theObject->HasSelection (theObject->GlobalSelectionMode()))
1019   {
1020     return;
1021   }
1022   Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
1023   if (anOwner.IsNull())
1024   {
1025     return;
1026   }
1027
1028   const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (theObject, anOwner);
1029   if (NbSelected() == 1 && myObjects (theObject)->IsHilighted())
1030   {
1031     Handle(Prs3d_Drawer) aCustomStyle;
1032     if (HighlightStyle (theObject, aCustomStyle))
1033     {
1034       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
1035       {
1036         HilightWithColor (theObject, anObjSelStyle, theToUpdateViewer);
1037       }
1038     }
1039     return;
1040   }
1041
1042   for (mySelection->Init(); mySelection->More(); mySelection->Next())
1043   {
1044     const Handle(SelectMgr_EntityOwner) aSelOwner = mySelection->Value();
1045     if (!myFilters->IsOk (aSelOwner))
1046     {
1047       continue;
1048     }
1049
1050     Handle(AIS_InteractiveObject) aSelectable = Handle(AIS_InteractiveObject)::DownCast (aSelOwner->Selectable());
1051     Unhilight (aSelectable, Standard_False);
1052     aSelOwner->SetSelected (Standard_False);
1053     if (aSelOwner == aSelectable->GlobalSelOwner())
1054     {
1055       myObjects.ChangeFind (aSelectable)->SetHilightStatus (Standard_False);
1056     }
1057   }
1058
1059   // added to avoid untimely viewer update...
1060   mySelection->ClearAndSelect (anOwner);
1061
1062   Handle(Prs3d_Drawer) aCustomStyle;
1063   if (HighlightStyle (theObject, aCustomStyle))
1064   {
1065     if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
1066     {
1067       HilightWithColor (theObject, anObjSelStyle, Standard_False);
1068     }
1069   }
1070   else
1071   {
1072     HilightWithColor (theObject, anObjSelStyle, Standard_False);
1073   }
1074   anOwner->SetSelected (Standard_True);
1075
1076   if (theToUpdateViewer)
1077     UpdateCurrentViewer();
1078 }
1079
1080 //=======================================================================
1081 //function : SetSelected
1082 //purpose  : Sets the whole object as selected and highlights it with selection color
1083 //=======================================================================
1084 void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1085                                           const Standard_Boolean theToUpdateViewer)
1086 {
1087   if (theOwner.IsNull() || !theOwner->HasSelectable() || !myFilters->IsOk (theOwner))
1088     return;
1089
1090   const Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
1091   const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObject, theOwner);
1092   if (NbSelected() == 1 && theOwner->IsSelected() && !theOwner->IsForcedHilight())
1093   {
1094     Handle(Prs3d_Drawer) aCustomStyle;
1095     if (HighlightStyle (theOwner, aCustomStyle))
1096     {
1097       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
1098       {
1099         const Standard_Integer aHiMode = anObject->HasHilightMode() ? anObject->HilightMode() : 0;
1100         theOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
1101       }
1102     }
1103     return;
1104   }
1105
1106   if (!myObjects.IsBound (anObject))
1107     Display (anObject, Standard_False);
1108
1109   unhighlightSelected();
1110
1111   mySelection->ClearAndSelect (theOwner);
1112   Handle(Prs3d_Drawer) aCustomStyle;
1113   if (!HighlightStyle (theOwner, aCustomStyle) ||
1114     (!aCustomStyle.IsNull() && aCustomStyle != anObjSelStyle))
1115   {
1116     theOwner->SetSelected (Standard_True);
1117     highlightSelected (theOwner);
1118   }
1119
1120   theOwner->SetSelected (Standard_True);
1121   if (theOwner == anObject->GlobalSelOwner())
1122   {
1123     Handle(AIS_GlobalStatus)& aState = myObjects.ChangeFind (anObject);
1124     aState->SetHilightStatus (Standard_True);
1125     aState->SetHilightStyle (anObjSelStyle);
1126   }
1127
1128   if (theToUpdateViewer)
1129     UpdateCurrentViewer();
1130 }
1131
1132 //=======================================================================
1133 //function : AddOrRemoveSelected
1134 //purpose  : Adds or removes current object from AIS selection and highlights/unhighlights it.
1135 //           Since this method makes sence only for neutral point selection of a whole object,
1136 //           if 0 selection of the object is empty this method simply does nothing.
1137 //=======================================================================
1138 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveObject)& theObject,
1139                                                   const Standard_Boolean theToUpdateViewer)
1140 {
1141   if (theObject.IsNull())
1142     return;
1143
1144   if (HasOpenedContext())
1145     return myLocalContexts (myCurLocalIndex)->AddOrRemoveSelected (theObject, theToUpdateViewer);
1146
1147   const Standard_Integer aGlobalSelMode = theObject->GlobalSelectionMode();
1148   if (!myObjects.IsBound (theObject) || !theObject->HasSelection (aGlobalSelMode))
1149     return;
1150
1151   setContextToObject (theObject);
1152   const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
1153
1154   if (anOwner.IsNull() || !anOwner->HasSelectable())
1155     return;
1156
1157   AddOrRemoveSelected (anOwner, theToUpdateViewer);
1158 }
1159 //=======================================================================
1160 //function : AddOrRemoveSelected
1161 //purpose  : 
1162 //=======================================================================
1163
1164 void AIS_InteractiveContext::AddOrRemoveSelected (const TopoDS_Shape& aShap,
1165                                             const Standard_Boolean updateviewer)
1166
1167   if(!HasOpenedContext()) {
1168 #ifdef OCCT_DEBUG
1169     cout<<" Attempt to remove a selected shape with no opened local context"<<endl;
1170 #endif
1171     return;
1172   }
1173   
1174   myLocalContexts(myCurLocalIndex)->AddOrRemoveSelected(aShap,updateviewer);
1175   if(updateviewer) UpdateCurrentViewer();
1176   
1177 }
1178
1179 //=======================================================================
1180 //function : AddOrRemoveSelected
1181 //purpose  : Allows to highlight or unhighlight the owner given depending on
1182 //           its selection status
1183 //=======================================================================
1184 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1185                                                   const Standard_Boolean theToUpdateViewer)
1186 {
1187   if (HasOpenedContext())
1188     return myLocalContexts(myCurLocalIndex)->AddOrRemoveSelected (theOwner, theToUpdateViewer);
1189
1190   if (theOwner.IsNull() || !theOwner->HasSelectable())
1191     return;
1192
1193   if (!myFilters->IsOk(theOwner) && !theOwner->IsSelected())
1194     return;
1195
1196   AIS_SelectStatus aSelStat = mySelection->Select (theOwner);
1197   theOwner->SetSelected (aSelStat == AIS_SS_Added);
1198   const Handle(AIS_InteractiveObject) anObj =
1199     Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
1200   const Standard_Boolean isGlobal = anObj->GlobalSelOwner() == theOwner;
1201   Handle(AIS_GlobalStatus)& aStatus = myObjects.ChangeFind (anObj);
1202   if (theOwner->IsSelected())
1203   {
1204     highlightSelected (theOwner);
1205     if (isGlobal)
1206     {
1207       aStatus->SetHilightStatus (Standard_True);
1208       aStatus->SetHilightStyle (getSelStyle (anObj, theOwner));
1209     }
1210   }
1211   else
1212   {
1213     if (theOwner->IsAutoHilight())
1214     {
1215       theOwner->Unhilight (myMainPM);
1216     }
1217     else
1218     {
1219       anObj->ClearSelected();
1220     }
1221     aStatus->SetHilightStatus (Standard_False);
1222     aStatus->SetHilightStyle (Handle(Prs3d_Drawer)());
1223   }
1224
1225   if (theToUpdateViewer)
1226     UpdateCurrentViewer();
1227 }
1228
1229
1230 //=======================================================================
1231 //function : IsSelected
1232 //purpose  :
1233 //=======================================================================
1234 Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(AIS_InteractiveObject)& theObj) const
1235 {
1236   if(HasOpenedContext())
1237     return myLocalContexts(myCurLocalIndex)->IsSelected (theObj);
1238
1239   if (theObj.IsNull() || !myObjects.IsBound (theObj))
1240     return Standard_False;
1241
1242   const Standard_Integer aGlobalSelMode = theObj->GlobalSelectionMode();
1243   const TColStd_ListOfInteger& anActivatedModes = myObjects (theObj)->SelectionModes();
1244   Standard_Boolean isGlobalModeActivated = Standard_False;
1245   for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next())
1246   {
1247     if (aModeIter.Value() == aGlobalSelMode)
1248     {
1249       isGlobalModeActivated = Standard_True;
1250       break;
1251     }
1252   }
1253   if (!theObj->HasSelection (aGlobalSelMode) || !isGlobalModeActivated || theObj->GlobalSelOwner().IsNull())
1254     return Standard_False;
1255
1256   return theObj->GlobalSelOwner()->IsSelected();
1257 }
1258
1259 //=======================================================================
1260 //function : IsSelected
1261 //purpose  : Returns true is the owner given is selected
1262 //=======================================================================
1263 Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const
1264 {
1265   if (HasOpenedContext())
1266     return myLocalContexts(myCurLocalIndex)->IsSelected (theOwner);
1267
1268   if (theOwner.IsNull())
1269     return Standard_False;
1270
1271   return theOwner->IsSelected();
1272 }
1273
1274 //=======================================================================
1275 //function : InitSelected
1276 //purpose  :
1277 //=======================================================================
1278 void AIS_InteractiveContext::InitSelected()
1279 {
1280   if (HasOpenedContext())
1281   {
1282     myLocalContexts (myCurLocalIndex)->InitSelected();
1283     return;
1284   }
1285
1286   mySelection->Init();
1287 }
1288
1289 //=======================================================================
1290 //function : MoreSelected
1291 //purpose  :
1292 //=======================================================================
1293 Standard_Boolean AIS_InteractiveContext::MoreSelected() const
1294 {
1295   if (HasOpenedContext())
1296     return myLocalContexts (myCurLocalIndex)->MoreSelected();
1297
1298   return mySelection->More();
1299 }
1300
1301 //=======================================================================
1302 //function : NextSelected
1303 //purpose  :
1304 //=======================================================================
1305 void AIS_InteractiveContext::NextSelected()
1306 {
1307   if(HasOpenedContext())
1308   {
1309     return myLocalContexts (myCurLocalIndex)->NextSelected();
1310   }
1311
1312   mySelection->Next();
1313 }
1314
1315 //=======================================================================
1316 //function : HasSelectedShape
1317 //purpose  :
1318 //=======================================================================
1319 Standard_Boolean AIS_InteractiveContext::HasSelectedShape() const
1320 {
1321   if(HasOpenedContext())
1322   {
1323     return myLocalContexts(myCurLocalIndex)->HasSelectedShape();
1324   }
1325   if (!mySelection->More())
1326     return Standard_False;
1327
1328   const Handle(StdSelect_BRepOwner) anOwner =
1329     Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
1330
1331   return !anOwner.IsNull() && anOwner->HasShape();
1332 }
1333
1334 //=======================================================================
1335 //function : SelectedShape
1336 //purpose  :
1337 //=======================================================================
1338 TopoDS_Shape AIS_InteractiveContext::SelectedShape() const
1339 {
1340   if (HasOpenedContext())
1341   {
1342     return myLocalContexts (myCurLocalIndex)->SelectedShape();
1343   }
1344
1345   if (!mySelection->More())
1346     return TopoDS_Shape();
1347
1348   const Handle(StdSelect_BRepOwner) anOwner =
1349     Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
1350   if (anOwner.IsNull() || !anOwner->HasSelectable())
1351     return TopoDS_Shape();
1352
1353   return anOwner->Shape().Located (anOwner->Location() * anOwner->Shape().Location());
1354 }
1355
1356 //=======================================================================
1357 //function : SelectedInteractive
1358 //purpose  :
1359 //=======================================================================
1360 Handle(AIS_InteractiveObject) AIS_InteractiveContext::SelectedInteractive() const 
1361 {
1362   if (HasOpenedContext())
1363   {
1364     return myLocalContexts(myCurLocalIndex)->SelectedInteractive();
1365   }
1366
1367   return !mySelection->More()
1368        ? Handle(AIS_InteractiveObject)()
1369        : Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
1370 }
1371 //=======================================================================
1372 //function : SelectedOwner
1373 //purpose  :
1374 //=======================================================================
1375 Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::SelectedOwner() const
1376 {
1377   if(HasOpenedContext())
1378   {
1379     return myLocalContexts(myCurLocalIndex)->SelectedOwner();
1380   }
1381
1382   return !mySelection->More()
1383        ? Handle(SelectMgr_EntityOwner)()
1384        : mySelection->Value();
1385 }
1386
1387 //=======================================================================
1388 //function : EntityOwners
1389 //purpose  : 
1390 //=======================================================================
1391 void AIS_InteractiveContext::EntityOwners(Handle(SelectMgr_IndexedMapOfOwner)& theOwners,
1392                                           const Handle(AIS_InteractiveObject)& theIObj,
1393                                           const Standard_Integer theMode) const 
1394 {
1395   if ( theIObj.IsNull() )
1396       return;
1397
1398   TColStd_ListOfInteger aModes;
1399   if ( theMode == -1 )
1400     ActivatedModes( theIObj, aModes );
1401   else
1402     aModes.Append( theMode );
1403
1404   if (theOwners.IsNull())
1405     theOwners = new SelectMgr_IndexedMapOfOwner();
1406
1407   TColStd_ListIteratorOfListOfInteger anItr( aModes );
1408   for (; anItr.More(); anItr.Next() )
1409   {
1410     int aMode = anItr.Value();
1411     if ( !theIObj->HasSelection( aMode ) )
1412       continue;
1413
1414     Handle(SelectMgr_Selection) aSel = theIObj->Selection(aMode);
1415
1416     for ( aSel->Init(); aSel->More(); aSel->Next() )
1417     {
1418       Handle(SelectBasics_SensitiveEntity) aEntity = aSel->Sensitive()->BaseSensitive();
1419       if ( aEntity.IsNull() )
1420         continue;
1421
1422       Handle(SelectMgr_EntityOwner) aOwner =
1423         Handle(SelectMgr_EntityOwner)::DownCast(aEntity->OwnerId());
1424       if ( !aOwner.IsNull() )
1425         theOwners->Add( aOwner );
1426     }
1427   }
1428 }
1429
1430 //=======================================================================
1431 //function : NbSelected
1432 //purpose  :
1433 //=======================================================================
1434 Standard_Integer AIS_InteractiveContext::NbSelected()
1435 {
1436   if (HasOpenedContext())
1437   {
1438     return myLocalContexts (myCurLocalIndex)->Selection()->Extent();
1439   }
1440   return mySelection->Extent();
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 : DetectedCurrentOwner
1666 //purpose  :
1667 //=======================================================================
1668 Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::DetectedCurrentOwner() const
1669 {
1670   if (HasOpenedContext())
1671   {
1672     return myLocalContexts (myCurLocalIndex)->DetectedCurrentOwner();
1673   }
1674
1675   return MoreDetected()
1676        ? myMainSel->Picked (myDetectedSeq (myCurDetected))
1677        : Handle(SelectMgr_EntityOwner)();
1678 }
1679
1680 //=======================================================================
1681 //function : DetectedCurrentShape
1682 //purpose  :
1683 //=======================================================================
1684 const TopoDS_Shape& AIS_InteractiveContext::DetectedCurrentShape() const
1685 {
1686   if (HasOpenedContext())
1687   {
1688     return myLocalContexts(myCurLocalIndex)->DetectedCurrentShape();
1689   }
1690
1691   Standard_DISABLE_DEPRECATION_WARNINGS
1692   Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1693   Standard_ENABLE_DEPRECATION_WARNINGS
1694
1695   if (aCurrentShape.IsNull())
1696   {
1697     return AIS_InteractiveContext_myDummyShape;
1698   }
1699
1700   return aCurrentShape->Shape();
1701 }
1702
1703 //=======================================================================
1704 //function : DetectedCurrentObject
1705 //purpose  :
1706 //=======================================================================
1707 Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedCurrentObject() const
1708 {
1709   if (HasOpenedContext())
1710   {
1711     return myLocalContexts(myCurLocalIndex)->DetectedCurrentObject();
1712   }
1713
1714   return MoreDetected()
1715     ? Handle(AIS_InteractiveObject)::DownCast (myMainSel->Picked (myDetectedSeq (myCurDetected))->Selectable())
1716     : NULL;
1717 }
1718
1719 //=======================================================================
1720 //function : FirstSelectedObject
1721 //purpose  :
1722 //=======================================================================
1723 Handle(AIS_InteractiveObject) AIS_InteractiveContext::FirstSelectedObject()
1724 {
1725   Handle(AIS_InteractiveObject) anObject;
1726
1727   if (HasOpenedContext())
1728     return anObject;
1729
1730   InitSelected();
1731   if (MoreSelected())
1732   {
1733     return SelectedInteractive();
1734   }
1735   return anObject;
1736 }
1737
1738 //=======================================================================
1739 //function : RedrawImmediate
1740 //purpose  : Redisplays immediate strucures of the viewer given according to their visibility
1741 //=======================================================================
1742 void AIS_InteractiveContext::RedrawImmediate (const Handle(V3d_Viewer)& theViewer)
1743 {
1744   myMainPM->RedrawImmediate (theViewer);
1745 }