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