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