04c094d8962d4955f6d6d420591f882694ef4a94
[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. AIS_Selection : 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     else
926     {
927       aRemoveEntites.Append (anOwner);
928       anOwner->SetSelected (Standard_False);
929       for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
930       {
931         Unhilight (anOwner, aViewer->ActiveView());
932       }
933     }
934   }
935   AIS_NListTransient::Iterator anIterRemove (aRemoveEntites);
936   for (; anIterRemove.More(); anIterRemove.Next())
937   {
938     aSelection->Select (anIterRemove.Value());
939   }
940
941   // 4. AIS_LocalContext - myMapOfOwner : remove entity owners from myMapOfOwner
942   SelectMgr_IndexedMapOfOwner anOwnersToKeep;
943   for (Standard_Integer anIdx = 1; anIdx <= myMapOfOwner.Extent(); anIdx++)
944   {
945     Handle(SelectMgr_EntityOwner) anOwner = myMapOfOwner (anIdx);
946     if (anOwner.IsNull())
947     {
948       continue;
949     }
950
951     if (anOwner->Selectable() != theIO || aValidOwners.Contains (anOwner))
952     {
953       anOwnersToKeep.Add (anOwner);
954     }
955     else
956     {
957       for (aViewer->InitActiveViews(); aViewer->MoreActiveViews(); aViewer->NextActiveViews())
958       {
959         Unhilight (anOwner, aViewer->ActiveView());
960       }
961     }
962   }
963   myMapOfOwner.Clear();
964   myMapOfOwner.Assign (anOwnersToKeep);
965   mylastindex = myMapOfOwner.FindIndex (aLastPicked);
966   if (!IsValidIndex (mylastindex))
967   {
968     myMainPM->ClearImmediateDraw();
969   }
970
971   if (!isAISRemainsDetected)
972   {
973     // Remove the interactive object from detected sequences
974     for (Standard_Integer anIdx = 1; anIdx <= myAISDetectedSeq.Length(); ++anIdx)
975     {
976       Handle(AIS_InteractiveObject) aDetectedIO = myAISDetectedSeq.Value (anIdx);
977       if (aDetectedIO.IsNull() || aDetectedIO != theIO)
978       {
979         continue;
980       }
981
982       myAISDetectedSeq.Remove (anIdx--);
983
984       if (anIdx < myAISCurDetected)
985       {
986         myAISCurDetected--;
987       }
988     }
989     myAISCurDetected = Max (myAISCurDetected, 1);
990   }
991 }
992
993 //=======================================================================
994 //function : SetSelected
995 //purpose  : 
996 //=======================================================================
997 void AIS_LocalContext::SetSelected(const Handle(AIS_InteractiveObject)& anIObj,
998                                    const Standard_Boolean updateviewer)
999 {
1000   if(!IsValidForSelection(anIObj)) return;
1001   UnhilightPicked(Standard_False);
1002   
1003   //1st case, owner already <anIObj> as owner  
1004   // and not separated is found...
1005
1006   Handle(AIS_Selection) sel = AIS_Selection::Selection(mySelName.ToCString());
1007   //Standard_Boolean found(Standard_False);
1008   Handle(Standard_Transient) Tr;
1009   Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromIO(anIObj);
1010   if(EO.IsNull()){
1011     //check if in selection number 0 there is an owner that can be triturated...
1012     if(anIObj->HasSelection(0)){
1013       const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1014       SIOBJ->Init();
1015       if(SIOBJ->More()){
1016         Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1017         EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
1018       }
1019     }
1020     if(EO.IsNull()) 
1021       EO = new SelectMgr_EntityOwner(anIObj);
1022   }
1023   
1024   ClearSelected(Standard_False);
1025
1026   AIS_Selection::Select(EO);
1027   EO->SetSelected (Standard_True);
1028
1029   HilightPicked(updateviewer);
1030 }
1031
1032 //=======================================================================
1033 //function : AddOrRemoveSelected
1034 //purpose  : 
1035 //=======================================================================
1036
1037 void AIS_LocalContext::AddOrRemoveSelected(const Handle(AIS_InteractiveObject)& anIObj,
1038                                            const Standard_Boolean updateviewer)
1039 {
1040   if(!IsValidForSelection(anIObj)) return;
1041   UnhilightPicked(Standard_False);
1042   // first check if it is selected...
1043   Handle(SelectMgr_EntityOwner) EO;
1044
1045   EO = FindSelectedOwnerFromIO(anIObj);
1046
1047   if (EO.IsNull())
1048   {
1049     if(anIObj->HasSelection(0))
1050     {
1051       const Handle(SelectMgr_Selection)& SIOBJ = anIObj->Selection(0);
1052       SIOBJ->Init();
1053       if(SIOBJ->More()){
1054         Handle(SelectBasics_EntityOwner) BO = SIOBJ->Sensitive()->BaseSensitive()->OwnerId();
1055         EO = *((Handle(SelectMgr_EntityOwner)*)&BO);
1056       }
1057     }
1058     if(EO.IsNull())
1059     {
1060       EO = new SelectMgr_EntityOwner(anIObj);
1061     }
1062   }
1063   
1064 //  cout<<"AIS_LocalContext::AddOrRemoveSelected : Selection = "<<mySelName<<endl;
1065   const Handle(AIS_Selection)& S = AIS_Selection::Selection(mySelName.ToCString());
1066   
1067   if (!S.IsNull())
1068   {
1069     AIS_SelectStatus aStatus = S->Select(EO);
1070     EO->SetSelected (aStatus == AIS_SS_Added);
1071   }
1072
1073   HilightPicked(updateviewer);
1074 }
1075
1076 //=======================================================================
1077 //function : AddOrRemoveSelected
1078 //purpose  : To check...
1079 //=======================================================================
1080 void AIS_LocalContext::AddOrRemoveSelected(const TopoDS_Shape& Sh,
1081                                            const Standard_Boolean updateviewer)
1082 {     
1083   UnhilightPicked (Standard_False);
1084   Handle(SelectMgr_EntityOwner) EO = FindSelectedOwnerFromShape(Sh);
1085   if (!EO.IsNull())
1086   {
1087     AIS_Selection::Selection(mySelName.ToCString())->Select(EO);
1088     EO->SetSelected (Standard_True);
1089   }
1090   HilightPicked (updateviewer);
1091 }
1092
1093 void AIS_LocalContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
1094                                            const Standard_Boolean toUpdateViewer)
1095 {
1096   if(myAutoHilight)
1097   {
1098     UnhilightPicked (Standard_False);
1099   }
1100
1101   Standard_Boolean toSelect = theOwner->IsSelected() ? Standard_False : Standard_True;
1102
1103   AIS_Selection::Selection (mySelName.ToCString())->Select (theOwner);
1104   theOwner->SetSelected (toSelect);
1105
1106   if(myAutoHilight)
1107   {
1108     HilightPicked (toUpdateViewer);
1109   }
1110 }
1111
1112 //==================================================
1113 // Function: manageDetected
1114 // Purpose :
1115 //==================================================
1116 void AIS_LocalContext::manageDetected (const Handle(SelectMgr_EntityOwner)& thePickOwner,
1117                                        const Handle(V3d_View)&              theView,
1118                                        const Standard_Boolean               theToRedrawImmediate)
1119 {
1120   if (thePickOwner.IsNull())
1121   {
1122     myMainPM->ClearImmediateDraw();
1123     if (theToRedrawImmediate)
1124     {
1125       theView->RedrawImmediate();
1126     }
1127     return;
1128   }
1129
1130   if (!myFilters->IsOk (thePickOwner))
1131   {
1132     if (mylastindex != 0)
1133     {
1134       mylastgood = mylastindex;
1135     }
1136     if (theToRedrawImmediate)
1137     {
1138       theView->RedrawImmediate();
1139     }
1140     return;
1141   }
1142
1143   //=======================================================================================================
1144   // 2 cases : a- object is in the map of picks:
1145   //             1. this is the same index as the last detected: -> Do nothing
1146   //             2. otherwise :
1147   //                  - if lastindex = 0 (no object was detected at the last step)
1148   //                    the object presentation is highlighted and lastindex = index(objet)
1149   //                  - othrwise :
1150   //                           the presentation of the object corresponding to lastindex is "unhighlighted"
1151   //                           it is removed if the object is not visualized but only active
1152   //                           then the presentation of the detected object is highlighted and lastindex = index(objet)
1153   //         b- the object is not in the map of picked objects
1154   //                  - if lastindex != 0 (object detected at the last step) it is unhighlighted ...
1155   //            if the object was decomposed, presentation is created for the detected shape and the couple
1156   //             (Proprietaire,Prs)is added in the map.
1157   //           otherwise the couple(proprietaire, NullPrs) is placed in the map and the interactive object
1158   //           itself is highlighted.
1159   //
1160   //=======================================================================================================
1161
1162   const Standard_Integer aNewIndex = myMapOfOwner.Contains  (thePickOwner)
1163                                    ? myMapOfOwner.FindIndex (thePickOwner)
1164                                    : myMapOfOwner.Add       (thePickOwner);
1165
1166   // For the advanced mesh selection mode the owner indices comparison
1167   // is not effective because in that case only one owner manage the
1168   // selection in current selection mode. It is necessary to check the current detected
1169   // entity and hilight it only if the detected entity is not the same as
1170   // previous detected (IsForcedHilight call)
1171   if (aNewIndex != mylastindex
1172    || thePickOwner->IsForcedHilight())
1173   {
1174     myMainPM->ClearImmediateDraw();
1175     if (mylastindex != 0
1176      && mylastindex <= myMapOfOwner.Extent())
1177     {
1178       const Handle(SelectMgr_EntityOwner)& aLastOwner = myMapOfOwner (mylastindex);
1179       Unhilight (aLastOwner, theView);
1180     }
1181
1182     if (myAutoHilight)
1183     {
1184       if (!thePickOwner->IsSelected() || myCTX->ToHilightSelected())
1185       {
1186         Hilight (thePickOwner, theView);
1187       }
1188       if (theToRedrawImmediate)
1189       {
1190         theView->RedrawImmediate();
1191       }
1192     }
1193
1194     mylastindex = aNewIndex;
1195   }
1196
1197   if (mylastindex != 0)
1198   {
1199     mylastgood = mylastindex;
1200   }
1201 }
1202
1203 //=======================================================================
1204 //function : HasDetectedShape
1205 //purpose  : 
1206 //=======================================================================
1207
1208 Standard_Boolean AIS_LocalContext::HasDetectedShape() const 
1209 {
1210   if(mylastindex==0) return Standard_False;
1211   return IsShape(mylastindex);
1212 }
1213
1214 //=======================================================================
1215 //function : DetectedShape
1216 //purpose  : 
1217 //=======================================================================
1218
1219 const TopoDS_Shape&
1220 AIS_LocalContext::DetectedShape() const
1221 {
1222   static TopoDS_Shape bidsh;
1223   if(mylastindex != 0)
1224   {
1225     Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner(mylastindex));
1226     if(BROwnr.IsNull()) return bidsh;
1227     return BROwnr->Shape();
1228   }
1229   return bidsh;
1230 }                                           
1231
1232 //=======================================================================
1233 //function : DetectedInteractive
1234 //purpose  : 
1235 //=======================================================================
1236
1237 Handle(AIS_InteractiveObject) 
1238 AIS_LocalContext::DetectedInteractive() const 
1239 {
1240   Handle(AIS_InteractiveObject) Iobj;
1241   if(IsValidIndex(mylastindex)){
1242     Handle(SelectMgr_SelectableObject) SO = myMapOfOwner.FindKey(mylastindex)->Selectable();
1243     Iobj = *((Handle(AIS_InteractiveObject)*) &SO);
1244   }
1245   return Iobj;
1246 }
1247 //=======================================================================
1248 //function : DetectedInteractive
1249 //purpose  : 
1250 //=======================================================================
1251 Handle(SelectMgr_EntityOwner) AIS_LocalContext::DetectedOwner() const 
1252 {
1253   Handle(SelectMgr_EntityOwner) bid;
1254   if(!IsValidIndex(mylastindex)) return bid;
1255   return myMapOfOwner.FindKey(mylastindex);
1256 }
1257
1258
1259 //=======================================================================
1260 //function : ComesFromDecomposition
1261 //purpose  : 
1262 //=======================================================================
1263
1264 Standard_Boolean AIS_LocalContext::ComesFromDecomposition(const Standard_Integer PickedIndex) const 
1265 {
1266   const Handle(SelectMgr_EntityOwner)& OWN = myMapOfOwner.FindKey(PickedIndex);
1267   Handle(SelectMgr_SelectableObject) aSel  = OWN->Selectable();
1268   if (myActiveObjects.IsBound (aSel)) { // debug of jmi
1269     const Handle(AIS_LocalStatus)& Stat      = myActiveObjects(aSel);    
1270     return Stat->Decomposed();
1271   }
1272   return Standard_False;
1273 }
1274
1275 //=======================================================================
1276 //function : DisplaySensitive
1277 //purpose  : 
1278 //=======================================================================
1279
1280 void AIS_LocalContext::DisplaySensitive(const Handle(V3d_View)& aviou)
1281 {
1282     myMainVS->DisplaySensitive(aviou);
1283 }
1284
1285 //=======================================================================
1286 //function : ClearSensitive
1287 //purpose  : 
1288 //=======================================================================
1289
1290 void AIS_LocalContext::ClearSensitive(const Handle(V3d_View)& aviou)
1291 {
1292     myMainVS->ClearSensitive(aviou);
1293 }
1294
1295
1296 //=======================================================================
1297 //function : IsShape
1298 //purpose  : 
1299 //=======================================================================
1300 Standard_Boolean AIS_LocalContext::IsShape(const Standard_Integer Index) const
1301 {
1302   
1303   if(Handle(StdSelect_BRepOwner)::DownCast(myMapOfOwner.FindKey(Index)).IsNull())
1304     return Standard_False;
1305   return 
1306     ComesFromDecomposition(Index);
1307 }
1308
1309 Standard_Boolean AIS_LocalContext::IsValidForSelection(const Handle(AIS_InteractiveObject)& anIObj) const 
1310 {
1311
1312   // Shape was not transfered from AIS_Shape to EntityOwner
1313   Handle(AIS_Shape) shape = Handle(AIS_Shape)::DownCast(anIObj);
1314   if( !shape.IsNull() ) 
1315     return myFilters->IsOk(new StdSelect_BRepOwner(shape->Shape(),shape));
1316   return myFilters->IsOk(new SelectMgr_EntityOwner(anIObj));
1317 }
1318
1319
1320 //=======================================================================
1321 //function : HilightNextDetected
1322 //purpose  :
1323 //=======================================================================
1324 Standard_Integer AIS_LocalContext::HilightNextDetected (const Handle(V3d_View)& theView,
1325                                                         const Standard_Boolean  theToRedrawImmediate)
1326 {
1327   // go to the next owner
1328   if (myDetectedSeq.IsEmpty())
1329   {
1330     return 0;
1331   }
1332
1333   const Standard_Integer aLen = myDetectedSeq.Length();
1334   if (++myCurDetected > aLen)
1335   {
1336     myCurDetected = 1;
1337   }
1338   Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1339   if (anOwner.IsNull())
1340   {
1341     return 0;
1342   }
1343   manageDetected (anOwner, theView, theToRedrawImmediate);
1344   return myCurDetected;
1345 }
1346
1347 //=======================================================================
1348 //function : HilightPreviousDetected
1349 //purpose  :
1350 //=======================================================================
1351 Standard_Integer AIS_LocalContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
1352                                                             const Standard_Boolean  theToRedrawImmediate)
1353 {
1354   if (myDetectedSeq.IsEmpty())
1355   {
1356     return 0;
1357   }
1358
1359   const Standard_Integer aLen = myDetectedSeq.Length();
1360   if (--myCurDetected < 1)
1361   {
1362     myCurDetected = aLen;
1363   }
1364   Handle(SelectMgr_EntityOwner) anOwner = myMainVS->Picked (myDetectedSeq (myCurDetected));
1365   if (anOwner.IsNull())
1366   {
1367     return 0;
1368   }
1369
1370   manageDetected (anOwner, theView, theToRedrawImmediate);
1371   return myCurDetected;
1372 }
1373
1374 //=======================================================================
1375 //function : UnhilightLastDetected
1376 //purpose  :
1377 //=======================================================================
1378 Standard_Boolean AIS_LocalContext::UnhilightLastDetected (const Handle(V3d_View)& theView)
1379 {
1380   if (!IsValidIndex (mylastindex))
1381   {
1382     return Standard_False;
1383   }
1384
1385   myMainPM->BeginImmediateDraw();
1386   const Handle(SelectMgr_EntityOwner)& anOwner = myMapOfOwner (mylastindex);
1387   const Standard_Integer aHilightMode = anOwner->HasSelectable()
1388                                       ? GetHiMod (Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()))
1389                                       : 0;
1390
1391   myMapOfOwner (mylastindex)->Unhilight (myMainPM, aHilightMode);
1392   myMainPM->EndImmediateDraw (theView);
1393   mylastindex = 0;
1394   return Standard_True;
1395 }
1396
1397 //=======================================================================
1398 //function : FindSelectedOwnerFromIO
1399 //purpose  : it is checked if one of the selected owners really presents IObj
1400 //=======================================================================
1401 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromIO
1402                           (const Handle(AIS_InteractiveObject)& anIObj) const 
1403 {
1404   Handle(SelectMgr_EntityOwner) EO,bid;
1405   if (anIObj.IsNull()) return EO;
1406   
1407   Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1408   if(Sel.IsNull()) {
1409 #ifdef OCCT_DEBUG
1410     cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "
1411         <<mySelName<<" Nulle "<<endl;
1412 #endif
1413     return EO;
1414   }
1415   Standard_Boolean found(Standard_False);
1416   const AIS_NListTransient& Obj = Sel->Objects();
1417   AIS_NListTransient::Iterator anIter( Obj );
1418   for(; anIter.More(); anIter.Next()){
1419     const Handle(Standard_Transient)& Tr = anIter.Value();
1420     if(!Tr.IsNull()){
1421       EO = *((Handle(SelectMgr_EntityOwner)*)&Tr);
1422       if(EO->HasSelectable()){
1423         Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1424         if(BROwnr.IsNull() || !BROwnr->ComesFromDecomposition()){
1425           if (anIObj == EO->Selectable()){
1426             found =Standard_True;
1427             break;
1428           }
1429         }
1430       }
1431     }
1432   }
1433   if(found)  return EO;
1434   return bid;
1435 }
1436
1437 //=======================================================================
1438 //function : FindSelectedOwnerFromShape
1439 //purpose  : it is checked if one of the selected owners really presents IObj
1440 //=======================================================================
1441 Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const TopoDS_Shape& sh) const 
1442 {
1443   Handle(SelectMgr_EntityOwner) EO, bid;
1444   if (sh.IsNull()) return EO;
1445   
1446   Handle(AIS_Selection) Sel = AIS_Selection::Selection(mySelName.ToCString());
1447   if(Sel.IsNull()) {
1448 #ifdef OCCT_DEBUG
1449     cout<<"\t\tAIS_LocalCOntext::FindSelectedOwnerFromShape : Selection "<<mySelName<<" Nulle "<<endl;
1450 #endif
1451     return EO;
1452   }
1453   
1454   Standard_Boolean found(Standard_False);
1455
1456   if (!found) {
1457     NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (myMainVS->ActiveOwners());
1458     for (; anOwnersIt.More(); anOwnersIt.Next()) {
1459       EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
1460       Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
1461       if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {
1462          found = Standard_True;
1463          break;
1464       }
1465     }
1466   }
1467
1468   if(found)  return EO;
1469   return bid;
1470 }
1471
1472 //=======================================================================
1473 //function : AIS_LocalContext::InitDetected
1474 //purpose  :
1475 //=======================================================================
1476 void AIS_LocalContext::InitDetected()
1477 {
1478   myAISCurDetected = myAISDetectedSeq.Length()? 1 : 0;
1479 }
1480
1481 //=======================================================================
1482 //function : AIS_LocalContext::MoreDetected
1483 //purpose  :
1484 //=======================================================================
1485 Standard_Boolean AIS_LocalContext::MoreDetected() const
1486 {
1487   return (myAISCurDetected > 0 && myAISCurDetected <= myAISDetectedSeq.Length());
1488 }
1489
1490 //=======================================================================
1491 //function : AIS_LocalContext::NextDetected
1492 //purpose  :
1493 //=======================================================================
1494 void AIS_LocalContext::NextDetected()
1495 {
1496   myAISCurDetected++;
1497 }
1498
1499 //=======================================================================
1500 //function : DetectedCurrentShape
1501 //purpose  :
1502 //=======================================================================
1503 const TopoDS_Shape& AIS_LocalContext::DetectedCurrentShape() const
1504 {
1505   static TopoDS_Shape aDummyShape;
1506
1507   Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
1508
1509   if (aCurrentShape.IsNull())
1510   {
1511     return aDummyShape;
1512   }
1513
1514   return aCurrentShape->Shape();
1515 }
1516 //=======================================================================
1517 //function : DetectedCurrentObject
1518 //purpose  :
1519 //=======================================================================
1520 Handle(AIS_InteractiveObject) AIS_LocalContext::DetectedCurrentObject() const
1521 {
1522   return MoreDetected() ? myAISDetectedSeq(myAISCurDetected) : NULL;
1523 }