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