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