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