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