0029882: Visualization - AcceptDisplayMode() should be redefined in class AIS_Texture...
[occt.git] / src / AIS / AIS_LocalContext_1.cxx
1 // Created on: 1996-10-30
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1996-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 // Modified by rob Thu Apr 02 1998 
18 //              - use of optimisation in SelectMgr_ViewerSelector
19 //              -> Best management in detected entities...
20
21 #include <AIS_InteractiveContext.hxx>
22 #include <AIS_InteractiveObject.hxx>
23 #include <AIS_LocalContext.hxx>
24 #include <AIS_LocalStatus.hxx>
25 #include <AIS_Selection.hxx>
26 #include <AIS_Shape.hxx>
27 #include <Aspect_Grid.hxx>
28 #include <Geom_Transformation.hxx>
29 #include <Graphic3d_ArrayOfTriangles.hxx>
30 #include <Graphic3d_Group.hxx>
31 #include <NCollection_Map.hxx>
32 #include <OSD_Environment.hxx>
33 #include <Prs3d_Drawer.hxx>
34 #include <Prs3d_Presentation.hxx>
35 #include <Prs3d_ShadingAspect.hxx>
36 #include <Select3D_SensitiveTriangulation.hxx>
37 #include <SelectBasics_SensitiveEntity.hxx>
38 #include <SelectMgr_EntityOwner.hxx>
39 #include <SelectMgr_Filter.hxx>
40 #include <SelectMgr_OrFilter.hxx>
41 #include <SelectMgr_SelectableObject.hxx>
42 #include <SelectMgr_Selection.hxx>
43 #include <SelectMgr_SelectionManager.hxx>
44 #include <SelectMgr_SequenceOfOwner.hxx>
45 #include <Standard_Transient.hxx>
46 #include <StdSelect_BRepOwner.hxx>
47 #include <StdSelect_ViewerSelector3d.hxx>
48 #include <TCollection_AsciiString.hxx>
49 #include <TColStd_ListIteratorOfListOfInteger.hxx>
50 #include <TColStd_ListOfInteger.hxx>
51 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
52 #include <TColStd_MapOfTransient.hxx>
53 #include <V3d_View.hxx>
54
55 namespace
56 {
57   TopoDS_Shape AIS_LocalContext_myDummyShape;
58 }
59
60 //==================================================
61 // Function: MoveTo
62 // Purpose :
63 //==================================================
64 AIS_StatusOfDetection AIS_LocalContext::MoveTo (const Standard_Integer  theXpix,
65                                                 const Standard_Integer  theYpix,
66                                                 const Handle(V3d_View)& theView,
67                                                 const Standard_Boolean  theToRedrawImmediate)
68 {
69   // check that ViewerSelector gives
70   if (theView->Viewer() != myCTX->CurrentViewer())
71   {
72     return AIS_SOD_Error;
73   }
74
75   myAISCurDetected = 0;
76
77   myCurDetected = 0;
78   myDetectedSeq.Clear();
79   myFilters->SetDisabledObjects (theView->View()->HiddenObjects());
80   myMainVS->Pick (theXpix, theYpix, theView);
81
82   const Standard_Integer aDetectedNb = myMainVS->NbPicked();
83   for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
84   {
85     Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (aDetIter);
86     if (!anOwner.IsNull()
87       && myFilters->IsOk (anOwner))
88     {
89       myDetectedSeq.Append (aDetIter); // normally they are already arranged in correct order...
90     }
91   }
92
93   // result of courses..
94   if (aDetectedNb == 0 || myDetectedSeq.IsEmpty())
95   {
96     if (mylastindex != 0 && mylastindex <= myMapOfOwner->Extent())
97     {
98       myMainPM->ClearImmediateDraw();
99       Unhilight (myMapOfOwner->FindKey (mylastindex), theView);
100       if (theToRedrawImmediate)
101       {
102         theView->RedrawImmediate();
103       }
104     }
105
106     mylastindex = 0;
107     return aDetectedNb == 0
108          ? AIS_SOD_Nothing
109          : AIS_SOD_AllBad;
110   }
111
112   // all owners detected by the selector are passed to the
113   // filters and correct ones are preserved...
114   myCurDetected = 1;
115   Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
116   manageDetected (anOwner, theView, theToRedrawImmediate);
117   if (myDetectedSeq.Length() == 1)
118   {
119     return aDetectedNb == 1
120          ? AIS_SOD_OnlyOneDetected
121          : AIS_SOD_OnlyOneGood;
122   }
123   else
124   {
125     return AIS_SOD_SeveralGood;
126   }
127 }
128
129 //=======================================================================
130 //function : AddSelect
131 //purpose  : 
132 //=======================================================================
133 AIS_StatusOfPick AIS_LocalContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
134 {
135   mySelection->AddSelect (theObject);
136
137   Standard_Integer aSelNum = mySelection->Extent();
138   return (aSelNum == 1) ? AIS_SOP_OneSelected
139                         : (aSelNum > 1) ? AIS_SOP_SeveralSelected
140                                         : AIS_SOP_Error;
141 }
142
143 //=======================================================================
144 //function : Select
145 //purpose  : 
146 //=======================================================================
147 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Boolean toUpdateViewer)
148 {
149   if (myAutoHilight)
150   {
151     UnhilightPicked (Standard_False);
152   }
153
154   Standard_Integer aDetIndex = DetectedIndex();
155   if (aDetIndex <= 0)
156   {
157     ClearSelected (toUpdateViewer);
158     return mySelection->IsEmpty() ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
159   }
160
161   const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
162
163   ClearSelected (Standard_False);
164
165   if (!anOwner->IsSelected()) // anOwner is not selected
166   {
167     anOwner->SetSelected (Standard_True);
168     mySelection->Select (anOwner);
169   }
170
171   if (myAutoHilight)
172   {
173     const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
174     for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
175     {
176       Unhilight (anOwner, anActiveViewIter.Value());
177     }
178
179     // advanced selection highlighting mechanism
180     if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
181     {
182       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
183       UpdateSelected (anIO, Standard_False);
184     }
185
186     if (toUpdateViewer)
187     {
188       myCTX->CurrentViewer()->Update();
189     }
190   }
191
192   return (mySelection->Extent() == 1) ? AIS_SOP_OneSelected : AIS_SOP_SeveralSelected;
193 }
194
195 //=======================================================================
196 //function : Select
197 //purpose  : 
198 //=======================================================================
199 AIS_StatusOfPick AIS_LocalContext::Select (const Standard_Integer  theXPMin,
200                                            const Standard_Integer  theYPMin,
201                                            const Standard_Integer  theXPMax,
202                                            const Standard_Integer  theYPMax,
203                                            const Handle(V3d_View)& theView,
204                                            const Standard_Boolean  toUpdateViewer)
205 {
206   if (theView->Viewer() == myCTX->CurrentViewer())
207   {
208     myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
209     if (myAutoHilight)
210     {
211       UnhilightPicked (Standard_False);
212     }
213
214     Standard_Integer aSelNum = mySelection->Extent();
215     if (myMainVS->NbPicked() == 0)
216     {
217       ClearSelected (toUpdateViewer);
218       mylastindex = 0;
219       return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
220     }
221
222     ClearSelected (Standard_False);
223
224     for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
225     {
226       const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
227       if (myFilters->IsOk (anOwner))
228       {
229         // it can be helpful to classify this owner immediately...
230         if (!anOwner->IsSelected())
231         {
232           anOwner->SetSelected (Standard_True);
233           mySelection->Select (anOwner);
234         }
235       }
236     }
237
238     if (myAutoHilight)
239     {
240       HilightPicked (toUpdateViewer);
241     }
242   }
243
244   Standard_Integer aSelNum = mySelection->Extent();
245
246   return (aSelNum == 1) ? AIS_SOP_OneSelected
247                         : (aSelNum > 1) ? AIS_SOP_SeveralSelected
248                                         : AIS_SOP_Error;
249 }
250
251 //==================================================
252 // Function: Select
253 // Purpose : Selection by polyline
254 //==================================================
255 AIS_StatusOfPick AIS_LocalContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
256                                            const Handle(V3d_View)& theView,
257                                            const Standard_Boolean toUpdateViewer)
258 {
259   if (theView->Viewer() == myCTX->CurrentViewer())
260   {
261     myMainVS->Pick (thePolyline, theView);
262
263     Standard_Integer aLastSelNum = mySelection->Extent();
264     if (myMainVS->NbPicked() == 0)
265     {
266       // Nothing is selected clear selection.
267       ClearSelected (toUpdateViewer);
268       mylastindex = 0;
269
270       // Return state to know if something was unselected
271       return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
272     }
273
274     if (myAutoHilight)
275     {
276       UnhilightPicked (Standard_False);
277     }
278
279     // Clear previous selection without update to process this selection
280     ClearSelected (Standard_False);
281
282     for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
283     {
284       const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
285       if (myFilters->IsOk (anOwner))
286       {
287         // it can be helpful to classify this owner immediately...
288         if (!anOwner->IsSelected())
289         {
290           mySelection->AddSelect (anOwner);
291           anOwner->SetSelected (Standard_True);
292         }
293       }
294     }
295
296     if (myAutoHilight)
297     {
298       HilightPicked (toUpdateViewer);
299     }
300   }
301
302   Standard_Integer aSelNum = mySelection->Extent();
303   return (aSelNum == 1) ? AIS_SOP_OneSelected
304                         : (aSelNum > 1) ? AIS_SOP_SeveralSelected
305                                         : AIS_SOP_Error;
306 }
307
308 //=======================================================================
309 //function : ShiftSelect
310 //purpose  : 
311 //=======================================================================
312 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Boolean toUpdateViewer)
313 {
314   Standard_Integer aDetIndex = DetectedIndex();
315
316   if(aDetIndex > 0)
317   {
318     Standard_Integer aSelNum = mySelection->Extent();
319     const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (aDetIndex);
320     Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
321     mySelection->Select (anOwner);
322     anOwner->SetSelected (toSelect);
323
324     if(myAutoHilight)
325     {
326       myMainPM->ClearImmediateDraw();
327       const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
328       for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
329       {
330         Unhilight (anOwner, anActiveViewIter.Value());
331       }
332
333       // advanced selection highlighting mechanism
334       if (!anOwner->IsAutoHilight() && anOwner->HasSelectable())
335       {
336         Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
337         UpdateSelected (anIO, Standard_False);
338       }
339
340       if (toUpdateViewer)
341       {
342         myCTX->CurrentViewer()->Update();
343       }
344     } 
345
346     Standard_Integer NS = mySelection->Extent();
347     if( NS == 1 ) return AIS_SOP_OneSelected;
348     else if( NS > 1 ) return AIS_SOP_SeveralSelected;
349     return aSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
350   }
351   return AIS_SOP_Error;
352 }
353
354 //=======================================================================
355 //function : ShiftSelect
356 //purpose  : 
357 //=======================================================================
358 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const Standard_Integer  theXPMin,
359                                                 const Standard_Integer  theYPMin,
360                                                 const Standard_Integer  theXPMax,
361                                                 const Standard_Integer  theYPMax,
362                                                 const Handle(V3d_View)& theView,
363                                                 const Standard_Boolean  toUpdateViewer)
364 {
365   myMainPM->ClearImmediateDraw();
366
367   if (theView->Viewer() == myCTX->CurrentViewer())
368   {
369     myMainVS->Pick (theXPMin, theYPMin, theXPMax, theYPMax, theView);
370
371     Standard_Integer aLastSelNum = mySelection->Extent();
372     if (myMainVS->NbPicked() == 0)
373     {
374       // Nothing is selected clear selection, but don't clear the selection
375       // as it is shift selection and previous selection matters.
376       // Return state to know if something was unselected
377       return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
378     }
379
380     if (myAutoHilight)
381     {
382       UnhilightPicked (Standard_False);
383     }
384
385     for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
386     {
387       const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
388       if(myFilters->IsOk (anOwner))
389       {
390         Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
391         mySelection->Select (anOwner);
392         anOwner->SetSelected (toSelect);
393       }
394     }
395
396     if (myAutoHilight)
397     {
398       HilightPicked (toUpdateViewer);
399     }
400   }
401
402   Standard_Integer aSelNum = mySelection->Extent();
403
404   return (aSelNum == 1) ? AIS_SOP_OneSelected
405                         : (aSelNum > 1) ? AIS_SOP_SeveralSelected
406                                         : AIS_SOP_Error;
407 }
408
409 //==================================================
410 // Function: Select
411 // Purpose : Selection by polyline
412 //==================================================
413 AIS_StatusOfPick AIS_LocalContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
414                                                 const Handle(V3d_View)&     theView,
415                                                 const Standard_Boolean      toUpdateViewer)
416 {
417   if (theView->Viewer() == myCTX->CurrentViewer())
418   {
419     myMainVS->Pick (thePolyline, theView);
420
421     Standard_Integer aLastSelNum = mySelection->Extent();
422     if (myMainVS->NbPicked() == 0)
423     {
424       // Nothing is selected clear selection, but don't clear the selection
425       // as it is shift selection and previous selection matters.
426       // Return state to know if something was unselected
427       return aLastSelNum == 0 ? AIS_SOP_NothingSelected : AIS_SOP_Removed;
428     }
429
430     if (myAutoHilight)
431     {
432       UnhilightPicked (Standard_False);
433     }
434
435     for (Standard_Integer aPickIter = 1; aPickIter <= myMainVS->NbPicked(); ++aPickIter)
436     {
437       const Handle(SelectMgr_EntityOwner)& anOwner = myMainVS->Picked (aPickIter);
438       if (myFilters->IsOk (anOwner))
439       {
440         Standard_Boolean toSelect = anOwner->IsSelected() ? Standard_False : Standard_True;
441         mySelection->Select (anOwner);
442         anOwner->SetSelected (toSelect);
443       }
444     }
445     if (myAutoHilight)
446     {
447       HilightPicked (toUpdateViewer);
448     }
449   }
450
451   Standard_Integer aSelNum = mySelection->Extent();
452
453   return (aSelNum == 1) ? AIS_SOP_OneSelected
454                         : (aSelNum > 1) ? AIS_SOP_SeveralSelected
455                                         : AIS_SOP_Error;
456 }
457
458 //==================================================
459 // Function: Hilight
460 // Purpose :
461 //==================================================
462 void AIS_LocalContext::Hilight (const Handle(SelectMgr_EntityOwner)& theOwner,
463                                 const Handle(V3d_View)&              theView)
464 {
465   if (theView.IsNull())
466   {
467     return;
468   }
469
470   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
471   const Handle(Prs3d_Drawer)& aHiStyle = myCTX->getHiStyle (anObj, theOwner);
472   const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aHiStyle, -1);
473   myMainPM->BeginImmediateDraw();
474   theOwner->HilightWithColor (myMainPM, aHiStyle, aHiMode);
475   myMainPM->EndImmediateDraw (theView->Viewer());
476 }
477
478 //==================================================
479 // Function: Unhilight
480 // Purpose :
481 //==================================================
482 void AIS_LocalContext::Unhilight (const Handle(SelectMgr_EntityOwner)& theOwner,
483                                   const Handle(V3d_View)&              theView)
484 {
485   if (theView.IsNull())
486   {
487     return;
488   }
489
490   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
491   if (IsSelected (theOwner))
492   {
493     if (theOwner->IsAutoHilight())
494     {
495       const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anObj, theOwner);
496       const Standard_Integer aHiMode = myCTX->getHilightMode (anObj, aSelStyle, -1);
497       theOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode);
498     }
499   }
500   else
501   {
502     theOwner->Unhilight (myMainPM);
503   }
504 }
505
506 //=======================================================================
507 //function : HilightPicked
508 //purpose  :
509 //=======================================================================
510 void AIS_LocalContext::HilightPicked (const Standard_Boolean theToUpdateviewer)
511 {
512   if (mySelection.IsNull())
513   {
514     return;
515   }
516   
517   typedef NCollection_Shared<SelectMgr_SequenceOfOwner> SelectMgr_HSequenceOfOwner;
518   typedef NCollection_DataMap <Handle(SelectMgr_SelectableObject), Handle(SelectMgr_HSequenceOfOwner) > SelectMgr_DataMapOfObjectOwners;
519   SelectMgr_DataMapOfObjectOwners aMap;
520
521   // to avoid problems when there is a loop searching for selected objects...
522   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
523   {
524     const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
525     Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
526     if (anOwner->IsAutoHilight())
527     {
528       Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast(aSelObj);
529       const Handle(Prs3d_Drawer)& aSelStyle = myCTX->getSelStyle (anIO, anOwner);
530       const Standard_Integer aHiMode = myCTX->getHilightMode (anIO, aSelStyle, -1);
531       anOwner->HilightWithColor (myMainPM, aSelStyle, aHiMode);
532       continue;
533     }
534
535     Handle(SelectMgr_HSequenceOfOwner) aSeq;
536     if (aMap.Find (aSelObj, aSeq))
537     {
538       aSeq->Append (anOwner);
539     }
540     else
541     {
542       aSeq = new SelectMgr_HSequenceOfOwner();
543       aSeq->Append (anOwner);
544       aMap.Bind (aSelObj, aSeq);
545     }
546   }
547
548   for (SelectMgr_DataMapOfObjectOwners::Iterator aMapIter (aMap); aMapIter.More(); aMapIter.Next())
549   {
550     aMapIter.Key()->HilightSelected (myMainPM, *aMapIter.Value());
551   }
552
553   if (theToUpdateviewer)
554   {
555     myCTX->CurrentViewer()->Update();
556   }
557 }
558
559 //==================================================
560 // Function: UnhilightPicked
561 // Purpose :
562 //==================================================
563 void AIS_LocalContext::UnhilightPicked (const Standard_Boolean theToUpdateViewer)
564 {
565   myMainPM->ClearImmediateDraw();
566   if (mySelection.IsNull())
567   {
568     return;
569   }
570
571   NCollection_Map<Handle(SelectMgr_SelectableObject)> anObjMap;
572   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
573   {
574     const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
575     Handle(SelectMgr_SelectableObject) aSelObj = anOwner->Selectable();
576     Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (aSelObj);
577     anObjMap.Add (aSelObj);
578     anOwner->Unhilight (myMainPM);
579   }
580
581   for (NCollection_Map<Handle(SelectMgr_SelectableObject)>::Iterator aMapIter (anObjMap);
582        aMapIter.More(); aMapIter.Next())
583   {
584     if (!aMapIter.Key()->IsAutoHilight())
585     {
586       aMapIter.Key()->ClearSelected();
587     }
588   }
589
590   if (theToUpdateViewer)
591   {
592     myCTX->CurrentViewer()->Update();
593   }
594 }
595
596 //=======================================================================
597 //function : IsSelected
598 //purpose  : 
599 //=======================================================================
600 Standard_Boolean AIS_LocalContext::IsSelected(const Handle(AIS_InteractiveObject)& anIObj) const 
601 {
602   return (!FindSelectedOwnerFromIO(anIObj).IsNull());
603 }
604
605 //=======================================================================
606 //function : IsSelected
607 //purpose  : 
608 //=======================================================================
609
610 Standard_Boolean AIS_LocalContext::IsSelected (const Handle(SelectMgr_EntityOwner)& theOwner) const 
611 {
612   return !theOwner.IsNull() && theOwner->IsSelected();
613 }
614
615 //==================================================
616 // Function: 
617 // Purpose :
618 //==================================================
619 void AIS_LocalContext::
620 InitSelected()
621 {
622   mySelection->Init();
623 }
624
625 //==================================================
626 // Function: 
627 // Purpose :
628 //==================================================
629 Standard_Boolean AIS_LocalContext::
630 MoreSelected() const 
631 {
632   return mySelection->More();
633 }
634
635 //==================================================
636 // Function: 
637 // Purpose :
638 //==================================================
639 void AIS_LocalContext::
640 NextSelected()
641 {
642   mySelection->Next();
643 }
644
645 //==================================================
646 // Function: HasShape
647 // Purpose :
648 //==================================================
649 Standard_Boolean AIS_LocalContext::HasShape() const
650 {
651   if (!mySelection->More())
652   {
653     return Standard_False;
654   }
655
656   Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
657   return !aBROwner.IsNull()
658        && aBROwner->HasShape()
659        && aBROwner->ComesFromDecomposition();
660 }
661
662 //================================================================
663 // Function : HasSelectedShape
664 // Purpose  : Checks if there is a selected shape regardless of its decomposition status
665 //================================================================
666 Standard_Boolean AIS_LocalContext::HasSelectedShape() const
667 {
668   if (!mySelection->More())
669   {
670     return Standard_False;
671   }
672
673   Handle(StdSelect_BRepOwner) aBrepOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
674   return !aBrepOwner.IsNull()
675       && aBrepOwner->HasShape();
676 }
677
678 //==================================================
679 // Function: SelectedShape
680 // Purpose :
681 //==================================================
682 TopoDS_Shape AIS_LocalContext::SelectedShape() const 
683 {
684   if (!mySelection->More())
685   {
686     return TopoDS_Shape();
687   }
688
689   Handle(StdSelect_BRepOwner) aBRO = Handle(StdSelect_BRepOwner)::DownCast(mySelection->Value());
690   if (aBRO.IsNull())
691   {
692     return TopoDS_Shape();
693   }
694
695   return aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
696 }
697
698 //==================================================
699 // Function: SelectedInteractive
700 // Purpose :
701 //==================================================
702 Handle(AIS_InteractiveObject) AIS_LocalContext::SelectedInteractive() const
703 {
704   return !mySelection->More()
705        ?  Handle(AIS_InteractiveObject)()
706        :  Handle(AIS_InteractiveObject)::DownCast (mySelection->Value()->Selectable());
707 }
708
709 //==================================================
710 // Function: SelectedOwner
711 // Purpose :
712 //==================================================
713 Handle(SelectMgr_EntityOwner) AIS_LocalContext::SelectedOwner() const
714 {
715   return !mySelection->More()
716        ?  Handle(SelectMgr_EntityOwner)()
717        :  mySelection->Value();
718 }
719
720 //==================================================
721 // Function: 
722 // Purpose :
723 //==================================================
724 Standard_Boolean AIS_LocalContext::HasApplicative() const
725 {
726   Handle(AIS_InteractiveObject) anIO = SelectedInteractive();
727   return !anIO.IsNull()
728        && anIO->HasOwner();
729 }
730
731 //==================================================
732 // Function: 
733 // Purpose :
734 //==================================================
735 const Handle(Standard_Transient)& AIS_LocalContext::
736 SelectedApplicative() const 
737 {
738   return SelectedInteractive()->GetOwner();
739 }
740
741
742
743 //=======================================================================
744 //function : UpdateSelection
745 //purpose  : should disappear...
746 //=======================================================================
747 void AIS_LocalContext::UpdateSelected(const Standard_Boolean updateviewer)
748 {
749   UnhilightPicked(Standard_False);
750   HilightPicked(updateviewer);
751 }
752
753 //================================================================
754 // Function : UpdateSelected
755 // Purpose  : Part of advanced selection mechanism.
756 //            Highlightes or clears selection presentation for the given IO
757 //================================================================
758 void AIS_LocalContext::UpdateSelected(const Handle(AIS_InteractiveObject)& anobj,
759                                       const Standard_Boolean updateviewer)
760 {
761   if (anobj.IsNull() || anobj->IsAutoHilight())
762     return;
763
764   SelectMgr_SequenceOfOwner aSeq;
765   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
766   {
767     if (aSelIter.Value()->IsSameSelectable (anobj))
768     {
769       aSeq.Append (aSelIter.Value());
770     }
771   }
772
773   if ( aSeq.Length() )
774     anobj->HilightSelected( myMainPM, aSeq );
775   else
776     anobj->ClearSelected();
777
778   if(updateviewer){
779      myCTX->CurrentViewer()->Update();
780   }
781 }
782
783 //==================================================
784 // Function: ClearSelected
785 // Purpose :
786 //==================================================
787 void AIS_LocalContext::ClearSelected (const Standard_Boolean updateviewer)
788 {
789   UnhilightPicked(updateviewer);
790   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
791   {
792     aSelIter.Value()->SetSelected (Standard_False);
793   }
794   mySelection->Clear();
795   mylastindex = 0;
796 }
797
798 //==================================================
799 // Function: ClearOutdatedSelection
800 // Purpose :
801 //==================================================
802 void AIS_LocalContext::ClearOutdatedSelection (const Handle(AIS_InteractiveObject)& theIO,
803                                                const Standard_Boolean toClearDeactivated)
804 {
805   // 1. Collect selectable entities
806   SelectMgr_IndexedMapOfOwner aValidOwners;
807   const TColStd_ListOfInteger& aModes = SelectionModes (theIO);
808   for (TColStd_ListIteratorOfListOfInteger aModeIter (aModes); aModeIter.More(); aModeIter.Next())
809   {
810     const int aMode = aModeIter.Value();
811     if (!theIO->HasSelection(aMode))
812     {
813       continue;
814     }
815
816     if (toClearDeactivated && !mySM->IsActivated(theIO, aMode, myMainVS))
817     {
818       continue;
819     }
820
821     const Handle(SelectMgr_Selection)& aSelection = theIO->Selection (aMode);
822     for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
823     {
824       if (Handle(SelectBasics_SensitiveEntity) anEntity = aSelEntIter.Value()->BaseSensitive())
825       {
826         if (Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId()))
827         {
828           aValidOwners.Add (anOwner);
829         }
830       }
831     }
832   }
833
834   // 2. Refresh context's detection and selection and keep only active owners.
835   // Keep last detected object for lastindex initialization.
836   Handle(SelectMgr_EntityOwner) aLastPicked;
837   if (IsValidIndex (mylastindex))
838   {
839     aLastPicked = myMapOfOwner->FindKey (mylastindex);
840   }
841
842   // Remove entity owners from detected sequences
843   for (Standard_Integer anIdx = 1; anIdx <= myDetectedSeq.Length(); ++anIdx)
844   {
845     Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (anIdx));
846     if (anOwner.IsNull() || !anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
847     {
848       continue;
849     }
850
851     myDetectedSeq.Remove (anIdx--);
852     if (myCurDetected > anIdx)
853     {
854       --myCurDetected;
855     }
856     if (myAISCurDetected > anIdx)
857     {
858       --myAISCurDetected;
859     }
860   }
861   myCurDetected    = Max (myCurDetected,    1);
862   myAISCurDetected = Max (myAISCurDetected, 1);
863
864   // 3. AIS_Selection : remove entity owners from AIS_Selection
865   const Handle(V3d_Viewer)& aViewer = myCTX->CurrentViewer();
866   NCollection_List<Handle(SelectMgr_EntityOwner)> aRemoveEntites;
867   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
868   {
869     Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
870     if (!anOwner->IsSameSelectable (theIO))
871     {
872       continue;
873     }
874
875     if (!aValidOwners.Contains (anOwner))
876     {
877       aRemoveEntites.Append (anOwner);
878       anOwner->SetSelected (Standard_False);
879       for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
880       {
881         Unhilight (anOwner, anActiveViewIter.Value());
882       }
883     }
884   }
885
886   for (NCollection_List<Handle(SelectMgr_EntityOwner)>::Iterator anIterRemove (aRemoveEntites);
887        anIterRemove.More(); anIterRemove.Next())
888   {
889     mySelection->Select (anIterRemove.Value());
890   }
891
892   // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
893   SelectMgr_IndexedMapOfOwner anOwnersToKeep;
894   for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner->Extent(); anIdx++)
895   {
896     Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner->FindKey (anIdx);
897     if (anOwner.IsNull())
898     {
899       continue;
900     }
901
902     if (!anOwner->IsSameSelectable (theIO) || aValidOwners.Contains (anOwner))
903     {
904       anOwnersToKeep.Add (anOwner);
905     }
906     else
907     {
908       for (V3d_ListOfViewIterator anActiveViewIter (aViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
909       {
910         Unhilight (anOwner, anActiveViewIter.Value());
911       }
912     }
913   }
914   myMapOfOwner->Clear();
915   myMapOfOwner->Assign (anOwnersToKeep);
916
917   if (myDetectedSeq.IsEmpty() && !aLastPicked.IsNull())
918   {
919     myMainPM->ClearImmediateDraw();
920     mylastindex = 0;
921   }
922   else if (!aLastPicked.IsNull())
923   {
924     // For a case when the last detected owner was unhilighted and removed as outdated we
925     // need to check if there were other detected owners with less priority. If yes then
926     // one from the remaining should be treated.
927     Standard_Integer anIndex = 1, aDetectedSeqLength = myDetectedSeq.Length();
928     for (; anIndex <= aDetectedSeqLength; anIndex++)
929     {
930       if (aLastPicked == myMainVS->Picked (myDetectedSeq.Value(anIndex)))
931       {
932         break; // detected owner was not removed
933       }
934     }
935     if (anIndex <= aDetectedSeqLength)
936     {
937       // Last detected owner was not removed, update mylastindex variable
938       mylastindex = myMapOfOwner->FindIndex (aLastPicked);
939     }
940     else
941     {
942       // Last detected owner was removed. First object from sequence become detected.
943       // Pass any active view because in current implementation the highlighting is
944       // synchronized in all view.
945       manageDetected (myMainVS->Picked (myDetectedSeq.First()),
946                       aViewer->ActiveViewIterator().Value(),
947                       Standard_False);
948     }
949   }
950 }
951
952 //=======================================================================
953 //function : SetSelected
954 //purpose  : 
955 //=======================================================================
956 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
957                                    const Standard_Boolean updateviewer)
958 {
959   if(!IsValidForSelection(anIObj)) return;
960   UnhilightPicked(Standard_False);
961   
962   //1st case, owner already <anIObj> as owner  
963   // and not separated is found...
964
965   Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
966   if(EO.IsNull()){
967     //check if global selection there is an owner that can be triturated...
968     if (anIObj->HasSelection (anIObj->GlobalSelectionMode()))
969     {
970       EO = anIObj->GlobalSelOwner();
971     }
972     if(EO.IsNull()) 
973       EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
974   }
975   
976   ClearSelected(Standard_False);
977
978   mySelection->Select(EO);
979   EO->SetSelected (Standard_True);
980
981   HilightPicked(updateviewer);
982 }
983
984 //=======================================================================
985 //function : AddOrRemoveSelected
986 //purpose  : 
987 //=======================================================================
988
989 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
990                                            const Standard_Boolean updateviewer)
991 {
992   if(!IsValidForSelection(anIObj)) return;
993   UnhilightPicked(Standard_False);
994   // first check if it is selected...
995   Handle(SelectMgr_EntityOwner) EO;
996
997   EO = FindSelectedOwnerFromIO(anIObj);
998
999   if (EO.IsNull())
1000   {
1001     if(anIObj->HasSelection (anIObj->GlobalSelectionMode()))
1002     {
1003       EO = anIObj->GlobalSelOwner();
1004     }
1005     if(EO.IsNull())
1006     {
1007       EO = new SelectMgr_EntityOwner((const Handle(SelectMgr_SelectableObject)&)anIObj);
1008     }
1009   }
1010
1011   if (!mySelection.IsNull())
1012   {
1013     AIS_SelectStatus aStatus = mySelection->Select(EO);
1014     EO->SetSelected (aStatus == AIS_SS_Added);
1015   }
1016
1017   HilightPicked(updateviewer);
1018 }
1019
1020 //=======================================================================
1021 //function : AddOrRemoveSelected
1022 //purpose  : To check...
1023 //=======================================================================
1024 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1025                                            const Standard_Boolean updateviewer)
1026 {     
1027   UnhilightPicked (Standard_False);
1028   Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1029   if (!EO.IsNull())
1030   {
1031     mySelection->Select(EO);
1032     EO->SetSelected (Standard_True);
1033   }
1034   HilightPicked (updateviewer);
1035 }
1036
1037 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1038                                            const Standard_Boolean toUpdateViewer)
1039 {
1040   if(myAutoHilight)
1041   {
1042     UnhilightPicked (Standard_False);
1043   }
1044
1045   Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1046
1047   mySelection->Select(theOwner);
1048   theOwner->SetSelected (toSelect);
1049
1050   if(myAutoHilight)
1051   {
1052     HilightPicked (toUpdateViewer);
1053   }
1054 }
1055
1056 //==================================================
1057 // Function: manageDetected
1058 // Purpose :
1059 //==================================================
1060 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1061                                        const Handle(V3d_View)&              theView,
1062                                        const Standard_Boolean               theToRedrawImmediate)
1063 {
1064   if (thePickOwner.IsNull())
1065   {
1066     myMainPM->ClearImmediateDraw();
1067     if (theToRedrawImmediate)
1068     {
1069       theView->RedrawImmediate();
1070     }
1071     return;
1072   }
1073
1074   if (!myFilters->IsOk (thePickOwner))
1075   {
1076     if (mylastindex != 0)
1077     {
1078       mylastgood = mylastindex;
1079     }
1080     if (theToRedrawImmediate)
1081     {
1082       theView->RedrawImmediate();
1083     }
1084     return;
1085   }
1086
1087   //=======================================================================================================
1088   // 2 cases : a- object is in the map of picks:
1089   //             1. this is the same index as the last detected: -> Do nothing
1090   //             2. otherwise :
1091   //                  - if lastindex = 0 (no object was detected at the last step)
1092   //                    the object presentation is highlighted and lastindex = index(objet)
1093   //                  - othrwise :
1094   //                           the presentation of the object corresponding to lastindex is "unhighlighted"
1095   //                           it is removed if the object is not visualized but only active
1096   //                           then the presentation of the detected object is highlighted and lastindex = index(objet)
1097   //         b- the object is not in the map of picked objects
1098   //                  - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1099   //            if the object was decomposed, presentation is created for the detected shape and the couple
1100   //             (Proprietaire,Prs)is added in the map.
1101   //           otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1102   //           itself is highlighted.
1103   //
1104   //=======================================================================================================
1105
1106   const Standard_Integer aNewIndex = myMapOfOwner->Contains  (thePickOwner)
1107                                    ? myMapOfOwner->FindIndex (thePickOwner)
1108                                    : myMapOfOwner->Add       (thePickOwner);
1109
1110   // For the advanced mesh selection mode the owner indices comparison
1111   // is not effective because in that case only one owner manage the
1112   // selection in current selection mode. It is necessary to check the current detected
1113   // entity and hilight it only if the detected entity is not the same as
1114   // previous detected (IsForcedHilight call)
1115   if (aNewIndex != mylastindex
1116    || thePickOwner->IsForcedHilight())
1117   {
1118     myMainPM->ClearImmediateDraw();
1119     if (mylastindex != 0
1120      && mylastindex <= myMapOfOwner->Extent())
1121     {
1122       const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner->FindKey (mylastindex);
1123       Unhilight (aLastOwner, theView);
1124     }
1125
1126     if (myAutoHilight)
1127     {
1128       if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1129       {
1130         Hilight (thePickOwner, theView);
1131       }
1132       if (theToRedrawImmediate)
1133       {
1134         theView->RedrawImmediate();
1135       }
1136     }
1137
1138     mylastindex = aNewIndex;
1139   }
1140
1141   if (mylastindex != 0)
1142   {
1143     mylastgood = mylastindex;
1144   }
1145 }
1146
1147 //=======================================================================
1148 //function : HasDetectedShape
1149 //purpose  : 
1150 //=======================================================================
1151
1152 Standard_Boolean AIS_LocalContext::HasDetectedShape() const 
1153 {
1154   if(mylastindex==0) return Standard_False;
1155   return IsShape(mylastindex);
1156 }
1157
1158 //=======================================================================
1159 //function : DetectedShape
1160 //purpose  : 
1161 //=======================================================================
1162
1163 const TopoDS_Shape&
1164 AIS_LocalContext::DetectedShape() const
1165 {
1166   if(mylastindex != 0)
1167   {
1168     Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner->FindKey (mylastindex));
1169     if(BROwnr.IsNull()) return AIS_LocalContext_myDummyShape;
1170     return BROwnr->Shape();
1171   }
1172   return AIS_LocalContext_myDummyShape;
1173 }                                           
1174
1175 //=======================================================================
1176 //function : DetectedInteractive
1177 //purpose  : 
1178 //=======================================================================
1179
1180 Handle(AIS_InteractiveObject) 
1181 AIS_LocalContext::DetectedInteractive() const 
1182 {
1183   Handle(AIS_InteractiveObject) Iobj;
1184   if(IsValidIndex(mylastindex)){
1185     Handle(SelectMgr_SelectableObject) SO = myMapOfOwner->FindKey(mylastindex)->Selectable();
1186     Iobj = Handle(AIS_InteractiveObject)::DownCast (SO);
1187   }
1188   return Iobj;
1189 }
1190 //=======================================================================
1191 //function : DetectedInteractive
1192 //purpose  : 
1193 //=======================================================================
1194 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const 
1195 {
1196   Handle(SelectMgr_EntityOwner) bid;
1197   if(!IsValidIndex(mylastindex)) return bid;
1198   return myMapOfOwner->FindKey(mylastindex);
1199 }
1200
1201
1202 //=======================================================================
1203 //function : ComesFromDecomposition
1204 //purpose  : 
1205 //=======================================================================
1206
1207 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const 
1208 {
1209   const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner->FindKey(PickedIndex);
1210   Handle(SelectMgr_SelectableObject) aSel  = OWN->Selectable();
1211   if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1212     const Handle(AIS_LocalStatus)& Stat      = myActiveObjects(aSel);    
1213     return Stat->Decomposed();
1214   }
1215   return Standard_False;
1216 }
1217
1218 //=======================================================================
1219 //function : DisplaySensitive
1220 //purpose  : 
1221 //=======================================================================
1222
1223 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1224 {
1225     myMainVS->DisplaySensitive(aviou);
1226 }
1227
1228 //=======================================================================
1229 //function : ClearSensitive
1230 //purpose  : 
1231 //=======================================================================
1232
1233 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1234 {
1235     myMainVS->ClearSensitive(aviou);
1236 }
1237
1238
1239 //=======================================================================
1240 //function : IsShape
1241 //purpose  : 
1242 //=======================================================================
1243 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1244 {
1245   Handle(SelectMgr_EntityOwner) aEO (myMapOfOwner->FindKey(Index));
1246   if (aEO.IsNull() || ! aEO->IsKind(STANDARD_TYPE(StdSelect_BRepOwner)))
1247     return Standard_False;
1248   return 
1249     ComesFromDecomposition(Index);
1250 }
1251
1252 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const 
1253 {
1254   const Handle(SelectMgr_SelectableObject)& aSelObj = anIObj; // to avoid ambiguity
1255   // Shape was not transfered from AIS_Shape to EntityOwner
1256   Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1257   if( !shape.IsNull() ) 
1258     return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(), aSelObj));
1259   return myFilters->IsOk(new SelectMgr_EntityOwner(aSelObj));
1260 }
1261
1262
1263 //=======================================================================
1264 //function : HilightNextDetected
1265 //purpose  :
1266 //=======================================================================
1267 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1268                                                         const Standard_Boolean  theToRedrawImmediate)
1269 {
1270   // go to the next owner
1271   if (myDetectedSeq.IsEmpty())
1272   {
1273     return 0;
1274   }
1275
1276   const Standard_Integer aLen = myDetectedSeq.Length();
1277   if (++myCurDetected > aLen)
1278   {
1279     myCurDetected = 1;
1280   }
1281   Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1282   if (anOwner.IsNull())
1283   {
1284     return 0;
1285   }
1286   manageDetected (anOwner, theView, theToRedrawImmediate);
1287   return myCurDetected;
1288 }
1289
1290 //=======================================================================
1291 //function : HilightPreviousDetected
1292 //purpose  :
1293 //=======================================================================
1294 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1295                                                             const Standard_Boolean  theToRedrawImmediate)
1296 {
1297   if (myDetectedSeq.IsEmpty())
1298   {
1299     return 0;
1300   }
1301
1302   const Standard_Integer aLen = myDetectedSeq.Length();
1303   if (--myCurDetected < 1)
1304   {
1305     myCurDetected = aLen;
1306   }
1307   Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1308   if (anOwner.IsNull())
1309   {
1310     return 0;
1311   }
1312
1313   manageDetected (anOwner, theView, theToRedrawImmediate);
1314   return myCurDetected;
1315 }
1316
1317 //=======================================================================
1318 //function : UnhilightLastDetected
1319 //purpose  :
1320 //=======================================================================
1321 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1322 {
1323   return UnhilightLastDetected (theView->Viewer());
1324 }
1325
1326 //=======================================================================
1327 //function : UnhilightLastDetected
1328 //purpose  :
1329 //=======================================================================
1330 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_Viewer)& theViewer)
1331 {
1332   if (!IsValidIndex (mylastindex))
1333   {
1334     return Standard_False;
1335   }
1336
1337   myMainPM->BeginImmediateDraw();
1338   const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner->FindKey (mylastindex);
1339   anOwner->Unhilight (myMainPM);
1340   myMainPM->EndImmediateDraw (theViewer);
1341   mylastindex = 0;
1342   return Standard_True;
1343 }
1344
1345 //=======================================================================
1346 //function : FindSelectedOwnerFromIO
1347 //purpose  : it is checked if one of the selected owners really presents IObj
1348 //=======================================================================
1349 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO (const Handle(AIS_InteractiveObject)& theObj) const
1350 {
1351   Handle(SelectMgr_EntityOwner) EO,bid;
1352   if (theObj.IsNull()
1353    || mySelection.IsNull())
1354   {
1355     return Handle(SelectMgr_EntityOwner)();
1356   }
1357
1358   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
1359   {
1360     if (!aSelIter.Value()->IsSameSelectable (theObj))
1361     {
1362       continue;
1363     }
1364
1365     Handle(StdSelect_BRepOwner) aBROwner = Handle(StdSelect_BRepOwner)::DownCast(aSelIter.Value());
1366     if (aBROwner.IsNull()
1367     || !aBROwner->ComesFromDecomposition())
1368     {
1369       return aSelIter.Value();
1370     }
1371   }
1372   return Handle(SelectMgr_EntityOwner)();
1373 }
1374
1375 //=======================================================================
1376 //function : FindSelectedOwnerFromShape
1377 //purpose  : it is checked if one of the selected owners really presents IObj
1378 //=======================================================================
1379 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const 
1380 {
1381   Handle(SelectMgr_EntityOwner) EO, bid;
1382   if (sh.IsNull()) return EO;
1383   
1384   if(mySelection.IsNull()) {
1385     return EO;
1386   }
1387   
1388   Standard_Boolean found(Standard_False);
1389
1390   if (!found) {
1391     NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
1392     myMainVS->ActiveOwners (anActiveOwners);
1393     for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
1394     {
1395       EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1396       Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1397       if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1398          found = Standard_True;
1399          break;
1400       }
1401     }
1402   }
1403
1404   if(found)  return EO;
1405   return bid;
1406 }
1407
1408 //=======================================================================
1409 //function : AIS_LocalContext::InitDetected
1410 //purpose  :
1411 //=======================================================================
1412 void AIS_LocalContext::InitDetected()
1413 {
1414   myAISCurDetected = !myDetectedSeq.IsEmpty() ? myDetectedSeq.Lower() : 0;
1415 }
1416
1417 //=======================================================================
1418 //function : AIS_LocalContext::MoreDetected
1419 //purpose  :
1420 //=======================================================================
1421 Standard_Boolean AIS_LocalContext::MoreDetected() const
1422 {
1423   return myAISCurDetected >= myDetectedSeq.Lower()
1424       && myAISCurDetected <= myDetectedSeq.Upper();
1425 }
1426
1427 //=======================================================================
1428 //function : AIS_LocalContext::NextDetected
1429 //purpose  :
1430 //=======================================================================
1431 void AIS_LocalContext::NextDetected()
1432 {
1433   myAISCurDetected++;
1434 }
1435
1436 //=======================================================================
1437 //function : DetectedCurrentShape
1438 //purpose  :
1439 //=======================================================================
1440 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1441 {
1442   Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1443
1444   if (aCurrentShape.IsNull())
1445   {
1446     return AIS_LocalContext_myDummyShape;
1447   }
1448
1449   return aCurrentShape->Shape();
1450 }
1451
1452 //=======================================================================
1453 //function : DetectedCurrentOwner
1454 //purpose  :
1455 //=======================================================================
1456 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedCurrentOwner() const
1457 {
1458   return MoreDetected()
1459        ? myMainVS->Picked (myDetectedSeq (myAISCurDetected))
1460        : Handle(SelectMgr_EntityOwner)();
1461 }
1462
1463 //=======================================================================
1464 //function : DetectedCurrentObject
1465 //purpose  :
1466 //=======================================================================
1467 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1468 {
1469   if (!MoreDetected())
1470   {
1471     return Handle(AIS_InteractiveObject)();
1472   }
1473   return Handle(AIS_InteractiveObject)::DownCast (myMainVS->Picked (myDetectedSeq (myAISCurDetected))->Selectable());
1474 }
1475
1476 //=======================================================================
1477 //function : RestoreActivatedModes
1478 //purpose  :
1479 //=======================================================================
1480 void AIS_LocalContext::RestoreActivatedModes() const
1481 {
1482   for (AIS_DataMapOfSelStat::Iterator anIter (myActiveObjects); anIter.More(); anIter.Next())
1483   {
1484     const TColStd_ListOfInteger& anActivatedModes = anIter.Value()->SelectionModes();
1485     for (TColStd_ListIteratorOfListOfInteger aModesIter (anActivatedModes); aModesIter.More(); aModesIter.Next())
1486     {
1487       mySM->Activate (anIter.Key(), aModesIter.Value(), myMainVS);
1488     }
1489   }
1490 }