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