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