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