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