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