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