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