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