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